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

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: Address Jan's latest comments 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);
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:
55 case And:
56 case Or:
57 case Xor:
58 return true;
59 default:
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);
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 IceOstream &operator<<(IceOstream &Str, const IceInst *I) {
192 if (!Str.isVerbose(IceV_Deleted) && (I->isDeleted()))
193 return Str;
194 if (Str.isVerbose(IceV_InstNumbers)) {
195 char buf[30];
196 int32_t Number = I->getNumber();
197 if (Number < 0)
198 sprintf(buf, "[XXX]");
199 else
200 sprintf(buf, "[%3d]", I->getNumber());
201 Str << buf;
202 }
203 Str << " ";
204 if (I->isDeleted())
205 Str << " //";
206 I->dump(Str);
207 Str << "\n";
208 return Str;
209 }
210
211 void IceInst::dump(IceOstream &Str) const {
212 dumpDest(Str);
213 Str << " =~ ";
214 dumpSources(Str);
215 }
216
217 void IceInst::dumpSources(IceOstream &Str) const {
218 for (uint32_t I = 0; I < getSrcSize(); ++I) {
219 if (I > 0)
220 Str << ", ";
221 Str << getSrc(I);
222 }
223 }
224
225 void IceInst::dumpDest(IceOstream &Str) const {
226 if (getDest())
227 Str << getDest();
228 }
229
230 void IceInstAlloca::dump(IceOstream &Str) const {
231 dumpDest(Str);
232 Str << " = alloca i8, i32 ";
233 Str << getSrc(0) << ", align " << Align;
234 }
235
236 void IceInstArithmetic::dump(IceOstream &Str) const {
237 dumpDest(Str);
238 Str << " = ";
239 switch (getOp()) {
240 case Add:
241 Str << "add";
242 break;
243 case Fadd:
244 Str << "fadd";
245 break;
246 case Sub:
247 Str << "sub";
248 break;
249 case Fsub:
250 Str << "fsub";
251 break;
252 case Mul:
253 Str << "mul";
254 break;
255 case Fmul:
256 Str << "fmul";
257 break;
258 case Udiv:
259 Str << "udiv";
260 break;
261 case Sdiv:
262 Str << "sdiv";
263 break;
264 case Fdiv:
265 Str << "fdiv";
266 break;
267 case Urem:
268 Str << "urem";
269 break;
270 case Srem:
271 Str << "srem";
272 break;
273 case Frem:
274 Str << "frem";
275 break;
276 case Shl:
277 Str << "shl";
278 break;
279 case Lshr:
280 Str << "lshr";
281 break;
282 case Ashr:
283 Str << "ashr";
284 break;
285 case And:
286 Str << "and";
287 break;
288 case Or:
289 Str << "or";
290 break;
291 case Xor:
292 Str << "xor";
293 break;
294 }
295 Str << " " << getDest()->getType() << " ";
296 dumpSources(Str);
297 }
298
299 void IceInstAssign::dump(IceOstream &Str) const {
300 dumpDest(Str);
301 Str << " = " << getDest()->getType() << " ";
302 dumpSources(Str);
303 }
304
305 void IceInstBr::dump(IceOstream &Str) const {
306 dumpDest(Str);
307 Str << "br ";
308 if (!isUnconditional()) {
309 Str << "i1 " << getSrc(0) << ", label %" << getTargetTrue()->getName()
310 << ", ";
311 }
312 Str << "label %" << getTargetFalse()->getName();
313 }
314
315 void IceInstCall::dump(IceOstream &Str) const {
316 if (getDest()) {
317 dumpDest(Str);
318 Str << " = ";
319 }
320 if (Tail)
321 Str << "tail ";
322 Str << "call ";
323 if (getDest())
324 Str << getDest()->getType();
325 else
326 Str << "void";
327 Str << " " << getCallTarget() << "(";
328 for (uint32_t I = 0; I < getNumArgs(); ++I) {
329 if (I > 0)
330 Str << ", ";
331 Str << getArg(I)->getType() << " " << getArg(I);
332 }
333 Str << ")";
334 }
335
336 void IceInstCast::dump(IceOstream &Str) const {
337 dumpDest(Str);
338 Str << " = ";
339 switch (getCastKind()) {
340 default:
341 Str << "UNKNOWN";
342 assert(0);
343 break;
344 case Trunc:
345 Str << "trunc";
346 break;
347 case Zext:
348 Str << "zext";
349 break;
350 case Sext:
351 Str << "sext";
352 break;
353 case Fptrunc:
354 Str << "fptrunc";
355 break;
356 case Fpext:
357 Str << "fpext";
358 break;
359 case Fptoui:
360 Str << "fptoui";
361 break;
362 case Fptosi:
363 Str << "fptosi";
364 break;
365 case Uitofp:
366 Str << "uitofp";
367 break;
368 case Sitofp:
369 Str << "sitofp";
370 break;
371 case Bitcast:
372 Str << "bitcast";
373 break;
374 }
375 Str << " " << getSrc(0)->getType() << " ";
376 dumpSources(Str);
377 Str << " to " << getDest()->getType();
378 }
379
380 void IceInstIcmp::dump(IceOstream &Str) const {
381 dumpDest(Str);
382 Str << " = icmp ";
383 switch (getCondition()) {
384 case Eq:
385 Str << "eq";
386 break;
387 case Ne:
388 Str << "ne";
389 break;
390 case Ugt:
391 Str << "ugt";
392 break;
393 case Uge:
394 Str << "uge";
395 break;
396 case Ult:
397 Str << "ult";
398 break;
399 case Ule:
400 Str << "ule";
401 break;
402 case Sgt:
403 Str << "sgt";
404 break;
405 case Sge:
406 Str << "sge";
407 break;
408 case Slt:
409 Str << "slt";
410 break;
411 case Sle:
412 Str << "sle";
413 break;
414 }
415 Str << " " << getSrc(0)->getType() << " ";
416 dumpSources(Str);
417 }
418
419 void IceInstFcmp::dump(IceOstream &Str) const {
420 dumpDest(Str);
421 Str << " = fcmp ";
422
423 switch (getCondition()) {
424 case False:
425 Str << "false";
426 break;
427 case Oeq:
428 Str << "oeq";
429 break;
430 case Ogt:
431 Str << "ogt";
432 break;
433 case Oge:
434 Str << "oge";
435 break;
436 case Olt:
437 Str << "olt";
438 break;
439 case Ole:
440 Str << "ole";
441 break;
442 case One:
443 Str << "one";
444 break;
445 case Ord:
446 Str << "ord";
447 break;
448 case Ueq:
449 Str << "ueq";
450 break;
451 case Ugt:
452 Str << "ugt";
453 break;
454 case Uge:
455 Str << "uge";
456 break;
457 case Ult:
458 Str << "ult";
459 break;
460 case Ule:
461 Str << "ule";
462 break;
463 case Une:
464 Str << "une";
465 break;
466 case Uno:
467 Str << "uno";
468 break;
469 case True:
470 Str << "true";
471 break;
472 }
473 Str << " " << getSrc(0)->getType() << " ";
474 dumpSources(Str);
475 }
476
477 void IceInstLoad::dump(IceOstream &Str) const {
478 dumpDest(Str);
479 IceType Type = getDest()->getType();
480 Str << " = load " << Type << "* ";
481 dumpSources(Str);
482 switch (Type) {
483 case IceType_f32:
484 Str << ", align 4";
485 break;
486 case IceType_f64:
487 Str << ", align 8";
488 break;
489 default:
490 Str << ", align 1";
491 break;
492 }
493 }
494
495 void IceInstStore::dump(IceOstream &Str) const {
496 IceType Type = getData()->getType();
497 Str << "store " << Type << " " << getData() << ", " << Type << "* "
498 << getAddr() << ", align ";
499 switch (Type) {
500 case IceType_f32:
501 Str << "4";
502 break;
503 case IceType_f64:
504 Str << "8";
505 break;
506 default:
507 Str << "1";
508 break;
509 }
510 }
511
512 void IceInstSwitch::dump(IceOstream &Str) const {
513 IceType Type = getSrc(0)->getType();
514 Str << "switch " << Type << " " << getSrc(0) << ", label %"
515 << getLabelDefault()->getName() << " [\n";
516 for (uint32_t I = 0; I < getNumCases(); ++I) {
517 Str << " " << Type << " " << getValue(I) << ", label %"
518 << getLabel(I)->getName() << "\n";
519 }
520 Str << " ]";
521 }
522
523 void IceInstPhi::dump(IceOstream &Str) const {
524 dumpDest(Str);
525 Str << " = phi " << getDest()->getType() << " ";
526 for (uint32_t I = 0; I < getSrcSize(); ++I) {
527 if (I > 0)
528 Str << ", ";
529 Str << "[ " << getSrc(I) << ", %" << Labels[I]->getName() << " ]";
530 }
531 }
532
533 void IceInstRet::dump(IceOstream &Str) const {
534 IceType Type = getSrcSize() == 0 ? IceType_void : getSrc(0)->getType();
535 Str << "ret " << Type;
536 if (getSrcSize()) {
537 Str << " ";
538 dumpSources(Str);
539 }
540 }
541
542 void IceInstSelect::dump(IceOstream &Str) const {
543 dumpDest(Str);
544 IceOperand *Condition = getCondition();
545 IceOperand *TrueOp = getTrueOperand();
546 IceOperand *FalseOp = getFalseOperand();
547 Str << " = select " << Condition->getType() << " " << Condition << ", "
548 << TrueOp->getType() << " " << TrueOp << ", " << FalseOp->getType() << " "
549 << FalseOp;
550 }
551
552 void IceInstUnreachable::dump(IceOstream &Str) const { Str << "unreachable"; }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698