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

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

Powered by Google App Engine
This is Rietveld 408576698