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

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: Use non-anonymous structs so that array_lengthof works Created 6 years, 7 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
« no previous file with comments | « src/IceInst.h ('k') | src/IceInst.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 namespace {
23
24 // Using non-anonymous struct so that array_lengthof works.
25 const struct _InstArithmeticAttributes {
26 const char *DisplayString;
27 bool IsCommutative;
28 } InstArithmeticAttributes[] = {
29 #define X(tag, str, commutative) \
30 { str, commutative } \
31 ,
32 ICEINSTARITHMETIC_TABLE
33 #undef X
34 };
35 const size_t InstArithmeticAttributesSize =
36 llvm::array_lengthof(InstArithmeticAttributes);
37
38 // Using non-anonymous struct so that array_lengthof works.
39 const struct _InstCastAttributes {
40 const char *DisplayString;
41 } InstCastAttributes[] = {
42 #define X(tag, str) \
43 { str } \
44 ,
45 ICEINSTCAST_TABLE
46 #undef X
47 };
48 const size_t InstCastAttributesSize = llvm::array_lengthof(InstCastAttributes);
49
50 // Using non-anonymous struct so that array_lengthof works.
51 const struct _InstFcmpAttributes {
52 const char *DisplayString;
53 } InstFcmpAttributes[] = {
54 #define X(tag, str) \
55 { str } \
56 ,
57 ICEINSTFCMP_TABLE
58 #undef X
59 };
60 const size_t InstFcmpAttributesSize = llvm::array_lengthof(InstFcmpAttributes);
61
62 // Using non-anonymous struct so that array_lengthof works.
63 const struct _InstIcmpAttributes {
64 const char *DisplayString;
65 } InstIcmpAttributes[] = {
66 #define X(tag, str) \
67 { str } \
68 ,
69 ICEINSTICMP_TABLE
70 #undef X
71 };
72 const size_t InstIcmpAttributesSize = llvm::array_lengthof(InstIcmpAttributes);
73
74 } // end of anonymous namespace
75
76 Inst::Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest)
77 : Kind(Kind), Number(Func->newInstNumber()), Deleted(false),
78 HasSideEffects(false), Dest(Dest), MaxSrcs(MaxSrcs), NumSrcs(0),
79 Srcs(Func->allocateArrayOf<Operand *>(MaxSrcs)) {}
80
81 void Inst::updateVars(CfgNode *Node) {
82 if (Dest)
83 Dest->setDefinition(this, Node);
84
85 SizeT VarIndex = 0;
86 for (SizeT I = 0; I < getSrcSize(); ++I) {
87 Operand *Src = getSrc(I);
88 SizeT NumVars = Src->getNumVars();
89 for (SizeT J = 0; J < NumVars; ++J, ++VarIndex) {
90 Variable *Var = Src->getVar(J);
91 Var->setUse(this, Node);
92 }
93 }
94 }
95
96 InstAlloca::InstAlloca(Cfg *Func, Operand *ByteCount, uint32_t AlignInBytes,
97 Variable *Dest)
98 : Inst(Func, Inst::Alloca, 1, Dest), AlignInBytes(AlignInBytes) {
99 // Verify AlignInBytes is 0 or a power of 2.
100 assert(AlignInBytes == 0 || llvm::isPowerOf2_32(AlignInBytes));
101 addSource(ByteCount);
102 }
103
104 InstArithmetic::InstArithmetic(Cfg *Func, OpKind Op, Variable *Dest,
105 Operand *Source1, Operand *Source2)
106 : Inst(Func, Inst::Arithmetic, 2, Dest), Op(Op) {
107 addSource(Source1);
108 addSource(Source2);
109 }
110
111 bool InstArithmetic::isCommutative() const {
112 return InstArithmeticAttributes[getOp()].IsCommutative;
113 }
114
115 InstAssign::InstAssign(Cfg *Func, Variable *Dest, Operand *Source)
116 : Inst(Func, Inst::Assign, 1, Dest) {
117 addSource(Source);
118 }
119
120 // If TargetTrue==TargetFalse, we turn it into an unconditional
121 // branch. This ensures that, along with the 'switch' instruction
122 // semantics, there is at most one edge from one node to another.
123 InstBr::InstBr(Cfg *Func, Operand *Source, CfgNode *TargetTrue,
124 CfgNode *TargetFalse)
125 : Inst(Func, Inst::Br, 1, NULL), TargetFalse(TargetFalse),
126 TargetTrue(TargetTrue) {
127 if (TargetTrue == TargetFalse) {
128 TargetTrue = NULL; // turn into unconditional version
129 } else {
130 addSource(Source);
131 }
132 }
133
134 InstBr::InstBr(Cfg *Func, CfgNode *Target)
135 : Inst(Func, Inst::Br, 0, NULL), TargetFalse(Target), TargetTrue(NULL) {}
136
137 NodeList InstBr::getTerminatorEdges() const {
138 NodeList OutEdges;
139 OutEdges.push_back(TargetFalse);
140 if (TargetTrue)
141 OutEdges.push_back(TargetTrue);
142 return OutEdges;
143 }
144
145 InstCast::InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source)
146 : Inst(Func, Inst::Cast, 1, Dest), CastKind(CastKind) {
147 addSource(Source);
148 }
149
150 InstFcmp::InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1,
151 Operand *Source2)
152 : Inst(Func, Inst::Fcmp, 2, Dest), Condition(Condition) {
153 addSource(Source1);
154 addSource(Source2);
155 }
156
157 InstIcmp::InstIcmp(Cfg *Func, ICond Condition, Variable *Dest, Operand *Source1,
158 Operand *Source2)
159 : Inst(Func, Inst::Icmp, 2, Dest), Condition(Condition) {
160 addSource(Source1);
161 addSource(Source2);
162 }
163
164 InstLoad::InstLoad(Cfg *Func, Variable *Dest, Operand *SourceAddr)
165 : Inst(Func, Inst::Load, 1, Dest) {
166 addSource(SourceAddr);
167 }
168
169 InstPhi::InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest)
170 : Inst(Func, Phi, MaxSrcs, Dest) {
171 Labels = Func->allocateArrayOf<CfgNode *>(MaxSrcs);
172 }
173
174 // TODO: A Switch instruction (and maybe others) can add duplicate
175 // edges. We may want to de-dup Phis and validate consistency (i.e.,
176 // the source operands are the same for duplicate edges), though it
177 // seems the current lowering code is OK with this situation.
178 void InstPhi::addArgument(Operand *Source, CfgNode *Label) {
179 Labels[getSrcSize()] = Label;
180 addSource(Source);
181 }
182
183 InstRet::InstRet(Cfg *Func, Operand *RetValue)
184 : Inst(Func, Ret, RetValue ? 1 : 0, NULL) {
185 if (RetValue)
186 addSource(RetValue);
187 }
188
189 InstSelect::InstSelect(Cfg *Func, Variable *Dest, Operand *Condition,
190 Operand *SourceTrue, Operand *SourceFalse)
191 : Inst(Func, Inst::Select, 3, Dest) {
192 assert(Condition->getType() == IceType_i1);
193 addSource(Condition);
194 addSource(SourceTrue);
195 addSource(SourceFalse);
196 }
197
198 InstStore::InstStore(Cfg *Func, Operand *Data, Operand *Addr)
199 : Inst(Func, Inst::Store, 2, NULL) {
200 addSource(Data);
201 addSource(Addr);
202 }
203
204 InstSwitch::InstSwitch(Cfg *Func, SizeT NumCases, Operand *Source,
205 CfgNode *LabelDefault)
206 : Inst(Func, Inst::Switch, 1, NULL), LabelDefault(LabelDefault),
207 NumCases(NumCases) {
208 addSource(Source);
209 Values = Func->allocateArrayOf<uint64_t>(NumCases);
210 Labels = Func->allocateArrayOf<CfgNode *>(NumCases);
211 // Initialize in case buggy code doesn't set all entries
212 for (SizeT I = 0; I < NumCases; ++I) {
213 Values[I] = 0;
214 Labels[I] = NULL;
215 }
216 }
217
218 void InstSwitch::addBranch(SizeT CaseIndex, uint64_t Value, CfgNode *Label) {
219 assert(CaseIndex < NumCases);
220 Values[CaseIndex] = Value;
221 Labels[CaseIndex] = Label;
222 }
223
224 NodeList InstSwitch::getTerminatorEdges() const {
225 NodeList OutEdges;
226 OutEdges.push_back(LabelDefault);
227 for (SizeT I = 0; I < NumCases; ++I) {
228 OutEdges.push_back(Labels[I]);
229 }
230 return OutEdges;
231 }
232
233 InstUnreachable::InstUnreachable(Cfg *Func)
234 : Inst(Func, Inst::Unreachable, 0, NULL) {}
235
236 // ======================== Dump routines ======================== //
237
238 void Inst::dumpDecorated(const Cfg *Func) const {
239 Ostream &Str = Func->getContext()->getStrDump();
240 if (!Func->getContext()->isVerbose(IceV_Deleted) && isDeleted())
241 return;
242 if (Func->getContext()->isVerbose(IceV_InstNumbers)) {
243 char buf[30];
244 int32_t Number = getNumber();
245 if (Number < 0)
246 snprintf(buf, llvm::array_lengthof(buf), "[XXX]");
247 else
248 snprintf(buf, llvm::array_lengthof(buf), "[%3d]", Number);
249 Str << buf;
250 }
251 Str << " ";
252 if (isDeleted())
253 Str << " //";
254 dump(Func);
255 Str << "\n";
256 }
257
258 void Inst::dump(const Cfg *Func) const {
259 Ostream &Str = Func->getContext()->getStrDump();
260 dumpDest(Func);
261 Str << " =~ ";
262 dumpSources(Func);
263 }
264
265 void Inst::dumpSources(const Cfg *Func) const {
266 Ostream &Str = Func->getContext()->getStrDump();
267 for (SizeT I = 0; I < getSrcSize(); ++I) {
268 if (I > 0)
269 Str << ", ";
270 getSrc(I)->dump(Func);
271 }
272 }
273
274 void Inst::dumpDest(const Cfg *Func) const {
275 if (getDest())
276 getDest()->dump(Func);
277 }
278
279 void InstAlloca::dump(const Cfg *Func) const {
280 Ostream &Str = Func->getContext()->getStrDump();
281 dumpDest(Func);
282 Str << " = alloca i8, i32 ";
283 getSizeInBytes()->dump(Func);
284 Str << ", align " << getAlignInBytes();
285 }
286
287 void InstArithmetic::dump(const Cfg *Func) const {
288 Ostream &Str = Func->getContext()->getStrDump();
289 dumpDest(Func);
290 Str << " = " << InstArithmeticAttributes[getOp()].DisplayString << " "
291 << getDest()->getType() << " ";
292 dumpSources(Func);
293 }
294
295 void InstAssign::dump(const Cfg *Func) const {
296 Ostream &Str = Func->getContext()->getStrDump();
297 dumpDest(Func);
298 Str << " = " << getDest()->getType() << " ";
299 dumpSources(Func);
300 }
301
302 void InstBr::dump(const Cfg *Func) const {
303 Ostream &Str = Func->getContext()->getStrDump();
304 dumpDest(Func);
305 Str << "br ";
306 if (!isUnconditional()) {
307 Str << "i1 ";
308 getCondition()->dump(Func);
309 Str << ", label %" << getTargetTrue()->getName() << ", ";
310 }
311 Str << "label %" << getTargetFalse()->getName();
312 }
313
314 void InstCall::dump(const Cfg *Func) const {
315 Ostream &Str = Func->getContext()->getStrDump();
316 if (getDest()) {
317 dumpDest(Func);
318 Str << " = ";
319 }
320 Str << "call ";
321 if (getDest())
322 Str << getDest()->getType();
323 else
324 Str << "void";
325 Str << " ";
326 getCallTarget()->dump(Func);
327 Str << "(";
328 for (SizeT I = 0; I < getNumArgs(); ++I) {
329 if (I > 0)
330 Str << ", ";
331 Str << getArg(I)->getType() << " ";
332 getArg(I)->dump(Func);
333 }
334 Str << ")";
335 }
336
337 void InstCast::dump(const Cfg *Func) const {
338 Ostream &Str = Func->getContext()->getStrDump();
339 dumpDest(Func);
340 Str << " = " << InstCastAttributes[getCastKind()].DisplayString << " "
341 << getSrc(0)->getType() << " ";
342 dumpSources(Func);
343 Str << " to " << getDest()->getType();
344 }
345
346 void InstIcmp::dump(const Cfg *Func) const {
347 Ostream &Str = Func->getContext()->getStrDump();
348 dumpDest(Func);
349 Str << " = icmp " << InstIcmpAttributes[getCondition()].DisplayString << " "
350 << getSrc(0)->getType() << " ";
351 dumpSources(Func);
352 }
353
354 void InstFcmp::dump(const Cfg *Func) const {
355 Ostream &Str = Func->getContext()->getStrDump();
356 dumpDest(Func);
357 Str << " = fcmp " << InstFcmpAttributes[getCondition()].DisplayString << " "
358 << getSrc(0)->getType() << " ";
359 dumpSources(Func);
360 }
361
362 void InstLoad::dump(const Cfg *Func) const {
363 Ostream &Str = Func->getContext()->getStrDump();
364 dumpDest(Func);
365 Type Ty = getDest()->getType();
366 Str << " = load " << Ty << "* ";
367 dumpSources(Func);
368 Str << ", align " << typeAlignInBytes(Ty);
369 }
370
371 void InstStore::dump(const Cfg *Func) const {
372 Ostream &Str = Func->getContext()->getStrDump();
373 Type Ty = getData()->getType();
374 Str << "store " << Ty << " ";
375 getData()->dump(Func);
376 Str << ", " << Ty << "* ";
377 getAddr()->dump(Func);
378 Str << ", align " << typeAlignInBytes(Ty);
379 }
380
381 void InstSwitch::dump(const Cfg *Func) const {
382 Ostream &Str = Func->getContext()->getStrDump();
383 Type Ty = getComparison()->getType();
384 Str << "switch " << Ty << " ";
385 getSrc(0)->dump(Func);
386 Str << ", label %" << getLabelDefault()->getName() << " [\n";
387 for (SizeT I = 0; I < getNumCases(); ++I) {
388 Str << " " << Ty << " " << getValue(I) << ", label %"
389 << getLabel(I)->getName() << "\n";
390 }
391 Str << " ]";
392 }
393
394 void InstPhi::dump(const Cfg *Func) const {
395 Ostream &Str = Func->getContext()->getStrDump();
396 dumpDest(Func);
397 Str << " = phi " << getDest()->getType() << " ";
398 for (SizeT I = 0; I < getSrcSize(); ++I) {
399 if (I > 0)
400 Str << ", ";
401 Str << "[ ";
402 getSrc(I)->dump(Func);
403 Str << ", %" << Labels[I]->getName() << " ]";
404 }
405 }
406
407 void InstRet::dump(const Cfg *Func) const {
408 Ostream &Str = Func->getContext()->getStrDump();
409 Type Ty = hasRetValue() ? getSrc(0)->getType() : IceType_void;
410 Str << "ret " << Ty;
411 if (hasRetValue()) {
412 Str << " ";
413 dumpSources(Func);
414 }
415 }
416
417 void InstSelect::dump(const Cfg *Func) const {
418 Ostream &Str = Func->getContext()->getStrDump();
419 dumpDest(Func);
420 Operand *Condition = getCondition();
421 Operand *TrueOp = getTrueOperand();
422 Operand *FalseOp = getFalseOperand();
423 Str << " = select " << Condition->getType() << " ";
424 Condition->dump(Func);
425 Str << ", " << TrueOp->getType() << " ";
426 TrueOp->dump(Func);
427 Str << ", " << FalseOp->getType() << " ";
428 FalseOp->dump(Func);
429 }
430
431 void InstUnreachable::dump(const Cfg *Func) const {
432 Ostream &Str = Func->getContext()->getStrDump();
433 Str << "unreachable";
434 }
435
436 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInst.h ('k') | src/IceInst.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698