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

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: Introduce IceGlobalContext, and rearrange other things around that 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..576427270b670c47838e7c19e977155bfe5b1ce5
--- /dev/null
+++ b/src/IceInst.h
@@ -0,0 +1,526 @@
+//===- 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 IceInst 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"
+
+class IceInst {
+public:
+ enum InstKind {
+ Alloca,
+ Arithmetic,
+ Assign, // not part of LLVM/PNaCl bitcode
+ Br,
+ Call,
+ Cast,
+ Fcmp,
+ Icmp,
+ Load,
+ Phi,
+ Ret,
+ Select,
+ Store,
+ Switch,
+ Unreachable
JF 2014/04/16 01:27:32 I'd put Unreachable as InstKind 0.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+ };
+ 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; }
+
+ IceVariable *getDest() const { return Dest; }
+
+ uint32_t getSrcSize() const { return NumSrcs; }
+ IceOperand *getSrc(uint32_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 IceNodeList getTerminatorEdges() const {
+ assert(0);
JF 2014/04/16 01:27:32 ?
Jim Stichnoth 2014/04/21 20:26:40 Jan had the same comment. :) Added a comment to e
JF 2014/04/23 03:51:28 llvm_unreachable would be better for this.
Jim Stichnoth 2014/04/26 15:02:11 Done.
+ return IceNodeList();
+ }
+
+ // Updates the status of the IceVariables 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(IceCfgNode *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 ~IceInst() {}
JF 2014/04/16 01:27:32 Srcs doesn't get deleted? You should also probabl
Jim Stichnoth 2014/04/21 20:26:40 Done.
+
+protected:
+ IceInst(IceCfg *Cfg, InstKind Kind, uint32_t MaxSrcs, IceVariable *Dest);
+ void addSource(IceOperand *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;
JF 2014/04/16 01:27:32 Having this in every Inst seems silly when it's a
Jim Stichnoth 2014/04/21 20:26:40 It's not purely computable from the instruction ki
+
+ IceVariable *Dest;
+ const uint32_t MaxSrcs; // only used for assert
JF 2014/04/16 01:27:32 size_t
Jim Stichnoth 2014/04/21 20:26:40 Changed this and many other instances of uint32_t
+ uint32_t NumSrcs;
+ IceOperand **Srcs;
JF 2014/04/16 01:27:32 The ideal here would be to use C's zero-sized arra
Jim Stichnoth 2014/04/21 20:26:40 I don't want IceInst or IceOperand to hold any con
+
+private:
+ IceInst(const IceInst &) LLVM_DELETED_FUNCTION;
+ IceInst &operator=(const IceInst &) LLVM_DELETED_FUNCTION;
+};
+
+template <> IceOstream &operator<<(IceOstream &Str, const IceInst &I);
JF 2014/04/16 01:27:32 I think you want this template specialization in I
Jim Stichnoth 2014/04/21 20:26:40 Actually that wasn't supposed to be there anymore.
+
+// Alloca instruction. This captures the size in bytes as getSrc(0),
+// and the alignment.
JF 2014/04/16 01:27:32 Are there any special meanings for alignment? What
Jim Stichnoth 2014/04/21 20:26:40 This is just the alignment from the LLVM bitcode,
JF 2014/04/23 03:51:28 Could you add a comment to this code that explains
Jim Stichnoth 2014/04/26 15:02:11 Done.
+class IceInstAlloca : public IceInst {
+public:
+ static IceInstAlloca *create(IceCfg *Cfg, IceOperand *ByteCount,
+ uint32_t Align, IceVariable *Dest) {
+ return new (Cfg->allocateInst<IceInstAlloca>())
+ IceInstAlloca(Cfg, ByteCount, Align, Dest);
+ }
+ uint32_t getAlign() const { return Align; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Alloca; }
JF 2014/04/16 01:27:32 This could also be auto-defined (albeit not declar
Jim Stichnoth 2014/04/21 20:26:40 True, except in the next CL, we add "Target" to en
JF 2014/04/23 03:51:28 I see. Maybe, but probably not worth it.
Jim Stichnoth 2014/04/26 15:02:11 OK, deferring this for now.
+
+private:
+ IceInstAlloca(IceCfg *Cfg, IceOperand *ByteCount, uint32_t Align,
+ IceVariable *Dest);
+ IceInstAlloca(const IceInstAlloca &) LLVM_DELETED_FUNCTION;
+ IceInstAlloca &operator=(const IceInstAlloca &) LLVM_DELETED_FUNCTION;
+ const uint32_t Align;
+};
+
+// Binary arithmetic instruction. The source operands are captured in
+// getSrc(0) and getSrc(1).
+class IceInstArithmetic : public IceInst {
+public:
+ enum OpKind {
+ // Ordered by http://llvm.org/docs/LangRef.html#binary-operations
JF 2014/04/16 01:27:32 Why does the order matter? Is the goal to match th
Jim Stichnoth 2014/04/21 20:26:40 Order doesn't matter, comment removed.
+ Add,
+ Fadd,
+ Sub,
+ Fsub,
+ Mul,
+ Fmul,
+ Udiv,
+ Sdiv,
+ Fdiv,
+ Urem,
+ Srem,
+ Frem,
+ // Ordered by http://llvm.org/docs/LangRef.html#bitwise-binary-operations
+ Shl,
+ Lshr,
+ Ashr,
+ And,
+ Or,
+ Xor
+ };
+ static IceInstArithmetic *create(IceCfg *Cfg, OpKind Op, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2) {
+ return new (Cfg->allocateInst<IceInstArithmetic>())
+ IceInstArithmetic(Cfg, Op, Dest, Source1, Source2);
JF 2014/04/16 01:27:32 Do the operand types necessarily match?
Jim Stichnoth 2014/04/21 20:26:40 Right now, I'm only doing the most haphazard of st
JF 2014/04/23 03:51:28 Good point, probably the reader, but I'm not sure
Jim Stichnoth 2014/04/26 15:02:11 Done. TODO added to the top of this file.
+ }
+ OpKind getOp() const { return Op; }
+ bool isCommutative() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) {
+ return Inst->getKind() == Arithmetic;
+ }
+
+private:
+ IceInstArithmetic(IceCfg *Cfg, OpKind Op, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2);
+ IceInstArithmetic(const IceInstArithmetic &) LLVM_DELETED_FUNCTION;
+ IceInstArithmetic &operator=(const IceInstArithmetic &) LLVM_DELETED_FUNCTION;
+
+ 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 IceInstAssign : public IceInst {
+public:
+ static IceInstAssign *create(IceCfg *Cfg, IceVariable *Dest,
+ IceOperand *Source) {
+ return new (Cfg->allocateInst<IceInstAssign>())
+ IceInstAssign(Cfg, Dest, Source);
+ }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Assign; }
+
+private:
+ IceInstAssign(IceCfg *Cfg, IceVariable *Dest, IceOperand *Source);
+ IceInstAssign(const IceInstAssign &) LLVM_DELETED_FUNCTION;
+ IceInstAssign &operator=(const IceInstAssign &) LLVM_DELETED_FUNCTION;
+};
+
+// Branch instruction. This represents both conditional and
+// unconditional branches.
JF 2014/04/16 01:27:32 The implementation says that True==False means unc
Jim Stichnoth 2014/04/21 20:26:40 Done.
+class IceInstBr : public IceInst {
+public:
+ static IceInstBr *create(IceCfg *Cfg, IceOperand *Source,
+ IceCfgNode *TargetTrue, IceCfgNode *TargetFalse) {
+ return new (Cfg->allocateInst<IceInstBr>())
+ IceInstBr(Cfg, Source, TargetTrue, TargetFalse);
+ }
+ static IceInstBr *create(IceCfg *Cfg, IceCfgNode *Target) {
+ return new (Cfg->allocateInst<IceInstBr>()) IceInstBr(Cfg, Target);
+ }
+ bool isUnconditional() const { return getTargetTrue() == NULL; }
+ IceCfgNode *getTargetTrue() const { return TargetTrue; }
+ IceCfgNode *getTargetFalse() const { return TargetFalse; }
+ IceCfgNode *getTargetUnconditional() const {
+ assert(isUnconditional());
+ return getTargetFalse();
+ }
+ virtual IceNodeList getTerminatorEdges() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Br; }
+
+private:
+ // Conditional branch
+ IceInstBr(IceCfg *Cfg, IceOperand *Source, IceCfgNode *TargetTrue,
+ IceCfgNode *TargetFalse);
+ // Unconditional branch
+ IceInstBr(IceCfg *Cfg, IceCfgNode *Target);
+ IceInstBr(const IceInstBr &) LLVM_DELETED_FUNCTION;
+ IceInstBr &operator=(const IceInstBr &) LLVM_DELETED_FUNCTION;
+
+ IceCfgNode *const TargetFalse; // Doubles as unconditional branch target
+ IceCfgNode *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 IceInstCall : public IceInst {
+public:
+ static IceInstCall *create(IceCfg *Cfg, uint32_t NumArgs, IceVariable *Dest,
+ IceOperand *CallTarget, bool Tail) {
JF 2014/04/16 01:27:32 Explain Tail: is it actually tailcall, or LLVM's w
Jim Stichnoth 2014/04/21 20:26:40 Done. (It's the weird LLVM tail marker.)
+ return new (Cfg->allocateInst<IceInstCall>())
+ IceInstCall(Cfg, NumArgs, Dest, CallTarget, Tail);
+ }
+ void addArg(IceOperand *Arg) { addSource(Arg); }
+ IceOperand *getCallTarget() const { return getSrc(0); }
+ IceOperand *getArg(uint32_t I) const { return getSrc(I + 1); }
+ uint32_t getNumArgs() const { return getSrcSize() - 1; }
+ bool isTail() const { return Tail; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Call; }
+
+private:
+ IceInstCall(IceCfg *Cfg, uint32_t NumArgs, IceVariable *Dest,
+ IceOperand *CallTarget, bool Tail)
+ : IceInst(Cfg, IceInst::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);
+ }
+ IceInstCall(const IceInstCall &) LLVM_DELETED_FUNCTION;
+ IceInstCall &operator=(const IceInstCall &) LLVM_DELETED_FUNCTION;
+ const bool Tail;
+};
+
+// Cast instruction (a.k.a. conversion operation).
+class IceInstCast : public IceInst {
+public:
+ enum OpKind {
+ // Ordered by http://llvm.org/docs/LangRef.html#conversion-operations
JF 2014/04/16 01:27:32 Ditto on ordering.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+ Trunc,
+ Zext,
+ Sext,
+ Fptrunc,
+ Fpext,
+ Fptoui,
+ Fptosi,
+ Uitofp,
+ Sitofp,
+ Bitcast
+ };
+ static IceInstCast *create(IceCfg *Cfg, OpKind CastKind, IceVariable *Dest,
+ IceOperand *Source) {
+ return new (Cfg->allocateInst<IceInstCast>())
+ IceInstCast(Cfg, CastKind, Dest, Source);
+ }
+ OpKind getCastKind() const { return CastKind; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Cast; }
+
+private:
+ IceInstCast(IceCfg *Cfg, OpKind CastKind, IceVariable *Dest,
+ IceOperand *Source);
+ IceInstCast(const IceInstCast &) LLVM_DELETED_FUNCTION;
+ IceInstCast &operator=(const IceInstCast &) LLVM_DELETED_FUNCTION;
+ OpKind CastKind;
JF 2014/04/16 01:27:32 const, to keep with the other classes.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+};
+
+// Floating-point comparison instruction. The source operands are
+// captured in getSrc(0) and getSrc(1).
+class IceInstFcmp : public IceInst {
+public:
+ enum FCond {
+ // Ordered by http://llvm.org/docs/LangRef.html#id254
JF 2014/04/16 01:27:32 Ditto.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+ False,
+ Oeq,
+ Ogt,
+ Oge,
+ Olt,
+ Ole,
+ One,
+ Ord,
+ Ueq,
+ Ugt,
+ Uge,
+ Ult,
+ Ule,
+ Une,
+ Uno,
+ True
+ };
+ static IceInstFcmp *create(IceCfg *Cfg, FCond Condition, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2) {
+ return new (Cfg->allocateInst<IceInstFcmp>())
+ IceInstFcmp(Cfg, Condition, Dest, Source1, Source2);
JF 2014/04/16 01:27:32 Do the operand types necessarily match?
Jim Stichnoth 2014/04/21 20:26:40 Ditto.
+ }
+ FCond getCondition() const { return Condition; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Fcmp; }
+
+private:
+ IceInstFcmp(IceCfg *Cfg, FCond Condition, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2);
+ IceInstFcmp(const IceInstFcmp &) LLVM_DELETED_FUNCTION;
+ IceInstFcmp &operator=(const IceInstFcmp &) LLVM_DELETED_FUNCTION;
+ FCond Condition;
JF 2014/04/16 01:27:32 const, to keep with the other classes.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+};
+
+// Integer comparison instruction. The source operands are captured
+// in getSrc(0) and getSrc(1).
+class IceInstIcmp : public IceInst {
+public:
+ enum ICond {
+ // Ordered by http://llvm.org/docs/LangRef.html#id249
JF 2014/04/16 01:27:32 Ditto.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+ Eq,
+ Ne,
+ Ugt,
+ Uge,
+ Ult,
+ Ule,
+ Sgt,
+ Sge,
+ Slt,
+ Sle
+ };
+ static IceInstIcmp *create(IceCfg *Cfg, ICond Condition, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2) {
+ return new (Cfg->allocateInst<IceInstIcmp>())
+ IceInstIcmp(Cfg, Condition, Dest, Source1, Source2);
JF 2014/04/16 01:27:32 Do the operand types necessarily match?
Jim Stichnoth 2014/04/21 20:26:40 Ditto.
+ }
+ ICond getCondition() const { return Condition; }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Icmp; }
+
+private:
+ IceInstIcmp(IceCfg *Cfg, ICond Condition, IceVariable *Dest,
+ IceOperand *Source1, IceOperand *Source2);
+ IceInstIcmp(const IceInstIcmp &) LLVM_DELETED_FUNCTION;
+ IceInstIcmp &operator=(const IceInstIcmp &) LLVM_DELETED_FUNCTION;
+ ICond Condition;
JF 2014/04/16 01:27:32 const, to keep with the other classes.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+};
+
+// Load instruction. The source address is captured in getSrc(0);
JF 2014/04/16 01:27:32 Could you infer alignment? We guarantee that FP is
Jim Stichnoth 2014/04/21 20:26:40 True, the target lowering can probably make use of
+class IceInstLoad : public IceInst {
+public:
+ static IceInstLoad *create(IceCfg *Cfg, IceVariable *Dest,
+ IceOperand *SourceAddr) {
+ return new (Cfg->allocateInst<IceInstLoad>())
+ IceInstLoad(Cfg, Dest, SourceAddr);
+ }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Load; }
+
+private:
+ IceInstLoad(IceCfg *Cfg, IceVariable *Dest, IceOperand *SourceAddr);
+ IceInstLoad(const IceInstLoad &) LLVM_DELETED_FUNCTION;
+ IceInstLoad &operator=(const IceInstLoad &) LLVM_DELETED_FUNCTION;
+};
+
+// Phi instruction. For incoming edge I, the node is Labels[I] and
+// the Phi source operand is getSrc(I).
+class IceInstPhi : public IceInst {
+public:
+ static IceInstPhi *create(IceCfg *Cfg, uint32_t MaxSrcs, IceVariable *Dest) {
+ return new (Cfg->allocateInst<IceInstPhi>()) IceInstPhi(Cfg, MaxSrcs, Dest);
+ }
+ void addArgument(IceOperand *Source, IceCfgNode *Label);
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Phi; }
+
+private:
+ IceInstPhi(IceCfg *Cfg, uint32_t MaxSrcs, IceVariable *Dest);
+ IceInstPhi(const IceInstPhi &) LLVM_DELETED_FUNCTION;
+ IceInstPhi &operator=(const IceInstPhi &) LLVM_DELETED_FUNCTION;
+ // Labels[] duplicates the InEdges[] information in the enclosing
+ // IceCfgNode, but the Phi instruction is created before InEdges[]
+ // is available, so it's more complicated to share the list.
+ IceCfgNode **Labels;
JF 2014/04/16 01:27:32 dtor that deletes Labels.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+};
+
+// Ret instruction. The return value is captured in getSrc(0), but if
+// there is no return value (void-type function), then
+// getSrcSize()==0.
JF 2014/04/16 01:27:32 Create an isVoid method that does this, so code re
Jim Stichnoth 2014/04/21 20:26:40 Done - hasRetValue().
+class IceInstRet : public IceInst {
+public:
+ static IceInstRet *create(IceCfg *Cfg, IceOperand *Source = NULL) {
JF 2014/04/16 01:27:32 Source is kind of a bad name here (and in the impl
Jim Stichnoth 2014/04/21 20:26:40 Done - Source==>RetValue.
+ return new (Cfg->allocateInst<IceInstRet>()) IceInstRet(Cfg, Source);
+ }
+ virtual IceNodeList getTerminatorEdges() const { return IceNodeList(); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Ret; }
+
+private:
+ IceInstRet(IceCfg *Cfg, IceOperand *Source);
+ IceInstRet(const IceInstRet &) LLVM_DELETED_FUNCTION;
+ IceInstRet &operator=(const IceInstRet &) LLVM_DELETED_FUNCTION;
+};
+
+// Select instruction. The condition, true, and false operands are captured.
+class IceInstSelect : public IceInst {
+public:
+ static IceInstSelect *create(IceCfg *Cfg, IceVariable *Dest,
+ IceOperand *Condition, IceOperand *SourceTrue,
+ IceOperand *SourceFalse) {
+ return new (Cfg->allocateInst<IceInstSelect>())
+ IceInstSelect(Cfg, Dest, Condition, SourceTrue, SourceFalse);
JF 2014/04/16 01:27:32 Do the operand's type necessarily match?
Jim Stichnoth 2014/04/21 20:26:40 Ditto.
+ }
+ IceOperand *getCondition() const { return getSrc(0); }
+ IceOperand *getTrueOperand() const { return getSrc(1); }
+ IceOperand *getFalseOperand() const { return getSrc(2); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Select; }
+
+private:
+ IceInstSelect(IceCfg *Cfg, IceVariable *Dest, IceOperand *Condition,
+ IceOperand *Source1, IceOperand *Source2);
+ IceInstSelect(const IceInstSelect &) LLVM_DELETED_FUNCTION;
+ IceInstSelect &operator=(const IceInstSelect &) LLVM_DELETED_FUNCTION;
+};
+
+// Store instruction. The address operand is captured, along with the
+// data operand to be stored into the address.
+class IceInstStore : public IceInst {
+public:
+ static IceInstStore *create(IceCfg *Cfg, IceOperand *Data, IceOperand *Addr) {
+ return new (Cfg->allocateInst<IceInstStore>())
+ IceInstStore(Cfg, Data, Addr);
+ }
+ IceOperand *getAddr() const { return getSrc(1); }
+ IceOperand *getData() const { return getSrc(0); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Store; }
+
+private:
+ IceInstStore(IceCfg *Cfg, IceOperand *Data, IceOperand *Addr);
+ IceInstStore(const IceInstStore &) LLVM_DELETED_FUNCTION;
+ IceInstStore &operator=(const IceInstStore &) LLVM_DELETED_FUNCTION;
+};
+
+// Switch instruction. The single source operand is captured as
+// getSrc(0).
+class IceInstSwitch : public IceInst {
+public:
+ static IceInstSwitch *create(IceCfg *Cfg, uint32_t NumCases,
+ IceOperand *Source, IceCfgNode *LabelDefault) {
+ return new (Cfg->allocateInst<IceInstSwitch>())
+ IceInstSwitch(Cfg, NumCases, Source, LabelDefault);
+ }
+ IceCfgNode *getLabelDefault() const { return LabelDefault; }
+ uint32_t getNumCases() const { return NumCases; }
+ uint64_t getValue(uint32_t I) const {
+ assert(I < NumCases);
+ return Values[I];
+ }
+ IceCfgNode *getLabel(uint32_t I) const {
+ assert(I < NumCases);
+ return Labels[I];
+ }
+ void addBranch(uint32_t CaseIndex, uint64_t Value, IceCfgNode *Label);
+ virtual IceNodeList getTerminatorEdges() const;
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) { return Inst->getKind() == Switch; }
+
+private:
+ IceInstSwitch(IceCfg *Cfg, uint32_t NumCases, IceOperand *Source,
+ IceCfgNode *LabelDefault);
+ IceInstSwitch(const IceInstSwitch &) LLVM_DELETED_FUNCTION;
+ IceInstSwitch &operator=(const IceInstSwitch &) LLVM_DELETED_FUNCTION;
+ IceCfgNode *LabelDefault;
JF 2014/04/16 01:27:32 Why not put default at the start of Labels? It wo
Jim Stichnoth 2014/04/21 20:26:40 It shortens getTerminatorEdges() by 1 line, but ne
+ uint32_t NumCases; // not including the default case
+ uint64_t *Values; // size is NumCases
+ IceCfgNode **Labels; // size is NumCases
JF 2014/04/16 01:27:32 dtor that deletes Values and Labels.
Jim Stichnoth 2014/04/21 20:26:40 Done.
+};
+
+// Unreachable instruction. This is a terminator instruction with no
+// operands.
+class IceInstUnreachable : public IceInst {
+public:
+ static IceInstUnreachable *create(IceCfg *Cfg) {
+ return new (Cfg->allocateInst<IceInstUnreachable>())
+ IceInstUnreachable(Cfg);
+ }
+ virtual IceNodeList getTerminatorEdges() const { return IceNodeList(); }
+ virtual void dump(const IceCfg *Cfg) const;
+ static bool classof(const IceInst *Inst) {
+ return Inst->getKind() == Unreachable;
+ }
+
+private:
+ IceInstUnreachable(IceCfg *Cfg);
+ IceInstUnreachable(const IceInstUnreachable &) LLVM_DELETED_FUNCTION;
+ IceInstUnreachable &
+ operator=(const IceInstUnreachable &) LLVM_DELETED_FUNCTION;
+};
+
+#endif // SUBZERO_SRC_ICEINST_H

Powered by Google App Engine
This is Rietveld 408576698