OLD | NEW |
---|---|
1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// | 1 //===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the Inst class and its target-independent | 10 // This file declares the Inst class and its target-independent |
(...skipping 29 matching lines...) Expand all Loading... | |
40 Br, | 40 Br, |
41 Call, | 41 Call, |
42 Cast, | 42 Cast, |
43 Fcmp, | 43 Fcmp, |
44 Icmp, | 44 Icmp, |
45 Load, | 45 Load, |
46 Phi, | 46 Phi, |
47 Ret, | 47 Ret, |
48 Select, | 48 Select, |
49 Store, | 49 Store, |
50 Switch | 50 Switch, |
51 FakeDef, // not part of LLVM/PNaCl bitcode | |
52 FakeUse, // not part of LLVM/PNaCl bitcode | |
53 FakeKill, // not part of LLVM/PNaCl bitcode | |
54 Target // target-specific low-level ICE | |
55 // Anything >= Target is an InstTarget subclass. | |
51 }; | 56 }; |
52 InstKind getKind() const { return Kind; } | 57 InstKind getKind() const { return Kind; } |
53 | 58 |
54 int32_t getNumber() const { return Number; } | 59 int32_t getNumber() const { return Number; } |
55 | 60 |
56 bool isDeleted() const { return Deleted; } | 61 bool isDeleted() const { return Deleted; } |
57 void setDeleted() { Deleted = true; } | 62 void setDeleted() { Deleted = true; } |
58 | 63 |
59 bool hasSideEffects() const { return HasSideEffects; } | 64 bool hasSideEffects() const { return HasSideEffects; } |
60 | 65 |
(...skipping 15 matching lines...) Expand all Loading... | |
76 "getTerminatorEdges() called on a non-terminator instruction"); | 81 "getTerminatorEdges() called on a non-terminator instruction"); |
77 return NodeList(); | 82 return NodeList(); |
78 } | 83 } |
79 | 84 |
80 // Updates the status of the Variables contained within the | 85 // Updates the status of the Variables contained within the |
81 // instruction. In particular, it marks where the Dest variable is | 86 // instruction. In particular, it marks where the Dest variable is |
82 // first assigned, and it tracks whether variables are live across | 87 // first assigned, and it tracks whether variables are live across |
83 // basic blocks, i.e. used in a different block from their definition. | 88 // basic blocks, i.e. used in a different block from their definition. |
84 void updateVars(CfgNode *Node); | 89 void updateVars(CfgNode *Node); |
85 | 90 |
91 virtual void emit(const Cfg *Func) const; | |
86 virtual void dump(const Cfg *Func) const; | 92 virtual void dump(const Cfg *Func) const; |
87 void dumpDecorated(const Cfg *Func) const; | 93 void dumpDecorated(const Cfg *Func) const; |
94 void emitSources(const Cfg *Func) const; | |
88 void dumpSources(const Cfg *Func) const; | 95 void dumpSources(const Cfg *Func) const; |
89 void dumpDest(const Cfg *Func) const; | 96 void dumpDest(const Cfg *Func) const; |
97 virtual bool isRedundantAssign() const { return false; } | |
90 | 98 |
91 virtual ~Inst() {} | 99 virtual ~Inst() {} |
92 | 100 |
93 protected: | 101 protected: |
94 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest); | 102 Inst(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest); |
95 void addSource(Operand *Src) { | 103 void addSource(Operand *Src) { |
96 assert(Src); | 104 assert(Src); |
97 assert(NumSrcs < MaxSrcs); | 105 assert(NumSrcs < MaxSrcs); |
98 Srcs[NumSrcs++] = Src; | 106 Srcs[NumSrcs++] = Src; |
99 } | 107 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 | 155 |
148 // Binary arithmetic instruction. The source operands are captured in | 156 // Binary arithmetic instruction. The source operands are captured in |
149 // getSrc(0) and getSrc(1). | 157 // getSrc(0) and getSrc(1). |
150 class InstArithmetic : public Inst { | 158 class InstArithmetic : public Inst { |
151 public: | 159 public: |
152 enum OpKind { | 160 enum OpKind { |
153 #define X(tag, str, commutative) tag, | 161 #define X(tag, str, commutative) tag, |
154 ICEINSTARITHMETIC_TABLE | 162 ICEINSTARITHMETIC_TABLE |
155 #undef X | 163 #undef X |
156 }; | 164 }; |
165 | |
157 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest, | 166 static InstArithmetic *create(Cfg *Func, OpKind Op, Variable *Dest, |
158 Operand *Source1, Operand *Source2) { | 167 Operand *Source1, Operand *Source2) { |
159 return new (Func->allocateInst<InstArithmetic>()) | 168 return new (Func->allocateInst<InstArithmetic>()) |
160 InstArithmetic(Func, Op, Dest, Source1, Source2); | 169 InstArithmetic(Func, Op, Dest, Source1, Source2); |
161 } | 170 } |
162 OpKind getOp() const { return Op; } | 171 OpKind getOp() const { return Op; } |
163 bool isCommutative() const; | 172 bool isCommutative() const; |
164 virtual void dump(const Cfg *Func) const; | 173 virtual void dump(const Cfg *Func) const; |
165 static bool classof(const Inst *Inst) { | 174 static bool classof(const Inst *Inst) { |
166 return Inst->getKind() == Arithmetic; | 175 return Inst->getKind() == Arithmetic; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
272 }; | 281 }; |
273 | 282 |
274 // Cast instruction (a.k.a. conversion operation). | 283 // Cast instruction (a.k.a. conversion operation). |
275 class InstCast : public Inst { | 284 class InstCast : public Inst { |
276 public: | 285 public: |
277 enum OpKind { | 286 enum OpKind { |
278 #define X(tag, str) tag, | 287 #define X(tag, str) tag, |
279 ICEINSTCAST_TABLE | 288 ICEINSTCAST_TABLE |
280 #undef X | 289 #undef X |
281 }; | 290 }; |
291 | |
282 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, | 292 static InstCast *create(Cfg *Func, OpKind CastKind, Variable *Dest, |
283 Operand *Source) { | 293 Operand *Source) { |
284 return new (Func->allocateInst<InstCast>()) | 294 return new (Func->allocateInst<InstCast>()) |
285 InstCast(Func, CastKind, Dest, Source); | 295 InstCast(Func, CastKind, Dest, Source); |
286 } | 296 } |
287 OpKind getCastKind() const { return CastKind; } | 297 OpKind getCastKind() const { return CastKind; } |
288 virtual void dump(const Cfg *Func) const; | 298 virtual void dump(const Cfg *Func) const; |
289 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } | 299 static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; } |
290 | 300 |
291 private: | 301 private: |
292 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); | 302 InstCast(Cfg *Func, OpKind CastKind, Variable *Dest, Operand *Source); |
293 InstCast(const InstCast &) LLVM_DELETED_FUNCTION; | 303 InstCast(const InstCast &) LLVM_DELETED_FUNCTION; |
294 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION; | 304 InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION; |
295 virtual ~InstCast() {} | 305 virtual ~InstCast() {} |
296 const OpKind CastKind; | 306 const OpKind CastKind; |
297 }; | 307 }; |
298 | 308 |
299 // Floating-point comparison instruction. The source operands are | 309 // Floating-point comparison instruction. The source operands are |
300 // captured in getSrc(0) and getSrc(1). | 310 // captured in getSrc(0) and getSrc(1). |
301 class InstFcmp : public Inst { | 311 class InstFcmp : public Inst { |
302 public: | 312 public: |
303 enum FCond { | 313 enum FCond { |
304 #define X(tag, str) tag, | 314 #define X(tag, str) tag, |
305 ICEINSTFCMP_TABLE | 315 ICEINSTFCMP_TABLE |
306 #undef X | 316 #undef X |
307 }; | 317 }; |
318 | |
308 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, | 319 static InstFcmp *create(Cfg *Func, FCond Condition, Variable *Dest, |
309 Operand *Source1, Operand *Source2) { | 320 Operand *Source1, Operand *Source2) { |
310 return new (Func->allocateInst<InstFcmp>()) | 321 return new (Func->allocateInst<InstFcmp>()) |
311 InstFcmp(Func, Condition, Dest, Source1, Source2); | 322 InstFcmp(Func, Condition, Dest, Source1, Source2); |
312 } | 323 } |
313 FCond getCondition() const { return Condition; } | 324 FCond getCondition() const { return Condition; } |
314 virtual void dump(const Cfg *Func) const; | 325 virtual void dump(const Cfg *Func) const; |
315 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } | 326 static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; } |
316 | 327 |
317 private: | 328 private: |
318 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, | 329 InstFcmp(Cfg *Func, FCond Condition, Variable *Dest, Operand *Source1, |
319 Operand *Source2); | 330 Operand *Source2); |
320 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION; | 331 InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION; |
321 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION; | 332 InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION; |
322 virtual ~InstFcmp() {} | 333 virtual ~InstFcmp() {} |
323 const FCond Condition; | 334 const FCond Condition; |
324 }; | 335 }; |
325 | 336 |
326 // Integer comparison instruction. The source operands are captured | 337 // Integer comparison instruction. The source operands are captured |
327 // in getSrc(0) and getSrc(1). | 338 // in getSrc(0) and getSrc(1). |
328 class InstIcmp : public Inst { | 339 class InstIcmp : public Inst { |
329 public: | 340 public: |
330 enum ICond { | 341 enum ICond { |
331 #define X(tag, str) tag, | 342 #define X(tag, str) tag, |
332 ICEINSTICMP_TABLE | 343 ICEINSTICMP_TABLE |
333 #undef X | 344 #undef X |
345 None // not part of LLVM; used for unconditional branch | |
JF
2014/05/04 23:54:58
Isn't that True?
Jim Stichnoth
2014/05/05 07:03:55
Weird, I don't know why this was there. :) It's g
| |
334 }; | 346 }; |
347 | |
335 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, | 348 static InstIcmp *create(Cfg *Func, ICond Condition, Variable *Dest, |
336 Operand *Source1, Operand *Source2) { | 349 Operand *Source1, Operand *Source2) { |
337 return new (Func->allocateInst<InstIcmp>()) | 350 return new (Func->allocateInst<InstIcmp>()) |
338 InstIcmp(Func, Condition, Dest, Source1, Source2); | 351 InstIcmp(Func, Condition, Dest, Source1, Source2); |
339 } | 352 } |
340 ICond getCondition() const { return Condition; } | 353 ICond getCondition() const { return Condition; } |
341 virtual void dump(const Cfg *Func) const; | 354 virtual void dump(const Cfg *Func) const; |
342 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } | 355 static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; } |
343 | 356 |
344 private: | 357 private: |
(...skipping 24 matching lines...) Expand all Loading... | |
369 }; | 382 }; |
370 | 383 |
371 // Phi instruction. For incoming edge I, the node is Labels[I] and | 384 // Phi instruction. For incoming edge I, the node is Labels[I] and |
372 // the Phi source operand is getSrc(I). | 385 // the Phi source operand is getSrc(I). |
373 class InstPhi : public Inst { | 386 class InstPhi : public Inst { |
374 public: | 387 public: |
375 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { | 388 static InstPhi *create(Cfg *Func, SizeT MaxSrcs, Variable *Dest) { |
376 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); | 389 return new (Func->allocateInst<InstPhi>()) InstPhi(Func, MaxSrcs, Dest); |
377 } | 390 } |
378 void addArgument(Operand *Source, CfgNode *Label); | 391 void addArgument(Operand *Source, CfgNode *Label); |
392 Operand *getOperandForTarget(CfgNode *Target) const; | |
393 Inst *lower(Cfg *Func, CfgNode *Node); | |
379 virtual void dump(const Cfg *Func) const; | 394 virtual void dump(const Cfg *Func) const; |
380 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } | 395 static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; } |
381 | 396 |
382 private: | 397 private: |
383 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); | 398 InstPhi(Cfg *Func, SizeT MaxSrcs, Variable *Dest); |
384 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION; | 399 InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION; |
385 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION; | 400 InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION; |
386 virtual void destroy(Cfg *Func) { | 401 virtual void destroy(Cfg *Func) { |
387 Func->deallocateArrayOf<CfgNode *>(Labels); | 402 Func->deallocateArrayOf<CfgNode *>(Labels); |
388 Inst::destroy(Func); | 403 Inst::destroy(Func); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 return Inst->getKind() == Unreachable; | 530 return Inst->getKind() == Unreachable; |
516 } | 531 } |
517 | 532 |
518 private: | 533 private: |
519 InstUnreachable(Cfg *Func); | 534 InstUnreachable(Cfg *Func); |
520 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION; | 535 InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION; |
521 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION; | 536 InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION; |
522 virtual ~InstUnreachable() {} | 537 virtual ~InstUnreachable() {} |
523 }; | 538 }; |
524 | 539 |
540 // FakeDef instruction. This creates a fake definition of a variable, | |
541 // which is how we represent the case when an instruction produces | |
542 // multiple results. This doesn't happen with high-level ICE | |
543 // instructions, but might with lowered instructions. For example, | |
544 // this would be a way to represent condition flags being modified by | |
545 // an instruction. | |
546 // | |
547 // It's generally useful to set the optional source operand to be the | |
548 // dest variable of the instruction that actually produces the FakeDef | |
549 // dest. Otherwise, the original instruction could be dead-code | |
550 // eliminated if its dest operand is unused, and therefore the FakeDef | |
551 // dest wouldn't be properly initialized. | |
552 class InstFakeDef : public Inst { | |
553 public: | |
554 static InstFakeDef *create(Cfg *Func, Variable *Dest, Variable *Src = NULL) { | |
555 return new (Func->allocateInst<InstFakeDef>()) InstFakeDef(Func, Dest, Src); | |
556 } | |
557 virtual void emit(const Cfg *Func) const; | |
558 virtual void dump(const Cfg *Func) const; | |
559 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeDef; } | |
560 | |
561 private: | |
562 InstFakeDef(Cfg *Func, Variable *Dest, Variable *Src); | |
563 InstFakeDef(const InstFakeDef &) LLVM_DELETED_FUNCTION; | |
564 InstFakeDef &operator=(const InstFakeDef &) LLVM_DELETED_FUNCTION; | |
565 virtual ~InstFakeDef() {} | |
566 }; | |
567 | |
568 // FakeUse instruction. This creates a fake use of a variable, to | |
569 // keep the instruction that produces that variable from being | |
570 // dead-code eliminated. This is useful in a variety of lowering | |
571 // situations. The FakeUse instruction has no dest, so it can itself | |
572 // never be dead-code eliminated. | |
573 class InstFakeUse : public Inst { | |
574 public: | |
575 static InstFakeUse *create(Cfg *Func, Variable *Src) { | |
576 return new (Func->allocateInst<InstFakeUse>()) InstFakeUse(Func, Src); | |
577 } | |
578 virtual void emit(const Cfg *Func) const; | |
579 virtual void dump(const Cfg *Func) const; | |
580 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeUse; } | |
581 | |
582 private: | |
583 InstFakeUse(Cfg *Func, Variable *Src); | |
584 InstFakeUse(const InstFakeUse &) LLVM_DELETED_FUNCTION; | |
585 InstFakeUse &operator=(const InstFakeUse &) LLVM_DELETED_FUNCTION; | |
586 virtual ~InstFakeUse() {} | |
587 }; | |
588 | |
589 // FakeKill instruction. This "kills" a set of variables by adding a | |
590 // trivial live range at this instruction to each variable. The | |
591 // primary use is to indicate that scratch registers are killed after | |
592 // a call, so that the register allocator won't assign a scratch | |
593 // register to a variable whose live range spans a call. | |
594 // | |
595 // The FakeKill instruction also holds a pointer to the instruction | |
596 // that kills the set of variables, so that if that linked instruction | |
597 // gets dead-code eliminated, the FakeKill instruction will as well. | |
598 class InstFakeKill : public Inst { | |
599 public: | |
600 static InstFakeKill *create(Cfg *Func, const VarList &KilledRegs, | |
601 const Inst *Linked) { | |
602 return new (Func->allocateInst<InstFakeKill>()) | |
603 InstFakeKill(Func, KilledRegs, Linked); | |
604 } | |
605 const Inst *getLinked() const { return Linked; } | |
606 virtual void emit(const Cfg *Func) const; | |
607 virtual void dump(const Cfg *Func) const; | |
608 static bool classof(const Inst *Inst) { return Inst->getKind() == FakeKill; } | |
609 | |
610 private: | |
611 InstFakeKill(Cfg *Func, const VarList &KilledRegs, const Inst *Linked); | |
612 InstFakeKill(const InstFakeKill &) LLVM_DELETED_FUNCTION; | |
613 InstFakeKill &operator=(const InstFakeKill &) LLVM_DELETED_FUNCTION; | |
614 virtual ~InstFakeKill() {} | |
615 | |
616 // This instruction is ignored if Linked->isDeleted() is true. | |
617 const Inst *Linked; | |
618 }; | |
619 | |
620 // The Target instruction is the base class for all target-specific | |
621 // instructions. | |
622 class InstTarget : public Inst { | |
623 public: | |
624 virtual void emit(const Cfg *Func) const = 0; | |
625 virtual void dump(const Cfg *Func) const; | |
626 static bool classof(const Inst *Inst) { return Inst->getKind() >= Target; } | |
627 | |
628 protected: | |
629 InstTarget(Cfg *Func, InstKind Kind, SizeT MaxSrcs, Variable *Dest) | |
630 : Inst(Func, Kind, MaxSrcs, Dest) { | |
631 assert(Kind >= Target); | |
632 } | |
633 InstTarget(const InstTarget &) LLVM_DELETED_FUNCTION; | |
634 InstTarget &operator=(const InstTarget &) LLVM_DELETED_FUNCTION; | |
635 virtual ~InstTarget() {} | |
636 }; | |
637 | |
525 } // end of namespace Ice | 638 } // end of namespace Ice |
526 | 639 |
527 #endif // SUBZERO_SRC_ICEINST_H | 640 #endif // SUBZERO_SRC_ICEINST_H |
OLD | NEW |