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

Unified 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: Fix omissions from previous patchset. Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: src/IceInst.h
diff --git a/src/IceInst.h b/src/IceInst.h
new file mode 100644
index 0000000000000000000000000000000000000000..d80e247727eb1698f1d0325cbb194627e29b6b21
--- /dev/null
+++ b/src/IceInst.h
@@ -0,0 +1,550 @@
+//===- subzero/src/IceInst.h - High-level instructions ----------*- C++ -*-===//
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Inst class and its target-independent
+// subclasses, which represent the high-level Vanilla ICE instructions
+// and map roughly 1:1 to LLVM instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEINST_H
+#define SUBZERO_SRC_ICEINST_H
+
+#include "IceDefs.h"
+#include "IceTypes.h"
+
+namespace Ice {
+
+class Inst {
+public:
+ enum InstKind {
+ // Arbitrary (alphabetical) order, except put Unreachable first.
+ Unreachable,
+ Alloca,
+ Arithmetic,
+ Assign, // not part of LLVM/PNaCl bitcode
+ Br,
+ Call,
+ Cast,
+ Fcmp,
+ Icmp,
+ Load,
+ Phi,
+ Ret,
+ Select,
+ Store,
+ Switch
+ };
+ InstKind getKind() const { return Kind; }
+
+ int32_t getNumber() const { return Number; }
+
+ bool isDeleted() const { return Deleted; }
+ void setDeleted() { Deleted = true; }
+
+ bool hasSideEffects() const { return HasSideEffects; }
+
+ Variable *getDest() const { return Dest; }
+
+ IceSize_t getSrcSize() const { return NumSrcs; }
+ Operand *getSrc(IceSize_t I) const {
+ assert(I < getSrcSize());
+ return Srcs[I];
+ }
+
+ // Returns a list of out-edges corresponding to a terminator
+ // instruction, which is the last instruction of the block.
+ virtual NodeList getTerminatorEdges() const {
+ // All valid terminator instructions override this method. For
+ // the default implementation, we assert in case some CfgNode
+ // is constructed without a terminator instruction at the end.
+ assert(0);
+ return NodeList();
+ }
+
+ // Updates the status of the Variables contained within the
+ // instruction. In particular, it marks where the Dest variable is
+ // first assigned, and it tracks whether variables are live across
+ // basic blocks, i.e. used in a different block from their definition.
+ void updateVars(CfgNode *Node);
+
+ virtual void dump(const IceCfg *Cfg) const;
+ void dumpDecorated(const IceCfg *Cfg) const;
+ void dumpSources(const IceCfg *Cfg) const;
+ void dumpDest(const IceCfg *Cfg) const;
+
+ virtual ~Inst();
+
+protected:
+ Inst(IceCfg *Cfg, InstKind Kind, IceSize_t MaxSrcs, Variable *Dest);
+ void addSource(Operand *Src) {
+ assert(Src);
+ assert(NumSrcs < MaxSrcs);
+ Srcs[NumSrcs++] = Src;
+ }
+
+ const InstKind Kind;
+ // Number is the instruction number for describing live ranges.
+ int32_t Number;
+ // Deleted means irrevocably deleted.
+ bool Deleted;
+ // HasSideEffects means the instruction is something like a function
+ // call or a volatile load that can't be removed even if its Dest
+ // variable is not live.
+ bool HasSideEffects;
+
+ Variable *Dest;
+ const IceSize_t MaxSrcs; // only used for assert
+ IceSize_t NumSrcs;
+ Operand **Srcs;
+
+private:
+ Inst(const Inst &) LLVM_DELETED_FUNCTION;
+ Inst &operator=(const Inst &) LLVM_DELETED_FUNCTION;
+};
+
+// Alloca instruction. This captures the size in bytes as getSrc(0),
+// and the alignment.
+class InstAlloca : public Inst {
+public:
+ static InstAlloca *create(IceCfg *Cfg, Operand *ByteCount, uint32_t Align,
+ Variable *Dest) {
+ return new (Cfg->allocateInst<InstAlloca>())
+ InstAlloca(Cfg, ByteCount, Align, Dest);
+ }
+ uint32_t getAlign() const { return Align; }
+ Operand *getSizeInBytes() const { return getSrc(0); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Alloca; }
+
+private:
+ InstAlloca(IceCfg *Cfg, Operand *ByteCount, uint32_t Align, Variable *Dest);
+ InstAlloca(const InstAlloca &) LLVM_DELETED_FUNCTION;
+ InstAlloca &operator=(const InstAlloca &) LLVM_DELETED_FUNCTION;
+ virtual ~InstAlloca() {}
+ const uint32_t Align;
+};
+
+#define ICEINSTARITHMETIC_TABLE \
+ /* enum value, printable string, commutative */ \
+ X(Add, "add", true) X(Fadd, "fadd", false) X(Sub, "sub", false) \
+ X(Fsub, "fsub", false) X(Mul, "mul", true) X(Fmul, "fmul", false) \
+ X(Udiv, "udiv", false) X(Sdiv, "sdiv", false) X(Fdiv, "fdiv", false) \
+ X(Urem, "urem", false) X(Srem, "srem", false) X(Frem, "frem", false) \
+ X(Shl, "shl", false) X(Lshr, "lshr", false) X(Ashr, "ashr", false) \
+ X(And, "and", true) X(Or, "or", true) X(Xor, "xor", true)
JF 2014/04/23 03:51:28 Yeah, un-clang-formatting this would be nice.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+
+// Binary arithmetic instruction. The source operands are captured in
+// getSrc(0) and getSrc(1).
+class InstArithmetic : public Inst {
+public:
+#define X(tag, str, commutative) tag,
+
+ enum OpKind {
+ ICEINSTARITHMETIC_TABLE
+ };
+#undef X
+ static InstArithmetic *create(IceCfg *Cfg, OpKind Op, Variable *Dest,
+ Operand *Source1, Operand *Source2) {
+ return new (Cfg->allocateInst<InstArithmetic>())
+ InstArithmetic(Cfg, Op, Dest, Source1, Source2);
+ }
+ OpKind getOp() const { return Op; }
+ bool isCommutative() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) {
+ return Inst->getKind() == Arithmetic;
+ }
+
+private:
+ InstArithmetic(IceCfg *Cfg, OpKind Op, Variable *Dest, Operand *Source1,
+ Operand *Source2);
+ InstArithmetic(const InstArithmetic &) LLVM_DELETED_FUNCTION;
+ InstArithmetic &operator=(const InstArithmetic &) LLVM_DELETED_FUNCTION;
+ virtual ~InstArithmetic() {}
+
+ const OpKind Op;
+};
+
+// Assignment instruction. The source operand is captured in
+// getSrc(0). This is not part of the LLVM bitcode, but is a useful
+// abstraction for some of the lowering. E.g., if Phi instruction
+// lowering happens before target lowering, or for representing an
+// Inttoptr instruction, or as an intermediate step for lowering a
+// Load instruction.
+class InstAssign : public Inst {
+public:
+ static InstAssign *create(IceCfg *Cfg, Variable *Dest, Operand *Source) {
+ return new (Cfg->allocateInst<InstAssign>()) InstAssign(Cfg, Dest, Source);
+ }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Assign; }
+
+private:
+ InstAssign(IceCfg *Cfg, Variable *Dest, Operand *Source);
+ InstAssign(const InstAssign &) LLVM_DELETED_FUNCTION;
+ InstAssign &operator=(const InstAssign &) LLVM_DELETED_FUNCTION;
+ virtual ~InstAssign() {}
+};
+
+// Branch instruction. This represents both conditional and
+// unconditional branches.
+class InstBr : public Inst {
+public:
+ // Create a conditional branch. If TargetTrue==TargetFalse, it is
+ // optimized to an unconditional branch.
+ static InstBr *create(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue,
+ CfgNode *TargetFalse) {
+ return new (Cfg->allocateInst<InstBr>())
+ InstBr(Cfg, Source, TargetTrue, TargetFalse);
+ }
+ // Create an unconditional branch.
+ static InstBr *create(IceCfg *Cfg, CfgNode *Target) {
+ return new (Cfg->allocateInst<InstBr>()) InstBr(Cfg, Target);
+ }
+ bool isUnconditional() const { return getTargetTrue() == NULL; }
+ Operand *getCondition() const {
+ assert(!isUnconditional());
+ return getSrc(0);
+ }
+ CfgNode *getTargetTrue() const { return TargetTrue; }
+ CfgNode *getTargetFalse() const { return TargetFalse; }
+ CfgNode *getTargetUnconditional() const {
+ assert(isUnconditional());
+ return getTargetFalse();
+ }
+ virtual NodeList getTerminatorEdges() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Br; }
+
+private:
+ // Conditional branch
+ InstBr(IceCfg *Cfg, Operand *Source, CfgNode *TargetTrue,
+ CfgNode *TargetFalse);
+ // Unconditional branch
+ InstBr(IceCfg *Cfg, CfgNode *Target);
+ InstBr(const InstBr &) LLVM_DELETED_FUNCTION;
+ InstBr &operator=(const InstBr &) LLVM_DELETED_FUNCTION;
+ virtual ~InstBr() {}
+
+ CfgNode *const TargetFalse; // Doubles as unconditional branch target
+ CfgNode *const TargetTrue; // NULL if unconditional branch
+};
+
+// Call instruction. The call target is captured as getSrc(0), and
+// arg I is captured as getSrc(I+1).
+class InstCall : public Inst {
+public:
+ // The Tail argument represents the "tail" marker from the original
+ // bitcode instruction (which doesn't necessarily mean that this
+ // call must be executed as a tail call).
JF 2014/04/23 03:51:28 What does it mean?
Jim Stichnoth 2014/04/26 15:02:11 Per offline discussion - since the tail marker isn
+ static InstCall *create(IceCfg *Cfg, IceSize_t NumArgs, Variable *Dest,
+ Operand *CallTarget, bool Tail) {
+ return new (Cfg->allocateInst<InstCall>())
+ InstCall(Cfg, NumArgs, Dest, CallTarget, Tail);
+ }
+ void addArg(Operand *Arg) { addSource(Arg); }
+ Operand *getCallTarget() const { return getSrc(0); }
+ Operand *getArg(IceSize_t I) const { return getSrc(I + 1); }
+ IceSize_t getNumArgs() const { return getSrcSize() - 1; }
+ bool isTail() const { return Tail; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Call; }
+
+private:
+ InstCall(IceCfg *Cfg, IceSize_t NumArgs, Variable *Dest, Operand *CallTarget,
+ bool Tail)
+ : Inst(Cfg, Inst::Call, NumArgs + 1, Dest), Tail(Tail) {
+ // Set HasSideEffects so that the call instruction can't be
+ // dead-code eliminated. Don't set this for a deletable intrinsic
+ // call.
+ HasSideEffects = true;
+ addSource(CallTarget);
+ }
+ InstCall(const InstCall &) LLVM_DELETED_FUNCTION;
+ InstCall &operator=(const InstCall &) LLVM_DELETED_FUNCTION;
+ virtual ~InstCall() {}
+ const bool Tail;
+};
+
+#define ICEINSTCAST_TABLE \
+ /* enum value, printable string */ \
+ X(Trunc, "trunc") X(Zext, "zext") X(Sext, "sext") X(Fptrunc, "fptrunc") \
+ X(Fpext, "fpext") X(Fptoui, "fptoui") X(Fptosi, "fptosi") \
+ X(Uitofp, "uitofp") X(Sitofp, "sitofp") X(Bitcast, "bitcast")
JF 2014/04/23 03:51:28 clang-un-format
Jim Stichnoth 2014/04/26 15:02:11 Done.
+
+// Cast instruction (a.k.a. conversion operation).
+class InstCast : public Inst {
+public:
+#define X(tag, str) tag,
+
+ enum OpKind {
+ ICEINSTCAST_TABLE
+ };
+#undef X
+ static InstCast *create(IceCfg *Cfg, OpKind CastKind, Variable *Dest,
+ Operand *Source) {
+ return new (Cfg->allocateInst<InstCast>())
+ InstCast(Cfg, CastKind, Dest, Source);
+ }
+ OpKind getCastKind() const { return CastKind; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Cast; }
+
+private:
+ InstCast(IceCfg *Cfg, OpKind CastKind, Variable *Dest, Operand *Source);
+ InstCast(const InstCast &) LLVM_DELETED_FUNCTION;
+ InstCast &operator=(const InstCast &) LLVM_DELETED_FUNCTION;
+ virtual ~InstCast() {}
+ const OpKind CastKind;
+};
+
+#define ICEINSTFCMP_TABLE \
+ /* enum value, printable string */ \
+ X(False, "false") X(Oeq, "oeq") X(Ogt, "ogt") X(Oge, "oge") X(Olt, "olt") \
+ X(Ole, "ole") X(One, "one") X(Ord, "ord") X(Ueq, "ueq") X(Ugt, "ugt") \
+ X(Uge, "uge") X(Ult, "ult") X(Ule, "ule") X(Une, "une") X(Uno, "uno") \
+ X(True, "true")
JF 2014/04/23 03:51:28 clang-un-format
Jim Stichnoth 2014/04/26 15:02:11 Done.
+
+// Floating-point comparison instruction. The source operands are
+// captured in getSrc(0) and getSrc(1).
+class InstFcmp : public Inst {
+public:
+#define X(tag, str) tag,
+
+ enum FCond {
+ ICEINSTFCMP_TABLE
+ };
+#undef X
+ static InstFcmp *create(IceCfg *Cfg, FCond Condition, Variable *Dest,
+ Operand *Source1, Operand *Source2) {
+ return new (Cfg->allocateInst<InstFcmp>())
+ InstFcmp(Cfg, Condition, Dest, Source1, Source2);
+ }
+ FCond getCondition() const { return Condition; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Fcmp; }
+
+private:
+ InstFcmp(IceCfg *Cfg, FCond Condition, Variable *Dest, Operand *Source1,
+ Operand *Source2);
+ InstFcmp(const InstFcmp &) LLVM_DELETED_FUNCTION;
+ InstFcmp &operator=(const InstFcmp &) LLVM_DELETED_FUNCTION;
+ virtual ~InstFcmp() {}
+ const FCond Condition;
+};
+
+#define ICEINSTICMP_TABLE \
+ /* enum value, printable string */ \
+ X(Eq, "eq") X(Ne, "ne") X(Ugt, "ugt") X(Uge, "uge") X(Ult, "ult") \
+ X(Ule, "ule") X(Sgt, "sgt") X(Sge, "sge") X(Slt, "slt") X(Sle, "sle")
JF 2014/04/23 03:51:28 clang-un-format
Jim Stichnoth 2014/04/26 15:02:11 Done.
+
+// Integer comparison instruction. The source operands are captured
+// in getSrc(0) and getSrc(1).
+class InstIcmp : public Inst {
+public:
+#define X(tag, str) tag,
+
+ enum ICond {
+ ICEINSTICMP_TABLE
+ };
+#undef X
+ static InstIcmp *create(IceCfg *Cfg, ICond Condition, Variable *Dest,
+ Operand *Source1, Operand *Source2) {
+ return new (Cfg->allocateInst<InstIcmp>())
+ InstIcmp(Cfg, Condition, Dest, Source1, Source2);
+ }
+ ICond getCondition() const { return Condition; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Icmp; }
+
+private:
+ InstIcmp(IceCfg *Cfg, ICond Condition, Variable *Dest, Operand *Source1,
+ Operand *Source2);
+ InstIcmp(const InstIcmp &) LLVM_DELETED_FUNCTION;
+ InstIcmp &operator=(const InstIcmp &) LLVM_DELETED_FUNCTION;
+ virtual ~InstIcmp() {}
+ const ICond Condition;
+};
+
+// Load instruction. The source address is captured in getSrc(0).
+class InstLoad : public Inst {
+public:
+ static InstLoad *create(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr) {
+ return new (Cfg->allocateInst<InstLoad>()) InstLoad(Cfg, Dest, SourceAddr);
+ }
+ Operand *getSourceAddress() const { return getSrc(0); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Load; }
+
+private:
+ InstLoad(IceCfg *Cfg, Variable *Dest, Operand *SourceAddr);
+ InstLoad(const InstLoad &) LLVM_DELETED_FUNCTION;
+ InstLoad &operator=(const InstLoad &) LLVM_DELETED_FUNCTION;
+ virtual ~InstLoad() {}
+};
+
+// Phi instruction. For incoming edge I, the node is Labels[I] and
+// the Phi source operand is getSrc(I).
+class InstPhi : public Inst {
+public:
+ static InstPhi *create(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest) {
+ return new (Cfg->allocateInst<InstPhi>()) InstPhi(Cfg, MaxSrcs, Dest);
+ }
+ void addArgument(Operand *Source, CfgNode *Label);
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Phi; }
+
+private:
+ InstPhi(IceCfg *Cfg, IceSize_t MaxSrcs, Variable *Dest);
+ InstPhi(const InstPhi &) LLVM_DELETED_FUNCTION;
+ InstPhi &operator=(const InstPhi &) LLVM_DELETED_FUNCTION;
+ virtual ~InstPhi() {
+#ifdef ICE_NO_ARENAS
+ delete[] Labels;
JF 2014/04/23 03:51:28 Call you call Cfg->deleteInst. That allows you to
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#endif // ICE_NO_ARENAS
+ }
+
+ // Labels[] duplicates the InEdges[] information in the enclosing
+ // CfgNode, but the Phi instruction is created before InEdges[]
+ // is available, so it's more complicated to share the list.
+ CfgNode **Labels;
+};
+
+// Ret instruction. The return value is captured in getSrc(0), but if
+// there is no return value (void-type function), then
+// getSrcSize()==0 and hasRetValue()==false.
+class InstRet : public Inst {
+public:
+ static InstRet *create(IceCfg *Cfg, Operand *RetValue = NULL) {
+ return new (Cfg->allocateInst<InstRet>()) InstRet(Cfg, RetValue);
+ }
+ bool hasRetValue() const { return getSrcSize(); }
+ Operand *getRetValue() const {
+ assert(hasRetValue());
+ return getSrc(0);
+ }
+ virtual NodeList getTerminatorEdges() const { return NodeList(); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Ret; }
+
+private:
+ InstRet(IceCfg *Cfg, Operand *RetValue);
+ InstRet(const InstRet &) LLVM_DELETED_FUNCTION;
+ InstRet &operator=(const InstRet &) LLVM_DELETED_FUNCTION;
+ virtual ~InstRet() {}
+};
+
+// Select instruction. The condition, true, and false operands are captured.
+class InstSelect : public Inst {
+public:
+ static InstSelect *create(IceCfg *Cfg, Variable *Dest, Operand *Condition,
+ Operand *SourceTrue, Operand *SourceFalse) {
+ return new (Cfg->allocateInst<InstSelect>())
+ InstSelect(Cfg, Dest, Condition, SourceTrue, SourceFalse);
+ }
+ Operand *getCondition() const { return getSrc(0); }
+ Operand *getTrueOperand() const { return getSrc(1); }
+ Operand *getFalseOperand() const { return getSrc(2); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Select; }
+
+private:
+ InstSelect(IceCfg *Cfg, Variable *Dest, Operand *Condition, Operand *Source1,
+ Operand *Source2);
+ InstSelect(const InstSelect &) LLVM_DELETED_FUNCTION;
+ InstSelect &operator=(const InstSelect &) LLVM_DELETED_FUNCTION;
+ virtual ~InstSelect() {}
+};
+
+// Store instruction. The address operand is captured, along with the
+// data operand to be stored into the address.
+class InstStore : public Inst {
+public:
+ static InstStore *create(IceCfg *Cfg, Operand *Data, Operand *Addr) {
+ return new (Cfg->allocateInst<InstStore>()) InstStore(Cfg, Data, Addr);
+ }
+ Operand *getAddr() const { return getSrc(1); }
+ Operand *getData() const { return getSrc(0); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Store; }
+
+private:
+ InstStore(IceCfg *Cfg, Operand *Data, Operand *Addr);
+ InstStore(const InstStore &) LLVM_DELETED_FUNCTION;
+ InstStore &operator=(const InstStore &) LLVM_DELETED_FUNCTION;
+ virtual ~InstStore() {}
+};
+
+// Switch instruction. The single source operand is captured as
+// getSrc(0).
+class InstSwitch : public Inst {
+public:
+ static InstSwitch *create(IceCfg *Cfg, IceSize_t NumCases, Operand *Source,
+ CfgNode *LabelDefault) {
+ return new (Cfg->allocateInst<InstSwitch>())
+ InstSwitch(Cfg, NumCases, Source, LabelDefault);
+ }
+ Operand *getComparison() const { return getSrc(0); }
+ CfgNode *getLabelDefault() const { return LabelDefault; }
+ IceSize_t getNumCases() const { return NumCases; }
+ uint64_t getValue(IceSize_t I) const {
+ assert(I < NumCases);
+ return Values[I];
+ }
+ CfgNode *getLabel(IceSize_t I) const {
+ assert(I < NumCases);
+ return Labels[I];
+ }
+ void addBranch(IceSize_t CaseIndex, uint64_t Value, CfgNode *Label);
+ virtual NodeList getTerminatorEdges() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) { return Inst->getKind() == Switch; }
+
+private:
+ InstSwitch(IceCfg *Cfg, IceSize_t NumCases, Operand *Source,
+ CfgNode *LabelDefault);
+ InstSwitch(const InstSwitch &) LLVM_DELETED_FUNCTION;
+ InstSwitch &operator=(const InstSwitch &) LLVM_DELETED_FUNCTION;
+ virtual ~InstSwitch() {
+#ifdef ICE_NO_ARENAS
+ delete[] Values;
+ delete[] Labels;
JF 2014/04/23 03:51:28 Same on delete.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+#endif // ICE_NO_ARENAS
+ }
+
+ CfgNode *LabelDefault;
+ IceSize_t NumCases; // not including the default case
+ uint64_t *Values; // size is NumCases
+ CfgNode **Labels; // size is NumCases
+};
+
+// Unreachable instruction. This is a terminator instruction with no
+// operands.
+class InstUnreachable : public Inst {
+public:
+ static InstUnreachable *create(IceCfg *Cfg) {
+ return new (Cfg->allocateInst<InstUnreachable>()) InstUnreachable(Cfg);
+ }
+ virtual NodeList getTerminatorEdges() const { return NodeList(); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const Inst *Inst) {
+ return Inst->getKind() == Unreachable;
+ }
+
+private:
+ InstUnreachable(IceCfg *Cfg);
+ InstUnreachable(const InstUnreachable &) LLVM_DELETED_FUNCTION;
+ InstUnreachable &operator=(const InstUnreachable &) LLVM_DELETED_FUNCTION;
+ virtual ~InstUnreachable() {}
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEINST_H

Powered by Google App Engine
This is Rietveld 408576698