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

Side by Side Diff: src/IceInst.h

Issue 205613002: Initial skeleton of Subzero. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Address Mark's layout/style comments 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.h - High-level instructions ----------*- C++ -*-===//
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 declares the IceInst class and its target-independent
11 // subclasses, which represent the high-level Vanilla ICE instructions
12 // and map roughly 1:1 to LLVM instructions.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef SUBZERO_ICEINST_H
17 #define SUBZERO_ICEINST_H
18
19 #include "IceDefs.h"
20 #include "IceTypes.h"
21
22 class IceInst {
23 public:
24 enum InstKind {
25 Alloca,
26 Arithmetic,
27 Assign, // not part of LLVM/PNaCl bitcode
28 Br,
29 Call,
30 Cast,
31 Fcmp,
32 Icmp,
33 Load,
34 Phi,
35 Ret,
36 Select,
37 Store,
38 Switch,
39 };
40 InstKind getKind() const { return Kind; }
41
42 int32_t getNumber() const { return Number; }
43
44 bool isDeleted() const { return Deleted; }
45 void setDeleted() { Deleted = true; }
46
47 bool hasSideEffects() const { return HasSideEffects; }
48
49 IceVariable *getDest() const { return Dest; }
50
51 uint32_t getSrcSize() const { return NumSrcs; }
52 IceOperand *getSrc(uint32_t I) const {
53 assert(I < getSrcSize());
54 return Srcs[I];
55 }
56
57 // Returns a list of out-edges corresponding to a terminator
58 // instruction, which is the last instruction of the block.
59 virtual IceNodeList getTerminatorEdges() const {
60 assert(0);
61 return IceNodeList();
62 }
63
64 // Updates the status of the IceVariables contained within the
65 // instruction. In particular, it marks where the Dest variable is
66 // first assigned, and it tracks whether variables are live across
67 // basic blocks, i.e. used in a different block from their definition.
68 void updateVars(IceCfgNode *Node);
69
70 virtual void dump(IceOstream &Str) const;
71 void dumpSources(IceOstream &Str) const;
72 void dumpDest(IceOstream &Str) const;
73
74 virtual ~IceInst() {}
75
76 protected:
77 IceInst(IceCfg *Cfg, InstKind Kind, uint32_t MaxSrcs, IceVariable *Dest);
78 void addSource(IceOperand *Src) {
79 assert(Src);
80 assert(NumSrcs < MaxSrcs);
81 Srcs[NumSrcs++] = Src;
82 }
83
84 const InstKind Kind;
85 // Number is the instruction number for describing live ranges.
86 int32_t Number;
87 // Deleted means irrevocably deleted.
88 bool Deleted;
89 // HasSideEffects means the instruction is something like a function
90 // call or a volatile load that can't be removed even if its Dest
91 // variable is not live.
92 bool HasSideEffects;
93
94 IceVariable *Dest;
95 const uint32_t MaxSrcs; // only used for assert
96 uint32_t NumSrcs;
97 IceOperand **Srcs;
98 };
99
100 IceOstream &operator<<(IceOstream &Str, const IceInst *I);
101
102 // Alloca instruction. This captures the size in bytes as getSrc(0),
103 // and the alignment.
104 class IceInstAlloca : public IceInst {
105 public:
106 static IceInstAlloca *create(IceCfg *Cfg, IceOperand *ByteCount,
107 uint32_t Align, IceVariable *Dest) {
108 return new (Cfg->allocateInst<IceInstAlloca>())
109 IceInstAlloca(Cfg, ByteCount, Align, Dest);
110 }
111 uint32_t getAlign() const { return Align; }
112 virtual void dump(IceOstream &Str) const;
113 static bool classof(const IceInst *Inst) { return Inst->getKind() == Alloca; }
114
115 protected:
116 private:
117 IceInstAlloca(IceCfg *Cfg, IceOperand *ByteCount, uint32_t Align,
118 IceVariable *Dest);
119 const uint32_t Align;
120 };
121
122 // Binary arithmetic instruction. The source operands are captured in
123 // getSrc(0) and getSrc(1).
124 class IceInstArithmetic : public IceInst {
125 public:
126 enum OpKind {
127 // Ordered by http://llvm.org/docs/LangRef.html#binary-operations
128 Add,
129 Fadd,
130 Sub,
131 Fsub,
132 Mul,
133 Fmul,
134 Udiv,
135 Sdiv,
136 Fdiv,
137 Urem,
138 Srem,
139 Frem,
140 // Ordered by http://llvm.org/docs/LangRef.html#bitwise-binary-operations
141 Shl,
142 Lshr,
143 Ashr,
144 And,
145 Or,
146 Xor
147 };
148 static IceInstArithmetic *create(IceCfg *Cfg, OpKind Op, IceVariable *Dest,
149 IceOperand *Source1, IceOperand *Source2) {
150 return new (Cfg->allocateInst<IceInstArithmetic>())
151 IceInstArithmetic(Cfg, Op, Dest, Source1, Source2);
152 }
153 OpKind getOp() const { return Op; }
154 bool isCommutative() const;
155 virtual void dump(IceOstream &Str) const;
156 static bool classof(const IceInst *Inst) {
157 return Inst->getKind() == Arithmetic;
158 }
159
160 private:
161 IceInstArithmetic(IceCfg *Cfg, OpKind Op, IceVariable *Dest,
162 IceOperand *Source1, IceOperand *Source2);
163
164 const OpKind Op;
165 };
166
167 // Assignment instruction. The source operand is captured in
168 // getSrc(0). This is not part of the LLVM bitcode, but is a useful
169 // abstraction for some of the lowering. E.g., if Phi instruction
170 // lowering happens before target lowering, or for representing an
171 // Inttoptr instruction, or as an intermediate step for lowering a
172 // Load instruction.
173 class IceInstAssign : public IceInst {
174 public:
175 static IceInstAssign *create(IceCfg *Cfg, IceVariable *Dest,
176 IceOperand *Source) {
177 return new (Cfg->allocateInst<IceInstAssign>())
178 IceInstAssign(Cfg, Dest, Source);
179 }
180 virtual void dump(IceOstream &Str) const;
181 static bool classof(const IceInst *Inst) { return Inst->getKind() == Assign; }
182
183 private:
184 IceInstAssign(IceCfg *Cfg, IceVariable *Dest, IceOperand *Source);
185 };
186
187 // Branch instruction. This represents both conditional and
188 // unconditional branches.
189 class IceInstBr : public IceInst {
190 public:
191 static IceInstBr *create(IceCfg *Cfg, IceOperand *Source,
192 IceCfgNode *TargetTrue, IceCfgNode *TargetFalse) {
193 return new (Cfg->allocateInst<IceInstBr>())
194 IceInstBr(Cfg, Source, TargetTrue, TargetFalse);
195 }
196 static IceInstBr *create(IceCfg *Cfg, IceCfgNode *Target) {
197 return new (Cfg->allocateInst<IceInstBr>()) IceInstBr(Cfg, Target);
198 }
199 bool isUnconditional() const { return getTargetTrue() == NULL; }
200 IceCfgNode *getTargetTrue() const { return TargetTrue; }
201 IceCfgNode *getTargetFalse() const { return TargetFalse; }
202 IceCfgNode *getTargetUnconditional() const {
203 assert(isUnconditional());
204 return getTargetFalse();
205 }
206 virtual IceNodeList getTerminatorEdges() const;
207 virtual void dump(IceOstream &Str) const;
208 static bool classof(const IceInst *Inst) { return Inst->getKind() == Br; }
209
210 private:
211 // Conditional branch
212 IceInstBr(IceCfg *Cfg, IceOperand *Source, IceCfgNode *TargetTrue,
213 IceCfgNode *TargetFalse);
214 // Unconditional branch
215 IceInstBr(IceCfg *Cfg, IceCfgNode *Target);
216
217 IceCfgNode *const TargetFalse; // Doubles as unconditional branch target
218 IceCfgNode *const TargetTrue; // NULL if unconditional branch
219 };
220
221 // Call instruction. The call target is captured as getSrc(0), and
222 // arg I is captured as getSrc(I+1).
223 class IceInstCall : public IceInst {
224 public:
225 static IceInstCall *create(IceCfg *Cfg, uint32_t NumArgs, IceVariable *Dest,
226 IceOperand *CallTarget, bool Tail) {
227 return new (Cfg->allocateInst<IceInstCall>())
228 IceInstCall(Cfg, NumArgs, Dest, CallTarget, Tail);
229 }
230 void addArg(IceOperand *Arg) { addSource(Arg); }
231 IceOperand *getCallTarget() const { return getSrc(0); }
232 IceOperand *getArg(uint32_t I) const { return getSrc(I + 1); }
233 uint32_t getNumArgs() const { return getSrcSize() - 1; }
234 bool isTail() const { return Tail; }
235 virtual void dump(IceOstream &Str) const;
236 static bool classof(const IceInst *Inst) { return Inst->getKind() == Call; }
237
238 private:
239 IceInstCall(IceCfg *Cfg, uint32_t NumArgs, IceVariable *Dest,
240 IceOperand *CallTarget, bool Tail)
241 : IceInst(Cfg, IceInst::Call, NumArgs + 1, Dest), Tail(Tail) {
242 // Set HasSideEffects so that the call instruction can't be
243 // dead-code eliminated. Don't set this for a deletable intrinsic
244 // call.
245 HasSideEffects = true;
246 addSource(CallTarget);
247 }
248 const bool Tail;
249 };
250
251 // Cast instruction (a.k.a. conversion operation).
252 class IceInstCast : public IceInst {
253 public:
254 enum OpKind {
255 // Ordered by http://llvm.org/docs/LangRef.html#conversion-operations
256 Trunc,
257 Zext,
258 Sext,
259 Fptrunc,
260 Fpext,
261 Fptoui,
262 Fptosi,
263 Uitofp,
264 Sitofp,
265 };
266 static IceInstCast *create(IceCfg *Cfg, OpKind CastKind, IceVariable *Dest,
267 IceOperand *Source) {
268 return new (Cfg->allocateInst<IceInstCast>())
269 IceInstCast(Cfg, CastKind, Dest, Source);
270 }
271 OpKind getCastKind() const { return CastKind; }
272 virtual void dump(IceOstream &Str) const;
273 static bool classof(const IceInst *Inst) { return Inst->getKind() == Cast; }
274
275 private:
276 IceInstCast(IceCfg *Cfg, OpKind CastKind, IceVariable *Dest,
277 IceOperand *Source);
278 OpKind CastKind;
279 };
280
281 // Floating-point comparison instruction. The source operands are
282 // captured in getSrc(0) and getSrc(1).
283 class IceInstFcmp : public IceInst {
284 public:
285 enum FCond {
286 // Ordered by http://llvm.org/docs/LangRef.html#id254
287 False,
288 Oeq,
289 Ogt,
290 Oge,
291 Olt,
292 Ole,
293 One,
294 Ord,
295 Ueq,
296 Ugt,
297 Uge,
298 Ult,
299 Ule,
300 Une,
301 Uno,
302 True
303 };
304 static IceInstFcmp *create(IceCfg *Cfg, FCond Condition, IceVariable *Dest,
305 IceOperand *Source1, IceOperand *Source2) {
306 return new (Cfg->allocateInst<IceInstFcmp>())
307 IceInstFcmp(Cfg, Condition, Dest, Source1, Source2);
308 }
309 FCond getCondition() const { return Condition; }
310 virtual void dump(IceOstream &Str) const;
311 static bool classof(const IceInst *Inst) { return Inst->getKind() == Fcmp; }
312
313 private:
314 IceInstFcmp(IceCfg *Cfg, FCond Condition, IceVariable *Dest,
315 IceOperand *Source1, IceOperand *Source2);
316 FCond Condition;
317 };
318
319 // Integer comparison instruction. The source operands are captured
320 // in getSrc(0) and getSrc(1).
321 class IceInstIcmp : public IceInst {
322 public:
323 enum ICond {
324 // Ordered by http://llvm.org/docs/LangRef.html#id249
325 Eq,
326 Ne,
327 Ugt,
328 Uge,
329 Ult,
330 Ule,
331 Sgt,
332 Sge,
333 Slt,
334 Sle
335 };
336 static IceInstIcmp *create(IceCfg *Cfg, ICond Condition, IceVariable *Dest,
337 IceOperand *Source1, IceOperand *Source2) {
338 return new (Cfg->allocateInst<IceInstIcmp>())
339 IceInstIcmp(Cfg, Condition, Dest, Source1, Source2);
340 }
341 ICond getCondition() const { return Condition; }
342 virtual void dump(IceOstream &Str) const;
343 static bool classof(const IceInst *Inst) { return Inst->getKind() == Icmp; }
344
345 private:
346 IceInstIcmp(IceCfg *Cfg, ICond Condition, IceVariable *Dest,
347 IceOperand *Source1, IceOperand *Source2);
348 ICond Condition;
349 };
350
351 // Load instruction. The source address is captured in getSrc(0);
352 class IceInstLoad : public IceInst {
353 public:
354 static IceInstLoad *create(IceCfg *Cfg, IceVariable *Dest,
355 IceOperand *SourceAddr) {
356 return new (Cfg->allocateInst<IceInstLoad>())
357 IceInstLoad(Cfg, Dest, SourceAddr);
358 }
359 virtual void dump(IceOstream &Str) const;
360 static bool classof(const IceInst *Inst) { return Inst->getKind() == Load; }
361
362 private:
363 IceInstLoad(IceCfg *Cfg, IceVariable *Dest, IceOperand *SourceAddr);
364 };
365
366 // Phi instruction. For incoming edge I, the node is Labels[I] and
367 // the Phi source operand is getSrc(I).
368 class IceInstPhi : public IceInst {
369 public:
370 static IceInstPhi *create(IceCfg *Cfg, uint32_t MaxSrcs, IceVariable *Dest) {
371 return new (Cfg->allocateInst<IceInstPhi>()) IceInstPhi(Cfg, MaxSrcs, Dest);
372 }
373 void addArgument(IceOperand *Source, IceCfgNode *Label);
374 virtual void dump(IceOstream &Str) const;
375 static bool classof(const IceInst *Inst) { return Inst->getKind() == Phi; }
376
377 private:
378 IceInstPhi(IceCfg *Cfg, uint32_t MaxSrcs, IceVariable *Dest);
379 // Labels[] duplicates the InEdges[] information in the enclosing
380 // IceCfgNode, but the Phi instruction is created before InEdges[]
381 // is available, so it's more complicated to share the list.
382 IceCfgNode **Labels;
383 };
384
385 // Ret instruction. The return value is captured in getSrc(0), but if
386 // there is no return value (void-type function), then
387 // getSrcSize()==0.
388 class IceInstRet : public IceInst {
389 public:
390 static IceInstRet *create(IceCfg *Cfg, IceOperand *Source = NULL) {
391 return new (Cfg->allocateInst<IceInstRet>()) IceInstRet(Cfg, Source);
392 }
393 virtual IceNodeList getTerminatorEdges() const { return IceNodeList(); }
394 virtual void dump(IceOstream &Str) const;
395 static bool classof(const IceInst *Inst) { return Inst->getKind() == Ret; }
396
397 private:
398 IceInstRet(IceCfg *Cfg, IceOperand *Source);
399 };
400
401 // Select instruction. The condition, true, and false operands are captured.
402 class IceInstSelect : public IceInst {
403 public:
404 static IceInstSelect *create(IceCfg *Cfg, IceVariable *Dest,
405 IceOperand *Condition, IceOperand *SourceTrue,
406 IceOperand *SourceFalse) {
407 return new (Cfg->allocateInst<IceInstSelect>())
408 IceInstSelect(Cfg, Dest, Condition, SourceTrue, SourceFalse);
409 }
410 IceOperand *getCondition() const { return getSrc(0); }
411 IceOperand *getTrueOperand() const { return getSrc(1); }
412 IceOperand *getFalseOperand() const { return getSrc(2); }
413 virtual void dump(IceOstream &Str) const;
414 static bool classof(const IceInst *Inst) { return Inst->getKind() == Select; }
415
416 private:
417 IceInstSelect(IceCfg *Cfg, IceVariable *Dest, IceOperand *Condition,
418 IceOperand *Source1, IceOperand *Source2);
419 };
420
421 // Store instruction. The address operand is captured, along with the
422 // data operand to be stored into the address.
423 class IceInstStore : public IceInst {
424 public:
425 static IceInstStore *create(IceCfg *Cfg, IceOperand *Data, IceOperand *Addr) {
426 return new (Cfg->allocateInst<IceInstStore>())
427 IceInstStore(Cfg, Data, Addr);
428 }
429 IceOperand *getAddr() const { return getSrc(1); }
430 IceOperand *getData() const { return getSrc(0); }
431 virtual void dump(IceOstream &Str) const;
432 static bool classof(const IceInst *Inst) { return Inst->getKind() == Store; }
433
434 private:
435 IceInstStore(IceCfg *Cfg, IceOperand *Data, IceOperand *Addr);
436 };
437
438 // Switch instruction. The single source operand is captured as
439 // getSrc(0).
440 class IceInstSwitch : public IceInst {
441 public:
442 static IceInstSwitch *create(IceCfg *Cfg, uint32_t NumCases,
443 IceOperand *Source, IceCfgNode *LabelDefault) {
444 return new (Cfg->allocateInst<IceInstSwitch>())
445 IceInstSwitch(Cfg, NumCases, Source, LabelDefault);
446 }
447 IceCfgNode *getLabelDefault() const { return LabelDefault; }
448 uint32_t getNumCases() const { return NumCases; }
449 uint64_t getValue(uint32_t I) const {
450 assert(I < NumCases);
451 return Values[I];
452 }
453 IceCfgNode *getLabel(uint32_t I) const {
454 assert(I < NumCases);
455 return Labels[I];
456 }
457 void addBranch(uint32_t CaseIndex, uint64_t Value, IceCfgNode *Label);
458 virtual IceNodeList getTerminatorEdges() const;
459 virtual void dump(IceOstream &Str) const;
460 static bool classof(const IceInst *Inst) { return Inst->getKind() == Switch; }
461
462 private:
463 IceInstSwitch(IceCfg *Cfg, uint32_t NumCases, IceOperand *Source,
464 IceCfgNode *LabelDefault);
465 IceCfgNode *LabelDefault;
466 uint32_t NumCases; // not including the default case
467 uint64_t *Values; // size is NumCases
468 IceCfgNode **Labels; // size is NumCases
469 };
470
471 #endif // SUBZERO_ICEINST_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698