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

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

Powered by Google App Engine
This is Rietveld 408576698