Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: src/IceInst.cpp

Issue 205613002: Initial skeleton of Subzero. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Fix omissions from previous patchset. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 //===- subzero/src/IceInst.cpp - High-level instruction implementation ----===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Inst class, primarily the various
11 // subclass constructors and dump routines.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "IceCfg.h"
16 #include "IceCfgNode.h"
17 #include "IceInst.h"
18 #include "IceOperand.h"
19
20 namespace Ice {
21
22 Inst::Inst(IceCfg *Cfg, InstKind Kind, IceSize_t MaxSrcs, Variable *Dest)
23 : Kind(Kind), Number(Cfg->newInstNumber()), Deleted(false),
24 HasSideEffects(false), Dest(Dest), MaxSrcs(MaxSrcs), NumSrcs(0),
25 Srcs(Cfg->allocateArrayOf<Operand *>(MaxSrcs)) {}
26
27 Inst::~Inst() {
28 #ifdef ICE_NO_ARENAS
29 for (IceSize_t i = 0; i < getSrcSize(); ++i) {
30 Operand *Src = getSrc(i);
31 if (Src && !Src->isPooled()) {
32 delete Src;
33 }
34 }
35 delete[] Srcs;
36 if (getDest() && !getDest()->isPooled()) {
37 delete getDest();
38 }
JF 2014/04/23 03:51:28 Same thing on deletion, though it kind of seems li
Jim Stichnoth 2014/04/26 15:02:11 Done. And you're right, it was just wrong for the
39 #endif // ICE_NO_ARENAS
40 }
41
42 void Inst::updateVars(CfgNode *Node) {
43 if (Dest)
44 Dest->setDefinition(this, Node);
45
46 IceSize_t VarIndex = 0;
47 for (IceSize_t I = 0; I < getSrcSize(); ++I) {
48 Operand *Src = getSrc(I);
49 IceSize_t NumVars = Src->getNumVars();
50 for (IceSize_t J = 0; J < NumVars; ++J, ++VarIndex) {
51 Variable *Var = Src->getVar(J);
52 Var->setUse(this, Node);
53 }
54 }
55 }
56
57 InstAlloca::InstAlloca(IceCfg *Cfg, Operand *ByteCount, uint32_t Align,
58 Variable *Dest)
59 : Inst(Cfg, Inst::Alloca, 1, Dest), Align(Align) {
60 addSource(ByteCount);
61 }
62
63 InstArithmetic::InstArithmetic(IceCfg *Cfg, OpKind Op, Variable *Dest,
64 Operand *Source1, Operand *Source2)
65 : Inst(Cfg, Inst::Arithmetic, 2, Dest), Op(Op) {
66 addSource(Source1);
67 addSource(Source2);
68 }
69
70 bool InstArithmetic::isCommutative() const {
71 #define X(tag, str, commutative) \
72 case tag: \
73 return commutative;
74
75 switch (getOp()) { ICEINSTARITHMETIC_TABLE }
JF 2014/04/23 03:51:28 Load from a static const bool table instead: show
Jim Stichnoth 2014/04/26 15:02:11 Done.
76 #undef X
77
78 assert(0); // should be unreachable
JF 2014/04/23 03:51:28 llvm_unreachable
Jim Stichnoth 2014/04/26 15:02:11 Done.
79 return false;
80 }
81
82 InstAssign::InstAssign(IceCfg *Cfg, Variable *Dest, Operand *Source)
83 : Inst(Cfg, Inst::Assign, 1, Dest) {
84 addSource(Source);
85 }
86
87 // If TargetTrue==TargetFalse, we turn it into an unconditional
88 // branch. This ensures that, along with the 'switch' instruction
89 // semantics, there is at most one edge from one node to another.
90 InstBr::InstBr(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue,
91 CfgNode *TargetFalse)
92 : Inst(Cfg, Inst::Br, 1, NULL), TargetFalse(TargetFalse),
93 TargetTrue(TargetTrue) {
94 if (TargetTrue == TargetFalse) {
95 TargetTrue = NULL; // turn into unconditional version
96 } else {
97 addSource(Source);
98 }
99 }
100
101 InstBr::InstBr(IceCfg *Cfg, CfgNode *Target)
102 : Inst(Cfg, Inst::Br, 0, NULL), TargetFalse(Target), TargetTrue(NULL) {}
103
104 NodeList InstBr::getTerminatorEdges() const {
105 NodeList OutEdges;
106 OutEdges.push_back(TargetFalse);
107 if (TargetTrue)
108 OutEdges.push_back(TargetTrue);
109 return OutEdges;
110 }
111
112 InstCast::InstCast(IceCfg *Cfg, OpKind CastKind, Variable *Dest,
113 Operand *Source)
114 : Inst(Cfg, Inst::Cast, 1, Dest), CastKind(CastKind) {
115 addSource(Source);
116 }
117
118 InstFcmp::InstFcmp(IceCfg *Cfg, FCond Condition, Variable *Dest,
119 Operand *Source1, Operand *Source2)
120 : Inst(Cfg, Inst::Fcmp, 2, Dest), Condition(Condition) {
121 addSource(Source1);
122 addSource(Source2);
123 }
124
125 InstIcmp::InstIcmp(IceCfg *Cfg, ICond Condition, Variable *Dest,
126 Operand *Source1, Operand *Source2)
127 : Inst(Cfg, Inst::Icmp, 2, Dest), Condition(Condition) {
128 addSource(Source1);
129 addSource(Source2);
130 }
131
132 InstLoad::InstLoad(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr)
133 : Inst(Cfg, Inst::Load, 1, Dest) {
134 addSource(SourceAddr);
135 }
136
137 InstPhi::InstPhi(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest)
138 : Inst(Cfg, Phi, MaxSrcs, Dest) {
139 Labels = Cfg->allocateArrayOf<CfgNode *>(MaxSrcs);
140 }
141
142 // TODO: A Switch instruction (and maybe others) can add duplicate
143 // edges. We may want to de-dup Phis and validate consistency (i.e.,
144 // the source operands are the same for duplicate edges), though it
145 // seems the current lowering code is OK with this situation.
146 void InstPhi::addArgument(Operand *Source, CfgNode *Label) {
147 Labels[getSrcSize()] = Label;
148 addSource(Source);
149 }
150
151 InstRet::InstRet(IceCfg *Cfg, Operand *RetValue)
152 : Inst(Cfg, Ret, RetValue ? 1 : 0, NULL) {
153 if (RetValue)
154 addSource(RetValue);
155 }
156
157 InstSelect::InstSelect(IceCfg *Cfg, Variable *Dest, Operand *Condition,
158 Operand *SourceTrue, Operand *SourceFalse)
159 : Inst(Cfg, Inst::Select, 3, Dest) {
160 assert(Condition->getType() == IceType_i1);
161 addSource(Condition);
162 addSource(SourceTrue);
163 addSource(SourceFalse);
164 }
165
166 InstStore::InstStore(IceCfg *Cfg, Operand *Data, Operand *Addr)
167 : Inst(Cfg, Inst::Store, 2, NULL) {
168 addSource(Data);
169 addSource(Addr);
170 }
171
172 InstSwitch::InstSwitch(IceCfg *Cfg, IceSize_t NumCases, Operand *Source,
173 CfgNode *LabelDefault)
174 : Inst(Cfg, Inst::Switch, 1, NULL), LabelDefault(LabelDefault),
175 NumCases(NumCases) {
176 addSource(Source);
177 Values = Cfg->allocateArrayOf<uint64_t>(NumCases);
178 Labels = Cfg->allocateArrayOf<CfgNode *>(NumCases);
179 // Initialize in case buggy code doesn't set all entries
180 for (IceSize_t I = 0; I < NumCases; ++I) {
181 Values[I] = 0;
182 Labels[I] = NULL;
183 }
184 }
185
186 void InstSwitch::addBranch(IceSize_t CaseIndex, uint64_t Value,
187 CfgNode *Label) {
188 assert(CaseIndex < NumCases);
189 Values[CaseIndex] = Value;
190 Labels[CaseIndex] = Label;
191 }
192
193 NodeList InstSwitch::getTerminatorEdges() const {
194 NodeList OutEdges;
195 OutEdges.push_back(LabelDefault);
196 for (IceSize_t I = 0; I < NumCases; ++I) {
197 OutEdges.push_back(Labels[I]);
198 }
199 return OutEdges;
200 }
201
202 InstUnreachable::InstUnreachable(IceCfg *Cfg)
203 : Inst(Cfg, Inst::Unreachable, 0, NULL) {}
204
205 // ======================== Dump routines ======================== //
206
207 void Inst::dumpDecorated(const IceCfg *Cfg) const {
208 IceOstream &Str = Cfg->getContext()->getStrDump();
209 if (!Cfg->getContext()->isVerbose(IceV_Deleted) && isDeleted())
210 return;
211 if (Cfg->getContext()->isVerbose(IceV_InstNumbers)) {
212 const static size_t BufLen = 30;
213 char buf[BufLen];
214 int32_t Number = getNumber();
215 if (Number < 0)
216 snprintf(buf, BufLen, "[XXX]");
217 else
218 snprintf(buf, BufLen, "[%3d]", Number);
219 Str << buf;
220 }
221 Str << " ";
222 if (isDeleted())
223 Str << " //";
224 dump(Cfg);
225 Str << "\n";
226 }
227
228 void Inst::dump(const IceCfg *Cfg) const {
229 IceOstream &Str = Cfg->getContext()->getStrDump();
230 dumpDest(Cfg);
231 Str << " =~ ";
232 dumpSources(Cfg);
233 }
234
235 void Inst::dumpSources(const IceCfg *Cfg) const {
236 IceOstream &Str = Cfg->getContext()->getStrDump();
237 for (IceSize_t I = 0; I < getSrcSize(); ++I) {
238 if (I > 0)
239 Str << ", ";
240 getSrc(I)->dump(Cfg);
241 }
242 }
243
244 void Inst::dumpDest(const IceCfg *Cfg) const {
245 if (getDest())
246 getDest()->dump(Cfg);
247 }
248
249 void InstAlloca::dump(const IceCfg *Cfg) const {
250 IceOstream &Str = Cfg->getContext()->getStrDump();
251 dumpDest(Cfg);
252 Str << " = alloca i8, i32 ";
253 getSizeInBytes()->dump(Cfg);
254 Str << ", align " << Align;
255 }
256
257 void InstArithmetic::dump(const IceCfg *Cfg) const {
258 IceOstream &Str = Cfg->getContext()->getStrDump();
259 dumpDest(Cfg);
260 Str << " = ";
261
262 #define X(tag, str, commutative) \
263 case tag: \
264 Str << str; \
265 break;
266
267 switch (getOp()) { ICEINSTARITHMETIC_TABLE }
JF 2014/04/23 03:51:28 Same thing on table lookup from static const char
Jim Stichnoth 2014/04/26 15:02:11 Done.
268 #undef X
269
270 Str << " " << getDest()->getType() << " ";
271 dumpSources(Cfg);
272 }
273
274 void InstAssign::dump(const IceCfg *Cfg) const {
275 IceOstream &Str = Cfg->getContext()->getStrDump();
276 dumpDest(Cfg);
277 Str << " = " << getDest()->getType() << " ";
278 dumpSources(Cfg);
279 }
280
281 void InstBr::dump(const IceCfg *Cfg) const {
282 IceOstream &Str = Cfg->getContext()->getStrDump();
283 dumpDest(Cfg);
284 Str << "br ";
285 if (!isUnconditional()) {
286 Str << "i1 ";
287 getCondition()->dump(Cfg);
288 Str << ", label %" << getTargetTrue()->getName() << ", ";
289 }
290 Str << "label %" << getTargetFalse()->getName();
291 }
292
293 void InstCall::dump(const IceCfg *Cfg) const {
294 IceOstream &Str = Cfg->getContext()->getStrDump();
295 if (getDest()) {
296 dumpDest(Cfg);
297 Str << " = ";
298 }
299 if (Tail)
300 Str << "tail ";
301 Str << "call ";
302 if (getDest())
303 Str << getDest()->getType();
304 else
305 Str << "void";
306 Str << " ";
307 getCallTarget()->dump(Cfg);
308 Str << "(";
309 for (IceSize_t I = 0; I < getNumArgs(); ++I) {
310 if (I > 0)
311 Str << ", ";
312 Str << getArg(I)->getType() << " ";
313 getArg(I)->dump(Cfg);
314 }
315 Str << ")";
316 }
317
318 void InstCast::dump(const IceCfg *Cfg) const {
319 IceOstream &Str = Cfg->getContext()->getStrDump();
320 dumpDest(Cfg);
321 Str << " = ";
322
323 #define X(tag, str) \
324 case tag: \
325 Str << str; \
326 break;
327
328 switch (getCastKind()) {
329 ICEINSTCAST_TABLE
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
330 default:
331 Str << "UNKNOWN";
332 assert(0);
333 break;
334 }
335 #undef X
336
337 Str << " " << getSrc(0)->getType() << " ";
338 dumpSources(Cfg);
339 Str << " to " << getDest()->getType();
340 }
341
342 void InstIcmp::dump(const IceCfg *Cfg) const {
343 IceOstream &Str = Cfg->getContext()->getStrDump();
344 dumpDest(Cfg);
345 Str << " = icmp ";
346
347 #define X(tag, str) \
348 case tag: \
349 Str << str; \
350 break;
351
352 switch (getCondition()) { ICEINSTICMP_TABLE }
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
353 #undef X
354 Str << " " << getSrc(0)->getType() << " ";
355 dumpSources(Cfg);
356 }
357
358 void InstFcmp::dump(const IceCfg *Cfg) const {
359 IceOstream &Str = Cfg->getContext()->getStrDump();
360 dumpDest(Cfg);
361 Str << " = fcmp ";
362
363 #define X(tag, str) \
364 case tag: \
365 Str << str; \
366 break;
367
368 switch (getCondition()) { ICEINSTFCMP_TABLE }
JF 2014/04/23 03:51:28 Same.
Jim Stichnoth 2014/04/26 15:02:11 Done.
369 #undef X
370 Str << " " << getSrc(0)->getType() << " ";
371 dumpSources(Cfg);
372 }
373
374 void InstLoad::dump(const IceCfg *Cfg) const {
375 IceOstream &Str = Cfg->getContext()->getStrDump();
376 dumpDest(Cfg);
377 IceType Type = getDest()->getType();
378 Str << " = load " << Type << "* ";
379 dumpSources(Cfg);
380 switch (Type) {
381 case IceType_f32:
382 Str << ", align 4";
383 break;
384 case IceType_f64:
385 Str << ", align 8";
386 break;
387 default:
388 Str << ", align 1";
389 break;
390 }
391 }
392
393 void InstStore::dump(const IceCfg *Cfg) const {
394 IceOstream &Str = Cfg->getContext()->getStrDump();
395 IceType Type = getData()->getType();
396 Str << "store " << Type << " ";
397 getData()->dump(Cfg);
398 Str << ", " << Type << "* ";
399 getAddr()->dump(Cfg);
400 Str << ", align ";
401 switch (Type) {
402 case IceType_f32:
403 Str << "4";
404 break;
405 case IceType_f64:
406 Str << "8";
407 break;
408 default:
409 Str << "1";
410 break;
411 }
412 }
413
414 void InstSwitch::dump(const IceCfg *Cfg) const {
415 IceOstream &Str = Cfg->getContext()->getStrDump();
416 IceType Type = getComparison()->getType();
417 Str << "switch " << Type << " ";
418 getSrc(0)->dump(Cfg);
419 Str << ", label %" << getLabelDefault()->getName() << " [\n";
420 for (IceSize_t I = 0; I < getNumCases(); ++I) {
421 Str << " " << Type << " " << getValue(I) << ", label %"
422 << getLabel(I)->getName() << "\n";
423 }
424 Str << " ]";
425 }
426
427 void InstPhi::dump(const IceCfg *Cfg) const {
428 IceOstream &Str = Cfg->getContext()->getStrDump();
429 dumpDest(Cfg);
430 Str << " = phi " << getDest()->getType() << " ";
431 for (IceSize_t I = 0; I < getSrcSize(); ++I) {
432 if (I > 0)
433 Str << ", ";
434 Str << "[ ";
435 getSrc(I)->dump(Cfg);
436 Str << ", %" << Labels[I]->getName() << " ]";
437 }
438 }
439
440 void InstRet::dump(const IceCfg *Cfg) const {
441 IceOstream &Str = Cfg->getContext()->getStrDump();
442 IceType Type = hasRetValue() ? getSrc(0)->getType() : IceType_void;
443 Str << "ret " << Type;
444 if (hasRetValue()) {
445 Str << " ";
446 dumpSources(Cfg);
447 }
448 }
449
450 void InstSelect::dump(const IceCfg *Cfg) const {
451 IceOstream &Str = Cfg->getContext()->getStrDump();
452 dumpDest(Cfg);
453 Operand *Condition = getCondition();
454 Operand *TrueOp = getTrueOperand();
455 Operand *FalseOp = getFalseOperand();
456 Str << " = select " << Condition->getType() << " ";
457 Condition->dump(Cfg);
458 Str << ", " << TrueOp->getType() << " ";
459 TrueOp->dump(Cfg);
460 Str << ", " << FalseOp->getType() << " ";
461 FalseOp->dump(Cfg);
462 }
463
464 void InstUnreachable::dump(const IceCfg *Cfg) const {
465 IceOstream &Str = Cfg->getContext()->getStrDump();
466 Str << "unreachable";
467 }
468
469 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698