From c8b25d40cbec063b1ca99cc1adf794399c6d05c0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 7 Jul 2001 08:36:50 +0000 Subject: Changed the fundemental architecture of Operands for Instructions. Now Operands are maintained as a vector in the User class, and operator iterators are provided as before. Getting an operand no longer requires a virtual function call. WARNING: getOperand(x) where x >= getNumOperands() will now assert instead of returning null! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/BasicBlock.h | 3 - include/llvm/ConstPoolVals.h | 46 +--------------- include/llvm/Function.h | 3 - include/llvm/InstrTypes.h | 68 ++++------------------- include/llvm/Instruction.h | 72 ------------------------ include/llvm/User.h | 38 ++++++++++--- include/llvm/iMemory.h | 107 ++++++++---------------------------- include/llvm/iOther.h | 52 +++++------------- include/llvm/iTerminators.h | 128 +++++++++++++++++++++++++------------------ 9 files changed, 156 insertions(+), 361 deletions(-) (limited to 'include') diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index d7f286ec56..402b1fd087 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -28,11 +28,8 @@ class Instruction; class Method; -class BasicBlock; class TerminatorInst; -typedef UseTy BasicBlockUse; - class BasicBlock : public Value { // Basic blocks are data objects also public: typedef ValueHolder InstListType; diff --git a/include/llvm/ConstPoolVals.h b/include/llvm/ConstPoolVals.h index dbdda62f92..d21ad8b6da 100644 --- a/include/llvm/ConstPoolVals.h +++ b/include/llvm/ConstPoolVals.h @@ -20,9 +20,6 @@ class StructType; // ConstPoolVal Class //===----------------------------------------------------------------------===// -class ConstPoolVal; -typedef UseTy ConstPoolUse; - class ConstPoolVal : public User { SymTabValue *Parent; @@ -53,17 +50,6 @@ public: inline const SymTabValue *getParent() const { return Parent; } inline SymTabValue *getParent() { return Parent; } - - // if i > the number of operands, then getOperand() returns 0, and setOperand - // returns false. setOperand() may also return false if the operand is of - // the wrong type. - // - // Note that some subclasses may change this default no argument behavior - // - virtual Value *getOperand(unsigned i) { return 0; } - virtual const Value *getOperand(unsigned i) const { return 0; } - virtual bool setOperand(unsigned i, Value *Val) { return false; } - virtual void dropAllReferences() {} }; @@ -172,7 +158,6 @@ public: // ConstPoolArray - Constant Array Declarations // class ConstPoolArray : public ConstPoolVal { - vector Val; ConstPoolArray(const ConstPoolArray &CPT); public: ConstPoolArray(const ArrayType *T, vector &V, @@ -183,20 +168,7 @@ public: virtual string getStrValue() const; virtual bool equals(const ConstPoolVal *V) const; - inline const vector &getValues() const { return Val; } - - // Implement User stuff... - // - virtual Value *getOperand(unsigned i) { - return (i < Val.size()) ? Val[i] : 0; - } - virtual const Value *getOperand(unsigned i) const { - return (i < Val.size()) ? Val[i] : 0; - } - - // setOperand fails! You can't change a constant! - virtual bool setOperand(unsigned i, Value *Val) { return false; } - virtual void dropAllReferences() { Val.clear(); } + inline const vector &getValues() const { return Operands; } }; @@ -204,7 +176,6 @@ public: // ConstPoolStruct - Constant Struct Declarations // class ConstPoolStruct : public ConstPoolVal { - vector Val; ConstPoolStruct(const ConstPoolStruct &CPT); public: ConstPoolStruct(const StructType *T, vector &V, @@ -215,20 +186,7 @@ public: virtual string getStrValue() const; virtual bool equals(const ConstPoolVal *V) const; - inline const vector &getValues() const { return Val; } - - // Implement User stuff... - // - virtual Value *getOperand(unsigned i) { - return (i < Val.size()) ? Val[i] : 0; - } - virtual const Value *getOperand(unsigned i) const { - return (i < Val.size()) ? Val[i] : 0; - } - - // setOperand fails! You can't change a constant! - virtual bool setOperand(unsigned i, Value *Val) { return false; } - virtual void dropAllReferences() { Val.clear(); } + inline const vector &getValues() const { return Operands; } }; #endif diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 51dbd646b3..b7aa855b2c 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -19,11 +19,8 @@ class Instruction; class BasicBlock; class MethodArgument; class MethodType; -class Method; class Module; -typedef UseTy MethodUse; - class Method : public SymTabValue { public: typedef ValueHolder ArgumentListType; diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 6d35ed5d50..8ec0da54d2 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -30,15 +30,8 @@ public: // Terminators must implement the methods required by Instruction... virtual Instruction *clone() const = 0; - virtual void dropAllReferences() = 0; virtual string getOpcode() const = 0; - virtual bool setOperand(unsigned i, Value *Val) = 0; - virtual const Value *getOperand(unsigned i) const = 0; - inline Value *getOperand(unsigned i) { - return (Value*)((const Instruction *)this)->getOperand(i); - } - // Additionally, they must provide a method to get at the successors of this // terminator instruction. If 'idx' is out of range, a null pointer shall be // returned. @@ -57,7 +50,6 @@ public: //===----------------------------------------------------------------------===// class UnaryOperator : public Instruction { - Use Source; public: // create() - Construct a unary instruction, given the opcode @@ -66,33 +58,17 @@ public: static UnaryOperator *create(unsigned Op, Value *Source); UnaryOperator(Value *S, unsigned iType, const string &Name = "") - : Instruction(S->getType(), iType, Name), Source(S, this) { + : Instruction(S->getType(), iType, Name) { + Operands.reserve(1); + Operands.push_back(Use(S, this)); } inline ~UnaryOperator() { dropAllReferences(); } virtual Instruction *clone() const { - return create(getInstType(), Source); - } - - virtual void dropAllReferences() { - Source = 0; + return create(getInstType(), Operands[0]); } virtual string getOpcode() const = 0; - - virtual unsigned getNumOperands() const { return 1; } - inline Value *getOperand(unsigned i) { - return (i == 0) ? Source : 0; - } - virtual const Value *getOperand(unsigned i) const { - return (i == 0) ? Source : 0; - } - virtual bool setOperand(unsigned i, Value *Val) { - // assert(Val && "operand must not be null!"); - if (i) return false; - Source = Val; - return true; - } }; @@ -102,7 +78,6 @@ public: //===----------------------------------------------------------------------===// class BinaryOperator : public Instruction { - Use Source1, Source2; public: // create() - Construct a binary instruction, given the opcode @@ -113,41 +88,20 @@ public: BinaryOperator(unsigned iType, Value *S1, Value *S2, const string &Name = "") - : Instruction(S1->getType(), iType, Name), Source1(S1, this), - Source2(S2, this){ - assert(S1 && S2 && S1->getType() == S2->getType()); + : Instruction(S1->getType(), iType, Name) { + Operands.reserve(2); + Operands.push_back(Use(S1, this)); + Operands.push_back(Use(S2, this)); + assert(Operands[0] && Operands[1] && + Operands[0]->getType() == Operands[1]->getType()); } inline ~BinaryOperator() { dropAllReferences(); } virtual Instruction *clone() const { - return create(getInstType(), Source1, Source2); - } - - virtual void dropAllReferences() { - Source1 = Source2 = 0; + return create(getInstType(), Operands[0], Operands[1]); } virtual string getOpcode() const = 0; - - virtual unsigned getNumOperands() const { return 2; } - virtual const Value *getOperand(unsigned i) const { - return (i == 0) ? Source1 : ((i == 1) ? Source2 : 0); - } - inline Value *getOperand(unsigned i) { - return (i == 0) ? Source1 : ((i == 1) ? Source2 : 0); - } - - virtual bool setOperand(unsigned i, Value *Val) { - // assert(Val && "operand must not be null!"); - if (i == 0) { - Source1 = Val; //assert(Val->getType() == Source2->getType()); - } else if (i == 1) { - Source2 = Val; //assert(Val->getType() == Source1->getType()); - } else { - return false; - } - return true; - } }; #endif diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 871ed037ef..70665232cd 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -41,32 +41,6 @@ public: inline BasicBlock *getParent() { return Parent; } bool hasSideEffects() const { return false; } // Memory & Call insts = true - // --------------------------------------------------------------------------- - // Implement the User interface - // if i > the number of operands, then getOperand() returns 0, and setOperand - // returns false. setOperand() may also return false if the operand is of - // the wrong type. - // - inline Value *getOperand(unsigned i) { - return (Value*)((const Instruction *)this)->getOperand(i); - } - virtual const Value *getOperand(unsigned i) const = 0; - virtual bool setOperand(unsigned i, Value *Val) = 0; - virtual unsigned getNumOperands() const = 0; - - // --------------------------------------------------------------------------- - // Operand Iterator interface... - // - template class OperandIterator; - typedef OperandIterator op_iterator; - typedef OperandIterator op_const_iterator; - - inline op_iterator op_begin() ; - inline op_const_iterator op_begin() const; - inline op_iterator op_end() ; - inline op_const_iterator op_end() const; - - // --------------------------------------------------------------------------- // Subclass classification... getInstType() returns a member of // one of the enums that is coming soon (down below)... @@ -148,52 +122,6 @@ public: NumOps, // Must be the last 'op' defined. UserOp1, UserOp2 // May be used internally to a pass... }; - -public: - template // Operand Iterator Implementation - class OperandIterator { - const _Inst Inst; - unsigned idx; - public: - typedef OperandIterator<_Inst, _Val> _Self; - typedef bidirectional_iterator_tag iterator_category; - typedef _Val pointer; - - inline OperandIterator(_Inst T) : Inst(T), idx(0) {} // begin iterator - inline OperandIterator(_Inst T, bool) - : Inst(T), idx(Inst->getNumOperands()) {} // end iterator - - inline bool operator==(const _Self& x) const { return idx == x.idx; } - inline bool operator!=(const _Self& x) const { return !operator==(x); } - - inline pointer operator*() const { return Inst->getOperand(idx); } - inline pointer *operator->() const { return &(operator*()); } - - inline _Self& operator++() { ++idx; return *this; } // Preincrement - inline _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; - } - - inline _Self& operator--() { --idx; return *this; } // Predecrement - inline _Self operator--(int) { // Postdecrement - _Self tmp = *this; --*this; return tmp; - } - }; - }; -inline Instruction::op_iterator Instruction::op_begin() { - return op_iterator(this); -} -inline Instruction::op_const_iterator Instruction::op_begin() const { - return op_const_iterator(this); -} -inline Instruction::op_iterator Instruction::op_end() { - return op_iterator(this,true); -} -inline Instruction::op_const_iterator Instruction::op_end() const { - return op_const_iterator(this,true); -} - - #endif diff --git a/include/llvm/User.h b/include/llvm/User.h index 58e0dec22b..7f2e3e39d8 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -13,20 +13,40 @@ #define LLVM_USER_H #include "llvm/Value.h" +#include class User : public Value { User(const User &); // Do not implement +protected: + vector Operands; public: User(const Type *Ty, ValueTy vty, const string &name = ""); - virtual ~User() {} + virtual ~User() { dropAllReferences(); } - // if i > the number of operands, then getOperand() returns 0, and setOperand - // returns false. setOperand() may also return false if the operand is of - // the wrong type. + inline Value *getOperand(unsigned i) { + assert(i < Operands.size() && "getOperand() out of range!"); + return Operands[i]; + } + inline const Value *getOperand(unsigned i) const { + assert(i < Operands.size() && "getOperand() const out of range!"); + return Operands[i]; + } + inline void setOperand(unsigned i, Value *Val) { + assert(i < Operands.size() && "setOperand() out of range!"); + Operands[i] = Val; + } + inline unsigned getNumOperands() const { return Operands.size(); } + + // --------------------------------------------------------------------------- + // Operand Iterator interface... // - virtual Value *getOperand(unsigned i) = 0; - virtual const Value *getOperand(unsigned i) const = 0; - virtual bool setOperand(unsigned i, Value *Val) = 0; + typedef vector::iterator op_iterator; + typedef vector::const_iterator op_const_iterator; + + inline op_iterator op_begin() { return Operands.begin(); } + inline op_const_iterator op_begin() const { return Operands.end(); } + inline op_iterator op_end() { return Operands.end(); } + inline op_const_iterator op_end() const { return Operands.end(); } // dropAllReferences() - This virtual function should be overridden to "let // go" of all references that this user is maintaining. This allows one to @@ -36,7 +56,9 @@ public: // valid on an object that has "dropped all references", except operator // delete. // - virtual void dropAllReferences() = 0; + virtual void dropAllReferences() { + Operands.clear(); + } // replaceUsesOfWith - Replaces all references to the "From" definition with // references to the "To" definition. (defined in Value.cpp) diff --git a/include/llvm/iMemory.h b/include/llvm/iMemory.h index 077266de94..fafe4c311a 100644 --- a/include/llvm/iMemory.h +++ b/include/llvm/iMemory.h @@ -10,31 +10,24 @@ #include "llvm/Instruction.h" #include "llvm/DerivedTypes.h" -#include "llvm/ConstPoolVals.h" - -class ConstPoolType; class AllocationInst : public Instruction { -protected: - UseTy TyVal; - Use ArraySize; public: - AllocationInst(ConstPoolType *tyVal, Value *arrSize, unsigned iTy, - const string &Name = "") - : Instruction(tyVal->getValue(), iTy, Name), - TyVal(tyVal, this), ArraySize(arrSize, this) { - - // Make sure they didn't try to specify a size for an invalid type... - assert(arrSize == 0 || - (getType()->getValueType()->isArrayType() && - ((const ArrayType*)getType()->getValueType())->isUnsized()) && - "Trying to allocate something other than unsized array, with size!"); - - // Make sure that if a size is specified, that it is a uint! - assert(arrSize == 0 || arrSize->getType() == Type::UIntTy && - "Malloc SIZE is not a 'uint'!"); + AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, + const string &Name = "") + : Instruction(Ty, iTy, Name) { + assert(Ty->isPointerType() && "Can't allocate a non pointer type!"); + + if (ArraySize) { + // Make sure they didn't try to specify a size for !(unsized array) type... + assert((getType()->getValueType()->isArrayType() && + ((const ArrayType*)getType()->getValueType())->isUnsized()) && + "Trying to allocate something other than unsized array, with size!"); + + Operands.reserve(1); + Operands.push_back(Use(ArraySize, this)); + } } - inline ~AllocationInst() {} // getType - Overload to return most specific pointer type... inline const PointerType *getType() const { @@ -42,46 +35,15 @@ public: } virtual Instruction *clone() const = 0; - - inline virtual void dropAllReferences() { TyVal = 0; ArraySize = 0; } - virtual bool setOperand(unsigned i, Value *Val) { - if (i == 0) { - assert(!Val || Val->getValueType() == Value::ConstantVal); - TyVal = (ConstPoolType*)Val; - return true; - } else if (i == 1) { - // Make sure they didn't try to specify a size for an invalid type... - assert(Val == 0 || - (getType()->getValueType()->isArrayType() && - ((const ArrayType*)getType()->getValueType())->isUnsized()) && - "Trying to allocate something other than unsized array, with size!"); - - // Make sure that if a size is specified, that it is a uint! - assert(Val == 0 || Val->getType() == Type::UIntTy && - "Malloc SIZE is not a 'uint'!"); - - ArraySize = Val; - return true; - } - return false; - } - - virtual unsigned getNumOperands() const { return 2; } - - virtual const Value *getOperand(unsigned i) const { - return i == 0 ? TyVal : (i == 1 ? ArraySize : 0); - } }; class MallocInst : public AllocationInst { public: - MallocInst(ConstPoolType *tyVal, Value *ArraySize = 0, - const string &Name = "") - : AllocationInst(tyVal, ArraySize, Instruction::Malloc, Name) {} - inline ~MallocInst() {} + MallocInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") + : AllocationInst(Ty, ArraySize, Instruction::Malloc, Name) {} virtual Instruction *clone() const { - return new MallocInst(TyVal, ArraySize); + return new MallocInst(getType(), Operands.size() ? Operands[1] : 0); } virtual string getOpcode() const { return "malloc"; } @@ -89,13 +51,11 @@ public: class AllocaInst : public AllocationInst { public: - AllocaInst(ConstPoolType *tyVal, Value *ArraySize = 0, - const string &Name = "") - : AllocationInst(tyVal, ArraySize, Instruction::Alloca, Name) {} - inline ~AllocaInst() {} + AllocaInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") + : AllocationInst(Ty, ArraySize, Instruction::Alloca, Name) {} virtual Instruction *clone() const { - return new AllocaInst(TyVal, ArraySize); + return new AllocaInst(getType(), Operands.size() ? Operands[1] : 0); } virtual string getOpcode() const { return "alloca"; } @@ -104,35 +64,16 @@ public: class FreeInst : public Instruction { -protected: - Use Pointer; public: FreeInst(Value *Ptr, const string &Name = "") - : Instruction(Type::VoidTy, Instruction::Free, Name), - Pointer(Ptr, this) { - + : Instruction(Type::VoidTy, Instruction::Free, Name) { assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!"); + Operands.reserve(1); + Operands.push_back(Use(Ptr, this)); } inline ~FreeInst() {} - virtual Instruction *clone() const { return new FreeInst(Pointer); } - - inline virtual void dropAllReferences() { Pointer = 0; } - - virtual bool setOperand(unsigned i, Value *Val) { - if (i == 0) { - assert(!Val || Val->getType()->isPointerType() && - "Can't free nonpointer!"); - Pointer = Val; - return true; - } - return false; - } - - virtual unsigned getNumOperands() const { return 1; } - virtual const Value *getOperand(unsigned i) const { - return i == 0 ? Pointer : 0; - } + virtual Instruction *clone() const { return new FreeInst(Operands[0]); } virtual string getOpcode() const { return "free"; } }; diff --git a/include/llvm/iOther.h b/include/llvm/iOther.h index 23bc5462a8..15c52729b3 100644 --- a/include/llvm/iOther.h +++ b/include/llvm/iOther.h @@ -21,42 +21,31 @@ // scientist's overactive imagination. // class PHINode : public Instruction { - typedef pair PairTy; - vector IncomingValues; - PHINode(const PHINode &PN); public: PHINode(const Type *Ty, const string &Name = ""); inline ~PHINode() { dropAllReferences(); } virtual Instruction *clone() const { return new PHINode(*this); } - - // Implement all of the functionality required by User... - // - virtual void dropAllReferences(); - virtual const Value *getOperand(unsigned i) const { - if (i >= IncomingValues.size()*2) return 0; - if (i & 1) return IncomingValues[i/2].second; - else return IncomingValues[i/2].first; - } - inline Value *getOperand(unsigned i) { - return (Value*)((const PHINode*)this)->getOperand(i); - } - virtual unsigned getNumOperands() const { return IncomingValues.size()*2; } - virtual bool setOperand(unsigned i, Value *Val); virtual string getOpcode() const { return "phi"; } // getNumIncomingValues - Return the number of incoming edges the PHI node has - inline unsigned getNumIncomingValues() const { return IncomingValues.size(); } + inline unsigned getNumIncomingValues() const { return Operands.size()/2; } // getIncomingValue - Return incoming value #x - inline Value *getIncomingValue(unsigned i) const { - return IncomingValues[i].first; + inline const Value *getIncomingValue(unsigned i) const { + return Operands[i*2]; + } + inline Value *getIncomingValue(unsigned i) { + return Operands[i*2]; } // getIncomingBlock - Return incoming basic block #x - inline BasicBlock *getIncomingBlock(unsigned i) const { - return IncomingValues[i].second; + inline const BasicBlock *getIncomingBlock(unsigned i) const { + return Operands[i*2+1]->castBasicBlockAsserting(); + } + inline BasicBlock *getIncomingBlock(unsigned i) { + return Operands[i*2+1]->castBasicBlockAsserting(); } // addIncoming - Add an incoming value to the end of the PHI list @@ -97,8 +86,6 @@ public: //===----------------------------------------------------------------------===// class CallInst : public Instruction { - MethodUse M; - vector Params; CallInst(const CallInst &CI); public: CallInst(Method *M, vector ¶ms, const string &Name = ""); @@ -110,21 +97,12 @@ public: bool hasSideEffects() const { return true; } - const Method *getCalledMethod() const { return M; } - Method *getCalledMethod() { return M; } - - // Implement all of the functionality required by Instruction... - // - virtual void dropAllReferences(); - virtual const Value *getOperand(unsigned i) const { - return i == 0 ? M : ((i <= Params.size()) ? Params[i-1] : 0); + const Method *getCalledMethod() const { + return Operands[0]->castMethodAsserting(); } - inline Value *getOperand(unsigned i) { - return (Value*)((const CallInst*)this)->getOperand(i); + Method *getCalledMethod() { + return Operands[0]->castMethodAsserting(); } - virtual unsigned getNumOperands() const { return Params.size()+1; } - - virtual bool setOperand(unsigned i, Value *Val); }; #endif diff --git a/include/llvm/iTerminators.h b/include/llvm/iTerminators.h index 168d91d027..0d154eab39 100644 --- a/include/llvm/iTerminators.h +++ b/include/llvm/iTerminators.h @@ -24,26 +24,32 @@ // not continue in this method any longer. // class ReturnInst : public TerminatorInst { - Use Val; // Will be null if returning void... - ReturnInst(const ReturnInst &RI); + ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret) { + if (RI.Operands.size()) { + assert(RI.Operands.size() == 1 && "Return insn can only have 1 operand!"); + Operands.reserve(1); + Operands.push_back(Use(RI.Operands[0], this)); + } + } public: - ReturnInst(Value *value = 0); + ReturnInst(Value *RetVal = 0) : TerminatorInst(Instruction::Ret) { + if (RetVal) { + Operands.reserve(1); + Operands.push_back(Use(RetVal, this)); + } + } inline ~ReturnInst() { dropAllReferences(); } virtual Instruction *clone() const { return new ReturnInst(*this); } virtual string getOpcode() const { return "ret"; } - inline const Value *getReturnValue() const { return Val; } - inline Value *getReturnValue() { return Val; } - - virtual void dropAllReferences(); - virtual const Value *getOperand(unsigned i) const { - return (i == 0) ? Val : 0; + inline const Value *getReturnValue() const { + return Operands.size() ? Operands[0] : 0; + } + inline Value *getReturnValue() { + return Operands.size() ? Operands[0] : 0; } - inline Value *getOperand(unsigned i) { return (i == 0) ? Val : 0; } - virtual bool setOperand(unsigned i, Value *Val); - virtual unsigned getNumOperands() const { return Val != 0; } // Additionally, they must provide a method to get at the successors of this // terminator instruction. If 'idx' is out of range, a null pointer shall be @@ -58,9 +64,6 @@ public: // BranchInst - Conditional or Unconditional Branch instruction. // class BranchInst : public TerminatorInst { - BasicBlockUse TrueDest, FalseDest; - Use Condition; - BranchInst(const BranchInst &BI); public: // If cond = null, then is an unconditional br... @@ -69,32 +72,40 @@ public: virtual Instruction *clone() const { return new BranchInst(*this); } - virtual void dropAllReferences(); - - inline const Value *getCondition() const { return Condition; } - inline Value *getCondition() { return Condition; } - inline bool isUnconditional() const { - return Condition == 0 || !FalseDest; + return Operands.size() == 1; + } + + inline const Value *getCondition() const { + return isUnconditional() ? 0 : Operands[2]; + } + inline Value *getCondition() { + return isUnconditional() ? 0 : Operands[2]; } virtual string getOpcode() const { return "br"; } - inline Value *getOperand(unsigned i) { - return (Value*)((const BranchInst *)this)->getOperand(i); + // setUnconditionalDest - Change the current branch to an unconditional branch + // targeting the specified block. + // + void setUnconditionalDest(BasicBlock *Dest) { + if (Operands.size() == 3) + Operands.erase(Operands.begin()+1, Operands.end()); + Operands[0] = Dest; + } + + // Additionally, they must provide a method to get at the successors of this + // terminator instruction. + // + virtual const BasicBlock *getSuccessor(unsigned i) const { + return (i == 0) ? Operands[0]->castBasicBlockAsserting() : + ((i == 1 && Operands.size() > 1) + ? Operands[1]->castBasicBlockAsserting() : 0); } - virtual const Value *getOperand(unsigned i) const; - virtual bool setOperand(unsigned i, Value *Val); - virtual unsigned getNumOperands() const { return isUnconditional() ? 1 : 3; } inline BasicBlock *getSuccessor(unsigned idx) { return (BasicBlock*)((const BranchInst *)this)->getSuccessor(idx); } - // Additionally, they must provide a method to get at the successors of this - // terminator instruction. If 'idx' is out of range, a null pointer shall be - // returned. - // - virtual const BasicBlock *getSuccessor(unsigned idx) const; virtual unsigned getNumSuccessors() const { return 1+!isUnconditional(); } }; @@ -103,17 +114,12 @@ public: // SwitchInst - Multiway switch // class SwitchInst : public TerminatorInst { -public: - typedef pair dest_value; -private: - BasicBlockUse DefaultDest; - Use Val; - vector Destinations; - + // Operand[0] = Value to switch on + // Operand[1] = Default basic block destination SwitchInst(const SwitchInst &RI); public: - typedef vector::iterator dest_iterator; - typedef vector::const_iterator dest_const_iterator; + //typedef vector::iterator dest_iterator; + //typedef vector::const_iterator dest_const_iterator; SwitchInst(Value *Value, BasicBlock *Default); inline ~SwitchInst() { dropAllReferences(); } @@ -122,36 +128,50 @@ public: // Accessor Methods for Switch stmt // + /* inline dest_iterator dest_begin() { return Destinations.begin(); } inline dest_iterator dest_end () { return Destinations.end(); } inline dest_const_iterator dest_begin() const { return Destinations.begin(); } inline dest_const_iterator dest_end () const { return Destinations.end(); } + */ - inline const Value *getCondition() const { return Val; } - inline Value *getCondition() { return Val; } - inline const BasicBlock *getDefaultDest() const { return DefaultDest; } - inline BasicBlock *getDefaultDest() { return DefaultDest; } + inline const Value *getCondition() const { return Operands[0]; } + inline Value *getCondition() { return Operands[0]; } + inline const BasicBlock *getDefaultDest() const { + return Operands[1]->castBasicBlockAsserting(); + } + inline BasicBlock *getDefaultDest() { + return Operands[1]->castBasicBlockAsserting(); + } void dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest); virtual string getOpcode() const { return "switch"; } - inline Value *getOperand(unsigned i) { - return (Value*)((const SwitchInst*)this)->getOperand(i); - } - virtual const Value *getOperand(unsigned i) const; - virtual bool setOperand(unsigned i, Value *Val); - virtual unsigned getNumOperands() const; - virtual void dropAllReferences(); // Additionally, they must provide a method to get at the successors of this // terminator instruction. If 'idx' is out of range, a null pointer shall be // returned. // - virtual const BasicBlock *getSuccessor(unsigned idx) const; - virtual unsigned getNumSuccessors() const { return 1+Destinations.size(); } + virtual const BasicBlock *getSuccessor(unsigned idx) const { + if (idx >= Operands.size()/2) return 0; + return Operands[idx*2+1]->castBasicBlockAsserting(); + } inline BasicBlock *getSuccessor(unsigned idx) { - return (BasicBlock*)((const SwitchInst *)this)->getSuccessor(idx); + if (idx >= Operands.size()/2) return 0; + return Operands[idx*2+1]->castBasicBlockAsserting(); + } + + // getSuccessorValue - Return the value associated with the specified successor + // WARNING: This does not gracefully accept idx's out of range! + inline const ConstPoolVal *getSuccessorValue(unsigned idx) const { + assert(idx < getNumSuccessors() && "Successor # out of range!"); + return Operands[idx*2]->castConstantAsserting(); + } + inline ConstPoolVal *getSuccessorValue(unsigned idx) { + assert(idx < getNumSuccessors() && "Successor # out of range!"); + return Operands[idx*2]->castConstantAsserting(); } + virtual unsigned getNumSuccessors() const { return Operands.size()/2; } }; #endif -- cgit v1.2.3