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

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: Introduce IceGlobalContext, and rearrange other things around that 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 IceInst 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 IceInst::IceInst(IceCfg *Cfg, InstKind Kind, uint32_t MaxSrcs,
21 IceVariable *Dest)
22 : Kind(Kind), Deleted(false), HasSideEffects(false), Dest(Dest),
23 MaxSrcs(MaxSrcs), NumSrcs(0) {
24 Number = Cfg->newInstNumber();
25 Srcs = Cfg->allocateArrayOf<IceOperand *>(MaxSrcs);
JF 2014/04/16 01:27:32 Move to the initialization list.
Jim Stichnoth 2014/04/21 20:26:40 Done.
26 }
27
28 void IceInst::updateVars(IceCfgNode *Node) {
29 if (Dest)
30 Dest->setDefinition(this, Node);
31 for (uint32_t I = 0; I < getSrcSize(); ++I) {
32 getSrc(I)->setUse(this, Node);
33 }
34 }
35
36 IceInstAlloca::IceInstAlloca(IceCfg *Cfg, IceOperand *ByteCount, uint32_t Align,
37 IceVariable *Dest)
38 : IceInst(Cfg, IceInst::Alloca, 1, Dest), Align(Align) {
39 addSource(ByteCount);
40 }
41
42 IceInstArithmetic::IceInstArithmetic(IceCfg *Cfg, OpKind Op, IceVariable *Dest,
43 IceOperand *Source1, IceOperand *Source2)
44 : IceInst(Cfg, IceInst::Arithmetic, 2, Dest), Op(Op) {
45 addSource(Source1);
46 addSource(Source2);
47 }
48
49 bool IceInstArithmetic::isCommutative() const {
50 switch (getOp()) {
51 case Add:
52 case Fadd:
53 case Mul:
54 case Fmul:
JF 2014/04/16 01:27:32 Fadd and Fmul aren't commutative.
Jim Stichnoth 2014/04/21 20:26:40 Done. I was sad to learn this.
Jim Stichnoth 2015/09/25 17:23:09 LLVM disagrees... see Instruction::isCommutative()
55 case And:
56 case Or:
57 case Xor:
58 return true;
59 default:
JF 2014/04/16 01:27:32 It would be better to list everything so that if y
Jim Stichnoth 2014/04/21 20:26:40 Done. And converted to x-macros.
60 return false;
61 }
62 }
63
64 IceInstAssign::IceInstAssign(IceCfg *Cfg, IceVariable *Dest, IceOperand *Source)
65 : IceInst(Cfg, IceInst::Assign, 1, Dest) {
66 addSource(Source);
67 }
68
69 // If TargetTrue==TargetFalse, we turn it into an unconditional
70 // branch. This ensures that, along with the 'switch' instruction
71 // semantics, there is at most one edge from one node to another.
72 IceInstBr::IceInstBr(IceCfg *Cfg, IceOperand *Source, IceCfgNode *TargetTrue,
73 IceCfgNode *TargetFalse)
74 : IceInst(Cfg, IceInst::Br, 1, NULL), TargetFalse(TargetFalse),
75 TargetTrue(TargetTrue) {
76 if (TargetTrue == TargetFalse) {
77 TargetTrue = NULL; // turn into unconditional version
78 } else {
79 addSource(Source);
JF 2014/04/16 01:27:32 It doesn't look like you have an invariant on True
Jim Stichnoth 2014/04/21 20:26:40 You crash, of course. :) Here and in all other in
80 }
81 }
82
83 IceInstBr::IceInstBr(IceCfg *Cfg, IceCfgNode *Target)
84 : IceInst(Cfg, IceInst::Br, 0, NULL), TargetFalse(Target),
85 TargetTrue(NULL) {}
86
87 IceNodeList IceInstBr::getTerminatorEdges() const {
88 IceNodeList OutEdges;
89 OutEdges.push_back(TargetFalse);
90 if (TargetTrue)
91 OutEdges.push_back(TargetTrue);
92 return OutEdges;
93 }
94
95 IceInstCast::IceInstCast(IceCfg *Cfg, OpKind CastKind, IceVariable *Dest,
96 IceOperand *Source)
97 : IceInst(Cfg, IceInst::Cast, 1, Dest), CastKind(CastKind) {
98 addSource(Source);
99 }
100
101 IceInstFcmp::IceInstFcmp(IceCfg *Cfg, FCond Condition, IceVariable *Dest,
102 IceOperand *Source1, IceOperand *Source2)
103 : IceInst(Cfg, IceInst::Fcmp, 2, Dest), Condition(Condition) {
104 addSource(Source1);
105 addSource(Source2);
106 }
107
108 IceInstIcmp::IceInstIcmp(IceCfg *Cfg, ICond Condition, IceVariable *Dest,
109 IceOperand *Source1, IceOperand *Source2)
110 : IceInst(Cfg, IceInst::Icmp, 2, Dest), Condition(Condition) {
111 addSource(Source1);
112 addSource(Source2);
113 }
114
115 IceInstLoad::IceInstLoad(IceCfg *Cfg, IceVariable *Dest, IceOperand *SourceAddr)
116 : IceInst(Cfg, IceInst::Load, 1, Dest) {
117 addSource(SourceAddr);
118 }
119
120 IceInstPhi::IceInstPhi(IceCfg *Cfg, uint32_t MaxSrcs, IceVariable *Dest)
121 : IceInst(Cfg, Phi, MaxSrcs, Dest) {
122 Labels = Cfg->allocateArrayOf<IceCfgNode *>(MaxSrcs);
123 }
124
125 // TODO: A Switch instruction (and maybe others) can add duplicate
126 // edges. We may want to de-dup Phis and validate consistency (i.e.,
127 // the source operands are the same for duplicate edges), though it
128 // seems the current lowering code is OK with this situation.
129 void IceInstPhi::addArgument(IceOperand *Source, IceCfgNode *Label) {
130 Labels[getSrcSize()] = Label;
131 addSource(Source);
132 }
133
134 IceInstRet::IceInstRet(IceCfg *Cfg, IceOperand *Source)
135 : IceInst(Cfg, Ret, Source ? 1 : 0, NULL) {
136 if (Source)
137 addSource(Source);
138 }
139
140 IceInstSelect::IceInstSelect(IceCfg *Cfg, IceVariable *Dest,
141 IceOperand *Condition, IceOperand *SourceTrue,
142 IceOperand *SourceFalse)
143 : IceInst(Cfg, IceInst::Select, 3, Dest) {
144 assert(Condition->getType() == IceType_i1);
145 addSource(Condition);
146 addSource(SourceTrue);
147 addSource(SourceFalse);
148 }
149
150 IceInstStore::IceInstStore(IceCfg *Cfg, IceOperand *Data, IceOperand *Addr)
151 : IceInst(Cfg, IceInst::Store, 2, NULL) {
152 addSource(Data);
153 addSource(Addr);
154 }
155
156 IceInstSwitch::IceInstSwitch(IceCfg *Cfg, uint32_t NumCases, IceOperand *Source,
157 IceCfgNode *LabelDefault)
158 : IceInst(Cfg, IceInst::Switch, 1, NULL), LabelDefault(LabelDefault),
159 NumCases(NumCases) {
160 addSource(Source);
161 Values = Cfg->allocateArrayOf<uint64_t>(NumCases);
162 Labels = Cfg->allocateArrayOf<IceCfgNode *>(NumCases);
163 // Initialize in case buggy code doesn't set all entries
164 for (uint32_t I = 0; I < NumCases; ++I) {
165 Values[I] = 0;
166 Labels[I] = NULL;
167 }
168 }
169
170 void IceInstSwitch::addBranch(uint32_t CaseIndex, uint64_t Value,
171 IceCfgNode *Label) {
172 assert(CaseIndex < NumCases);
173 Values[CaseIndex] = Value;
174 Labels[CaseIndex] = Label;
175 }
176
177 IceNodeList IceInstSwitch::getTerminatorEdges() const {
178 IceNodeList OutEdges;
179 OutEdges.push_back(LabelDefault);
180 for (uint32_t I = 0; I < NumCases; ++I) {
181 OutEdges.push_back(Labels[I]);
182 }
183 return OutEdges;
184 }
185
186 IceInstUnreachable::IceInstUnreachable(IceCfg *Cfg)
187 : IceInst(Cfg, IceInst::Unreachable, 0, NULL) {}
188
189 // ======================== Dump routines ======================== //
190
191 void IceInst::dumpDecorated(const IceCfg *Cfg) const {
192 IceOstream &Str = Cfg->getContext()->StrDump;
193 if (!Cfg->getContext()->isVerbose(IceV_Deleted) && isDeleted())
194 return;
195 if (Cfg->getContext()->isVerbose(IceV_InstNumbers)) {
196 char buf[30];
197 int32_t Number = getNumber();
198 if (Number < 0)
199 sprintf(buf, "[XXX]");
200 else
201 sprintf(buf, "[%3d]", Number);
202 Str << buf;
203 }
204 Str << " ";
205 if (isDeleted())
206 Str << " //";
207 dump(Cfg);
208 Str << "\n";
209 }
210
211 void IceInst::dump(const IceCfg *Cfg) const {
212 IceOstream &Str = Cfg->getContext()->StrDump;
213 dumpDest(Cfg);
214 Str << " =~ ";
215 dumpSources(Cfg);
216 }
217
218 void IceInst::dumpSources(const IceCfg *Cfg) const {
219 IceOstream &Str = Cfg->getContext()->StrDump;
220 for (uint32_t I = 0; I < getSrcSize(); ++I) {
221 if (I > 0)
222 Str << ", ";
223 getSrc(I)->dump(Cfg);
224 }
225 }
226
227 void IceInst::dumpDest(const IceCfg *Cfg) const {
228 if (getDest())
229 getDest()->dump(Cfg);
230 }
231
232 void IceInstAlloca::dump(const IceCfg *Cfg) const {
233 IceOstream &Str = Cfg->getContext()->StrDump;
234 dumpDest(Cfg);
235 Str << " = alloca i8, i32 ";
236 getSrc(0)->dump(Cfg);
237 Str << ", align " << Align;
238 }
239
240 void IceInstArithmetic::dump(const IceCfg *Cfg) const {
241 IceOstream &Str = Cfg->getContext()->StrDump;
242 dumpDest(Cfg);
243 Str << " = ";
244 switch (getOp()) {
245 case Add:
246 Str << "add";
247 break;
248 case Fadd:
249 Str << "fadd";
250 break;
251 case Sub:
252 Str << "sub";
253 break;
254 case Fsub:
255 Str << "fsub";
256 break;
257 case Mul:
258 Str << "mul";
259 break;
260 case Fmul:
261 Str << "fmul";
262 break;
263 case Udiv:
264 Str << "udiv";
265 break;
266 case Sdiv:
267 Str << "sdiv";
268 break;
269 case Fdiv:
270 Str << "fdiv";
271 break;
272 case Urem:
273 Str << "urem";
274 break;
275 case Srem:
276 Str << "srem";
277 break;
278 case Frem:
279 Str << "frem";
280 break;
281 case Shl:
282 Str << "shl";
283 break;
284 case Lshr:
285 Str << "lshr";
286 break;
287 case Ashr:
288 Str << "ashr";
289 break;
290 case And:
291 Str << "and";
292 break;
293 case Or:
294 Str << "or";
295 break;
296 case Xor:
297 Str << "xor";
298 break;
JF 2014/04/16 01:27:32 Another place where xmacros would be nice ;-)
Jim Stichnoth 2014/04/21 20:26:40 Done.
299 }
300 Str << " " << getDest()->getType() << " ";
301 dumpSources(Cfg);
302 }
303
304 void IceInstAssign::dump(const IceCfg *Cfg) const {
305 IceOstream &Str = Cfg->getContext()->StrDump;
306 dumpDest(Cfg);
307 Str << " = " << getDest()->getType() << " ";
308 dumpSources(Cfg);
309 }
310
311 void IceInstBr::dump(const IceCfg *Cfg) const {
312 IceOstream &Str = Cfg->getContext()->StrDump;
313 dumpDest(Cfg);
314 Str << "br ";
315 if (!isUnconditional()) {
316 Str << "i1 ";
317 getSrc(0)->dump(Cfg);
318 Str << ", label %" << getTargetTrue()->getName() << ", ";
319 }
320 Str << "label %" << getTargetFalse()->getName();
321 }
322
323 void IceInstCall::dump(const IceCfg *Cfg) const {
324 IceOstream &Str = Cfg->getContext()->StrDump;
325 if (getDest()) {
326 dumpDest(Cfg);
327 Str << " = ";
328 }
329 if (Tail)
330 Str << "tail ";
331 Str << "call ";
332 if (getDest())
333 Str << getDest()->getType();
334 else
335 Str << "void";
336 Str << " ";
337 getCallTarget()->dump(Cfg);
338 Str << "(";
339 for (uint32_t I = 0; I < getNumArgs(); ++I) {
340 if (I > 0)
341 Str << ", ";
342 Str << getArg(I)->getType() << " ";
343 getArg(I)->dump(Cfg);
344 }
345 Str << ")";
346 }
347
348 void IceInstCast::dump(const IceCfg *Cfg) const {
349 IceOstream &Str = Cfg->getContext()->StrDump;
350 dumpDest(Cfg);
351 Str << " = ";
352 switch (getCastKind()) {
353 default:
354 Str << "UNKNOWN";
355 assert(0);
356 break;
357 case Trunc:
358 Str << "trunc";
359 break;
360 case Zext:
361 Str << "zext";
362 break;
363 case Sext:
364 Str << "sext";
365 break;
366 case Fptrunc:
367 Str << "fptrunc";
368 break;
369 case Fpext:
370 Str << "fpext";
371 break;
372 case Fptoui:
373 Str << "fptoui";
374 break;
375 case Fptosi:
376 Str << "fptosi";
377 break;
378 case Uitofp:
379 Str << "uitofp";
380 break;
381 case Sitofp:
382 Str << "sitofp";
383 break;
384 case Bitcast:
385 Str << "bitcast";
386 break;
JF 2014/04/16 01:27:32 xmacros :-)
Jim Stichnoth 2014/04/21 20:26:40 Done.
387 }
388 Str << " " << getSrc(0)->getType() << " ";
389 dumpSources(Cfg);
390 Str << " to " << getDest()->getType();
391 }
392
393 void IceInstIcmp::dump(const IceCfg *Cfg) const {
394 IceOstream &Str = Cfg->getContext()->StrDump;
395 dumpDest(Cfg);
396 Str << " = icmp ";
397 switch (getCondition()) {
398 case Eq:
399 Str << "eq";
400 break;
401 case Ne:
402 Str << "ne";
403 break;
404 case Ugt:
405 Str << "ugt";
406 break;
407 case Uge:
408 Str << "uge";
409 break;
410 case Ult:
411 Str << "ult";
412 break;
413 case Ule:
414 Str << "ule";
415 break;
416 case Sgt:
417 Str << "sgt";
418 break;
419 case Sge:
420 Str << "sge";
421 break;
422 case Slt:
423 Str << "slt";
424 break;
425 case Sle:
426 Str << "sle";
427 break;
JF 2014/04/16 01:27:32 Ditto.
Jim Stichnoth 2014/04/21 20:26:40 Done.
428 }
429 Str << " " << getSrc(0)->getType() << " ";
430 dumpSources(Cfg);
431 }
432
433 void IceInstFcmp::dump(const IceCfg *Cfg) const {
434 IceOstream &Str = Cfg->getContext()->StrDump;
435 dumpDest(Cfg);
436 Str << " = fcmp ";
437
438 switch (getCondition()) {
439 case False:
440 Str << "false";
441 break;
442 case Oeq:
443 Str << "oeq";
444 break;
445 case Ogt:
446 Str << "ogt";
447 break;
448 case Oge:
449 Str << "oge";
450 break;
451 case Olt:
452 Str << "olt";
453 break;
454 case Ole:
455 Str << "ole";
456 break;
457 case One:
458 Str << "one";
459 break;
460 case Ord:
461 Str << "ord";
462 break;
463 case Ueq:
464 Str << "ueq";
465 break;
466 case Ugt:
467 Str << "ugt";
468 break;
469 case Uge:
470 Str << "uge";
471 break;
472 case Ult:
473 Str << "ult";
474 break;
475 case Ule:
476 Str << "ule";
477 break;
478 case Une:
479 Str << "une";
480 break;
481 case Uno:
482 Str << "uno";
483 break;
484 case True:
485 Str << "true";
486 break;
JF 2014/04/16 01:27:32 Ditto.
Jim Stichnoth 2014/04/21 20:26:40 Done.
487 }
488 Str << " " << getSrc(0)->getType() << " ";
489 dumpSources(Cfg);
490 }
491
492 void IceInstLoad::dump(const IceCfg *Cfg) const {
493 IceOstream &Str = Cfg->getContext()->StrDump;
494 dumpDest(Cfg);
495 IceType Type = getDest()->getType();
496 Str << " = load " << Type << "* ";
497 dumpSources(Cfg);
498 switch (Type) {
499 case IceType_f32:
500 Str << ", align 4";
501 break;
502 case IceType_f64:
503 Str << ", align 8";
504 break;
505 default:
506 Str << ", align 1";
507 break;
508 }
509 }
510
511 void IceInstStore::dump(const IceCfg *Cfg) const {
512 IceOstream &Str = Cfg->getContext()->StrDump;
513 IceType Type = getData()->getType();
514 Str << "store " << Type << " ";
515 getData()->dump(Cfg);
516 Str << ", " << Type << "* ";
517 getAddr()->dump(Cfg);
518 Str << ", align ";
519 switch (Type) {
520 case IceType_f32:
521 Str << "4";
522 break;
523 case IceType_f64:
524 Str << "8";
525 break;
526 default:
527 Str << "1";
528 break;
529 }
530 }
531
532 void IceInstSwitch::dump(const IceCfg *Cfg) const {
533 IceOstream &Str = Cfg->getContext()->StrDump;
534 IceType Type = getSrc(0)->getType();
535 Str << "switch " << Type << " ";
536 getSrc(0)->dump(Cfg);
537 Str << ", label %" << getLabelDefault()->getName() << " [\n";
538 for (uint32_t I = 0; I < getNumCases(); ++I) {
539 Str << " " << Type << " " << getValue(I) << ", label %"
540 << getLabel(I)->getName() << "\n";
541 }
542 Str << " ]";
543 }
544
545 void IceInstPhi::dump(const IceCfg *Cfg) const {
546 IceOstream &Str = Cfg->getContext()->StrDump;
547 dumpDest(Cfg);
548 Str << " = phi " << getDest()->getType() << " ";
549 for (uint32_t I = 0; I < getSrcSize(); ++I) {
550 if (I > 0)
551 Str << ", ";
552 Str << "[ ";
553 getSrc(I)->dump(Cfg);
554 Str << ", %" << Labels[I]->getName() << " ]";
555 }
556 }
557
558 void IceInstRet::dump(const IceCfg *Cfg) const {
559 IceOstream &Str = Cfg->getContext()->StrDump;
560 IceType Type = getSrcSize() == 0 ? IceType_void : getSrc(0)->getType();
561 Str << "ret " << Type;
562 if (getSrcSize()) {
563 Str << " ";
564 dumpSources(Cfg);
565 }
566 }
567
568 void IceInstSelect::dump(const IceCfg *Cfg) const {
569 IceOstream &Str = Cfg->getContext()->StrDump;
570 dumpDest(Cfg);
571 IceOperand *Condition = getCondition();
572 IceOperand *TrueOp = getTrueOperand();
573 IceOperand *FalseOp = getFalseOperand();
574 Str << " = select " << Condition->getType() << " ";
575 Condition->dump(Cfg);
576 Str << ", " << TrueOp->getType() << " ";
577 TrueOp->dump(Cfg);
578 Str << ", " << FalseOp->getType() << " ";
579 FalseOp->dump(Cfg);
580 }
581
582 void IceInstUnreachable::dump(const IceCfg *Cfg) const {
583 IceOstream &Str = Cfg->getContext()->StrDump;
584 Str << "unreachable";
585 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698