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

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

Powered by Google App Engine
This is Rietveld 408576698