From c8b25d40cbec063b1ca99cc1adf794399c6d05c0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 7 Jul 2001 08:36:50 +0000 Subject: [PATCH] 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 +++++++++++++--------- lib/Bytecode/Reader/InstructionReader.cpp | 18 +-- lib/Bytecode/Reader/ReaderInternals.h | 7 -- lib/Bytecode/Writer/ConstantWriter.cpp | 2 +- lib/Bytecode/Writer/InstructionWriter.cpp | 36 +++--- lib/Transforms/IPO/InlineSimple.cpp | 9 +- lib/Transforms/Scalar/ConstantProp.cpp | 17 ++- lib/Transforms/Scalar/DCE.cpp | 2 +- lib/Transforms/Scalar/SCCP.cpp | 8 +- lib/VMCore/AsmWriter.cpp | 40 +++---- lib/VMCore/ConstantPool.cpp | 52 +++++---- lib/VMCore/InstrTypes.cpp | 48 ++------ lib/VMCore/Value.cpp | 7 +- lib/VMCore/iBranch.cpp | 61 +++-------- lib/VMCore/iCall.cpp | 37 +++---- lib/VMCore/iReturn.cpp | 22 ---- lib/VMCore/iSwitch.cpp | 74 +++---------- 25 files changed, 309 insertions(+), 648 deletions(-) diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index d7f286ec561..402b1fd0875 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 dbdda62f92d..d21ad8b6da9 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 51dbd646b31..b7aa855b2c2 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 6d35ed5d50f..8ec0da54d2e 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 871ed037ef1..70665232cd5 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 58e0dec22bb..7f2e3e39d8d 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 077266de94c..fafe4c311a1 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 23bc5462a8c..15c52729b33 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 168d91d0270..0d154eab395 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 diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index fd919c92a26..dac7d374158 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -80,8 +80,11 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf, break; } - //cerr << "NO: " << Result.NumOperands << " opcode: " << Result.Opcode - // << " Ty: " << Result.Ty->getName() << " arg1: " << Result.Arg1 << endl; +#if 0 + cerr << "NO: " << Result.NumOperands << " opcode: " << Result.Opcode + << " Ty: " << Result.Ty->getName() << " arg1: " << Result.Arg1 + << " arg2: " << Result.Arg2 << " arg3: " << Result.Arg3 << endl; +#endif return false; } @@ -198,13 +201,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, return false; } else if (Raw.Opcode == Instruction::Malloc) { if (Raw.NumOperands > 2) return true; - Value *Sz = (Raw.NumOperands == 2) ? getValue(Type::UIntTy, Raw.Arg2) : 0; - Res = new MallocInst((ConstPoolType*)getValue(Type::TypeTy, Raw.Arg1), Sz); + Value *Sz = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; + Res = new MallocInst(Raw.Ty, Sz); return false; } else if (Raw.Opcode == Instruction::Alloca) { if (Raw.NumOperands > 2) return true; - Value *Sz = (Raw.NumOperands == 2) ? getValue(Type::UIntTy, Raw.Arg2) : 0; - Res = new AllocaInst((ConstPoolType*)getValue(Type::TypeTy, Raw.Arg1), Sz); + Value *Sz = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0; + Res = new AllocaInst(Raw.Ty, Sz); return false; } else if (Raw.Opcode == Instruction::Free) { Value *Val = getValue(Raw.Ty, Raw.Arg1); @@ -213,6 +216,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, return false; } - cerr << "Unrecognized instruction! " << Raw.Opcode << endl; + cerr << "Unrecognized instruction! " << Raw.Opcode + << " ADDR = 0x" << (void*)Buf << endl; return true; } diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 3bb04726743..fffcdb83c7a 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -94,16 +94,9 @@ public: struct InstPlaceHolderHelper : public Instruction { InstPlaceHolderHelper(const Type *Ty) : Instruction(Ty, UserOp1, "") {} - inline virtual void dropAllReferences() {} virtual string getOpcode() const { return "placeholder"; } virtual Instruction *clone() const { abort(); return 0; } - - // No "operands"... - 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 unsigned getNumOperands() const { return 0; } }; struct BBPlaceHolderHelper : public BasicBlock { diff --git a/lib/Bytecode/Writer/ConstantWriter.cpp b/lib/Bytecode/Writer/ConstantWriter.cpp index e65ea450674..5ca0fca0d12 100644 --- a/lib/Bytecode/Writer/ConstantWriter.cpp +++ b/lib/Bytecode/Writer/ConstantWriter.cpp @@ -128,7 +128,7 @@ bool BytecodeWriter::outputConstant(const ConstPoolVal *CPV) { case Type::StructTyID: { const ConstPoolStruct *CPS = (const ConstPoolStruct*)CPV; - const vector &Vals = CPS->getValues(); + const vector &Vals = CPS->getValues(); for (unsigned i = 0; i < Vals.size(); ++i) { int Slot = Table.getValSlot(Vals[i]); diff --git a/lib/Bytecode/Writer/InstructionWriter.cpp b/lib/Bytecode/Writer/InstructionWriter.cpp index c7c04efb731..0cd93c04fdb 100644 --- a/lib/Bytecode/Writer/InstructionWriter.cpp +++ b/lib/Bytecode/Writer/InstructionWriter.cpp @@ -32,14 +32,13 @@ static void outputInstructionFormat0(const Instruction *I, output_vbr(I->getInstType(), Out); // Instruction Opcode ID output_vbr(Type, Out); // Result type - unsigned NumArgs; // Count the number of arguments to the instruction - for (NumArgs = 0; I->getOperand(NumArgs); NumArgs++) /*empty*/; + unsigned NumArgs = I->getNumOperands(); output_vbr(NumArgs, Out); - for (unsigned i = 0; const Value *N = I->getOperand(i); i++) { - assert(i < NumArgs && "Count of arguments failed!"); - + for (unsigned i = 0; i < NumArgs; ++i) { + const Value *N = I->getOperand(i); int Slot = Table.getValSlot(N); + assert(Slot >= 0 && "No slot number for value!?!?"); output_vbr((unsigned)Slot, Out); } align32(Out); // We must maintain correct alignment! @@ -110,25 +109,24 @@ static void outputInstructionFormat3(const Instruction *I, // unsigned Opcode = (3 << 30) | (IType << 24) | (Type << 18) | (Slots[0] << 12) | (Slots[1] << 6) | (Slots[2] << 0); - // cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " - // << Slots[1] << " " << Slots[2] << endl; + //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " + // << Slots[1] << " " << Slots[2] << endl; output(Opcode, Out); } bool BytecodeWriter::processInstruction(const Instruction *I) { assert(I->getInstType() < 64 && "Opcode too big???"); - unsigned NumOperands = 0; + unsigned NumOperands = I->getNumOperands(); int MaxOpSlot = 0; - int Slots[3]; Slots[0] = (1 << 12)-1; + int Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands - const Value *Def; - while ((Def = I->getOperand(NumOperands))) { + for (unsigned i = 0; i < NumOperands; ++i) { + const Value *Def = I->getOperand(i); int slot = Table.getValSlot(Def); assert(slot != -1 && "Broken bytecode!"); if (slot > MaxOpSlot) MaxOpSlot = slot; - if (NumOperands < 3) Slots[NumOperands] = slot; - NumOperands++; + if (i < 3) Slots[i] = slot; } // Figure out which type to encode with the instruction. Typically we want @@ -137,12 +135,10 @@ bool BytecodeWriter::processInstruction(const Instruction *I) { // the first param is actually interesting). But if we have no arguments // we take the type of the instruction itself. // - - const Type *Ty; - if (NumOperands) - Ty = I->getOperand(0)->getType(); - else - Ty = I->getType(); + const Type *Ty = NumOperands ? I->getOperand(0)->getType() : I->getType(); + if (I->getInstType() == Instruction::Malloc || + I->getInstType() == Instruction::Alloca) + Ty = I->getType(); // Malloc & Alloca ALWAYS want to encode the return type unsigned Type; int Slot = Table.getValSlot(Ty); @@ -179,6 +175,8 @@ bool BytecodeWriter::processInstruction(const Instruction *I) { break; } + // If we weren't handled before here, we either have a large number of operands + // or a large operand index that we are refering to. outputInstructionFormat0(I, Table, Type, Out); return false; } diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index d85b33dffd1..de76dcd52dc 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -37,7 +37,8 @@ using namespace opt; static inline void RemapInstruction(Instruction *I, map &ValueMap) { - for (unsigned op = 0; const Value *Op = I->getOperand(op); ++op) { + for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) { + const Value *Op = I->getOperand(op); Value *V = ValueMap[Op]; if (!V && Op->isMethod()) continue; // Methods don't get relocated @@ -115,11 +116,9 @@ bool opt::InlineMethod(BasicBlock::iterator CIIt) { // Method::ArgumentListType::const_iterator PTI = CalledMeth->getArgumentList().begin(); - for (unsigned a = 1; Value *Operand = CI->getOperand(a); ++a, ++PTI) { - ValueMap[*PTI] = Operand; - } + for (unsigned a = 1, E = CI->getNumOperands(); a != E; ++a, ++PTI) + ValueMap[*PTI] = CI->getOperand(a); - ValueMap[NewBB] = NewBB; // Returns get converted to reference NewBB // Loop over all of the basic blocks in the method, inlining them as diff --git a/lib/Transforms/Scalar/ConstantProp.cpp b/lib/Transforms/Scalar/ConstantProp.cpp index 7a0254bca7a..91a21c3c6b4 100644 --- a/lib/Transforms/Scalar/ConstantProp.cpp +++ b/lib/Transforms/Scalar/ConstantProp.cpp @@ -132,9 +132,9 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) { BasicBlock *Dest1 = BI->getOperand(0)->castBasicBlockAsserting(); BasicBlock *Dest2 = BI->getOperand(1)->castBasicBlockAsserting(); - if (BI->getOperand(2)->isConstant()) { // Are we branching on constant? + if (BI->getCondition()->isConstant()) { // Are we branching on constant? // YES. Change to unconditional branch... - ConstPoolBool *Cond = (ConstPoolBool*)BI->getOperand(2); + ConstPoolBool *Cond = (ConstPoolBool*)BI->getCondition(); BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2; BasicBlock *OldDest = Cond->getValue() ? Dest2 : Dest1; @@ -147,9 +147,9 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) { assert(BI->getParent() && "Terminator not inserted in block!"); OldDest->removePredecessor(BI->getParent()); - BI->setOperand(0, Destination); // Set the unconditional destination - BI->setOperand(1, 0); // Clear the conditional destination - BI->setOperand(2, 0); // Clear the condition... + // Set the unconditional destination, and change the insn to be an + // unconditional branch. + BI->setUnconditionalDest(Destination); return true; } else if (Dest2 == Dest1) { // Conditional branch to same location? // This branch matches something like this: @@ -160,9 +160,8 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) { assert(BI->getParent() && "Terminator not inserted in block!"); Dest1->removePredecessor(BI->getParent()); - // Nuke the second destination, and the use of the condition variable - BI->setOperand(1, 0); // Clear the conditional destination - BI->setOperand(2, 0); // Clear the condition... + // Change a conditional branch to unconditional. + BI->setUnconditionalDest(Dest1); return true; } } @@ -192,7 +191,7 @@ ConstantFoldInstruction(Method *M, Method::inst_iterator &II) { PHINode *PN = (PHINode*)Inst; // If it's a PHI node and only has one operand // Then replace it directly with that operand. assert(PN->getOperand(0) && "PHI Node must have at least one operand!"); - if (PN->getOperand(1) == 0) { // If the PHI Node has exactly 1 operand + if (PN->getNumOperands() == 1) { // If the PHI Node has exactly 1 operand Value *V = PN->getOperand(0); PN->replaceAllUsesWith(V); // Replace all uses of this PHI // Unlink from basic block diff --git a/lib/Transforms/Scalar/DCE.cpp b/lib/Transforms/Scalar/DCE.cpp index 8e37279178d..fa2c9c72215 100644 --- a/lib/Transforms/Scalar/DCE.cpp +++ b/lib/Transforms/Scalar/DCE.cpp @@ -91,7 +91,7 @@ static bool RemoveSingularPHIs(BasicBlock *BB) { do { PHINode *PN = (PHINode*)I; - assert(PN->getOperand(2) == 0 && "PHI node should only have one value!"); + assert(PN->getNumOperands() == 2 && "PHI node should only have one value!"); Value *V = PN->getOperand(0); PN->replaceAllUsesWith(V); // Replace PHI node with its single value. diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 8b59e19c1c7..5bb75c7008a 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -408,10 +408,10 @@ void SCCP::UpdateInstruction(Instruction *I) { markExecutable(Succ); } else if (SCValue.isConstant()) { ConstPoolVal *CPV = SCValue.getConstant(); - for (SwitchInst::dest_iterator I = SI->dest_begin(), E = SI->dest_end(); - I != E; ++I) { - if (I->first->equals(CPV)) { // Found the right branch... - markExecutable(I->second); + // Make sure to skip the "default value" which isn't a value + for (unsigned i = 1, E = SI->getNumSuccessors(); i != E; ++i) { + if (SI->getSuccessorValue(i)->equals(CPV)) {// Found the right branch... + markExecutable(SI->getSuccessor(i)); return; } } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index c68cd796f1a..e2b24956058 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -157,10 +157,10 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { Out << I->getOpcode(); // Print out the type of the operands... - const Value *Operand = I->getOperand(0); + const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0; // Special case conditional branches to swizzle the condition out to the front - if (I->getInstType() == Instruction::Br && I->getOperand(1)) { + if (I->getInstType() == Instruction::Br && I->getNumOperands() > 1) { writeOperand(I->getOperand(2), true); Out << ","; writeOperand(Operand, true); @@ -172,9 +172,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { writeOperand(Operand , true); Out << ","; writeOperand(I->getOperand(1), true); Out << " ["; - for (unsigned op = 2; (Operand = I->getOperand(op)); op += 2) { + for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { Out << "\n\t\t"; - writeOperand(Operand, true); Out << ","; + writeOperand(I->getOperand(op ), true); Out << ","; writeOperand(I->getOperand(op+1), true); } Out << "\n\t]"; @@ -183,8 +183,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { Out << " ["; writeOperand(Operand, false); Out << ","; writeOperand(I->getOperand(1), false); Out << " ]"; - for (unsigned op = 2; (Operand = I->getOperand(op)); op += 2) { - Out << ", ["; writeOperand(Operand, false); Out << ","; + for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { + Out << ", ["; + writeOperand(I->getOperand(op ), false); Out << ","; writeOperand(I->getOperand(op+1), false); Out << " ]"; } } else if (I->getInstType() == Instruction::Ret && !Operand) { @@ -192,20 +193,19 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { } else if (I->getInstType() == Instruction::Call) { writeOperand(Operand, true); Out << "("; - Operand = I->getOperand(1); - if (Operand) writeOperand(Operand, true); - for (unsigned op = 2; (Operand = I->getOperand(op)); ++op) { + if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true); + for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) { Out << ","; - writeOperand(Operand, true); + writeOperand(I->getOperand(op), true); } Out << " )"; } else if (I->getInstType() == Instruction::Malloc || I->getInstType() == Instruction::Alloca) { - Out << " " << ((const PointerType*)((ConstPoolType*)Operand) - ->getValue())->getValueType(); - if ((Operand = I->getOperand(1))) { - Out << ","; writeOperand(Operand, true); + Out << " " << ((const PointerType*)I->getType())->getValueType(); + if (I->getNumOperands()) { + Out << ","; + writeOperand(I->getOperand(0), true); } } else if (Operand) { // Print the normal way... @@ -215,9 +215,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { // different type operands (for example br), then they are all printed. bool PrintAllTypes = false; const Type *TheType = Operand->getType(); - unsigned i; - for (i = 1; (Operand = I->getOperand(i)); i++) { + for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) { + Operand = I->getOperand(i); if (Operand->getType() != TheType) { PrintAllTypes = true; // We have differing types! Print them all! break; @@ -227,9 +227,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) { if (!PrintAllTypes) Out << " " << I->getOperand(0)->getType(); - for (unsigned i = 0; (Operand = I->getOperand(i)); i++) { + for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) { if (i) Out << ","; - writeOperand(Operand, PrintAllTypes); + writeOperand(I->getOperand(i), PrintAllTypes); } } @@ -262,8 +262,8 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, } else { int Slot = Table.getValSlot(Operand); - if (Operand->isConstant()) { - Out << " " << ((ConstPoolVal*)Operand)->getStrValue(); + if (const ConstPoolVal *CPV = Operand->castConstant()) { + Out << " " << CPV->getStrValue(); } else { if (Slot >= 0) Out << " %" << Slot; else if (PrintName) diff --git a/lib/VMCore/ConstantPool.cpp b/lib/VMCore/ConstantPool.cpp index 77ed50ae26d..13463a17344 100644 --- a/lib/VMCore/ConstantPool.cpp +++ b/lib/VMCore/ConstantPool.cpp @@ -219,7 +219,7 @@ ConstPoolArray::ConstPoolArray(const ArrayType *T, : ConstPoolVal(T, Name) { for (unsigned i = 0; i < V.size(); i++) { assert(V[i]->getType() == T->getElementType()); - Val.push_back(ConstPoolUse(V[i], this)); + Operands.push_back(Use(V[i], this)); } } @@ -231,7 +231,7 @@ ConstPoolStruct::ConstPoolStruct(const StructType *T, for (unsigned i = 0; i < V.size(); i++) { assert(V[i]->getType() == ETypes[i]); - Val.push_back(ConstPoolUse(V[i], this)); + Operands.push_back(Use(V[i], this)); } } @@ -265,14 +265,14 @@ ConstPoolType::ConstPoolType(const ConstPoolType &CPT) ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA) : ConstPoolVal(CPA.getType()) { - for (unsigned i = 0; i < CPA.Val.size(); i++) - Val.push_back(ConstPoolUse((ConstPoolVal*)CPA.Val[i], this)); + for (unsigned i = 0; i < CPA.Operands.size(); i++) + Operands.push_back(Use(CPA.Operands[i], this)); } ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS) : ConstPoolVal(CPS.getType()) { - for (unsigned i = 0; i < CPS.Val.size(); i++) - Val.push_back(ConstPoolUse((ConstPoolVal*)CPS.Val[i], this)); + for (unsigned i = 0; i < CPS.Operands.size(); i++) + Operands.push_back(Use(CPS.Operands[i], this)); } //===----------------------------------------------------------------------===// @@ -301,12 +301,12 @@ string ConstPoolType::getStrValue() const { string ConstPoolArray::getStrValue() const { string Result = "["; - if (Val.size()) { - Result += " " + Val[0]->getType()->getName() + - " " + Val[0]->getStrValue(); - for (unsigned i = 1; i < Val.size(); i++) - Result += ", " + Val[i]->getType()->getName() + - " " + Val[i]->getStrValue(); + if (Operands.size()) { + Result += " " + Operands[0]->getType()->getName() + + " " + Operands[0]->castConstantAsserting()->getStrValue(); + for (unsigned i = 1; i < Operands.size(); i++) + Result += ", " + Operands[i]->getType()->getName() + + " " + Operands[i]->castConstantAsserting()->getStrValue(); } return Result + " ]"; @@ -314,12 +314,12 @@ string ConstPoolArray::getStrValue() const { string ConstPoolStruct::getStrValue() const { string Result = "{"; - if (Val.size()) { - Result += " " + Val[0]->getType()->getName() + - " " + Val[0]->getStrValue(); - for (unsigned i = 1; i < Val.size(); i++) - Result += ", " + Val[i]->getType()->getName() + - " " + Val[i]->getStrValue(); + if (Operands.size()) { + Result += " " + Operands[0]->getType()->getName() + + " " + Operands[0]->castConstantAsserting()->getStrValue(); + for (unsigned i = 1; i < Operands.size(); i++) + Result += ", " + Operands[i]->getType()->getName() + + " " + Operands[i]->castConstantAsserting()->getStrValue(); } return Result + " }"; @@ -356,9 +356,11 @@ bool ConstPoolType::equals(const ConstPoolVal *V) const { bool ConstPoolArray::equals(const ConstPoolVal *V) const { assert(getType() == V->getType()); ConstPoolArray *AV = (ConstPoolArray*)V; - if (Val.size() != AV->Val.size()) return false; - for (unsigned i = 0; i < Val.size(); i++) - if (!Val[i]->equals(AV->Val[i])) return false; + if (Operands.size() != AV->Operands.size()) return false; + for (unsigned i = 0; i < Operands.size(); i++) + if (!Operands[i]->castConstantAsserting()->equals( + AV->Operands[i]->castConstantAsserting())) + return false; return true; } @@ -366,9 +368,11 @@ bool ConstPoolArray::equals(const ConstPoolVal *V) const { bool ConstPoolStruct::equals(const ConstPoolVal *V) const { assert(getType() == V->getType()); ConstPoolStruct *SV = (ConstPoolStruct*)V; - if (Val.size() != SV->Val.size()) return false; - for (unsigned i = 0; i < Val.size(); i++) - if (!Val[i]->equals(SV->Val[i])) return false; + if (Operands.size() != SV->Operands.size()) return false; + for (unsigned i = 0; i < Operands.size(); i++) + if (!Operands[i]->castConstantAsserting()->equals( + SV->Operands[i]->castConstantAsserting())) + return false; return true; } diff --git a/lib/VMCore/InstrTypes.cpp b/lib/VMCore/InstrTypes.cpp index baafe0bc131..cda99a9446a 100644 --- a/lib/VMCore/InstrTypes.cpp +++ b/lib/VMCore/InstrTypes.cpp @@ -9,7 +9,7 @@ #include "llvm/Method.h" #include "llvm/SymbolTable.h" #include "llvm/Type.h" -#include +#include // find // TODO: Move to getUnaryOperator iUnary.cpp when and if it exists! UnaryOperator *UnaryOperator::create(unsigned Op, Value *Source) { @@ -52,49 +52,25 @@ PHINode::PHINode(const Type *Ty, const string &name) PHINode::PHINode(const PHINode &PN) : Instruction(PN.getType(), Instruction::PHINode) { - - for (unsigned i = 0; i < PN.IncomingValues.size(); i++) - IncomingValues.push_back( - make_pair(Use(PN.IncomingValues[i].first, this), - BasicBlockUse(PN.IncomingValues[i].second, this))); -} - -void PHINode::dropAllReferences() { - IncomingValues.clear(); -} - -bool PHINode::setOperand(unsigned i, Value *Val) { - assert(Val && "PHI node must only reference nonnull definitions!"); - if (i >= IncomingValues.size()*2) return false; - - if (i & 1) { - IncomingValues[i/2].second = Val->castBasicBlockAsserting(); - } else { - IncomingValues[i/2].first = Val; + Operands.reserve(PN.Operands.size()); + for (unsigned i = 0; i < PN.Operands.size(); i+=2) { + Operands.push_back(Use(PN.Operands[i], this)); + Operands.push_back(Use(PN.Operands[i+1], this)); } - return true; } void PHINode::addIncoming(Value *D, BasicBlock *BB) { - IncomingValues.push_back(make_pair(Use(D, this), BasicBlockUse(BB, this))); + Operands.push_back(Use(D, this)); + Operands.push_back(Use(BB, this)); } -struct FindBBEntry { - const BasicBlock *BB; - inline FindBBEntry(const BasicBlock *bb) : BB(bb) {} - inline bool operator()(const pair &Entry) { - return Entry.second == BB; - } -}; - - // removeIncomingValue - Remove an incoming value. This is useful if a // predecessor basic block is deleted. Value *PHINode::removeIncomingValue(const BasicBlock *BB) { - vector::iterator Idx = find_if(IncomingValues.begin(), - IncomingValues.end(), FindBBEntry(BB)); - assert(Idx != IncomingValues.end() && "BB not in PHI node!"); - Value *Removed = Idx->first; - IncomingValues.erase(Idx); + op_iterator Idx = find(Operands.begin(), Operands.end(), (const Value*)BB); + assert(Idx != Operands.end() && "BB not in PHI node!"); + --Idx; // Back up to value prior to Basic block + Value *Removed = *Idx; + Operands.erase(Idx, Idx+2); // Erase Value and BasicBlock return Removed; } diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index fa3c0f60fb4..a051bcb3cc6 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -89,14 +89,13 @@ User::User(const Type *Ty, ValueTy vty, const string &name) void User::replaceUsesOfWith(Value *From, Value *To) { if (From == To) return; // Duh what? - for (unsigned OpNum = 0; Value *D = getOperand(OpNum); ++OpNum) { - if (D == From) { // Okay, this operand is pointing to our fake def. + for (unsigned i = 0, E = getNumOperands(); i != E; ++i) + if (getOperand(i) == From) { // Is This operand is pointing to oldval? // The side effects of this setOperand call include linking to // "To", adding "this" to the uses list of To, and // most importantly, removing "this" from the use list of "From". - setOperand(OpNum, To); // Fix it now... + setOperand(i, To); // Fix it now... } - } } diff --git a/lib/VMCore/iBranch.cpp b/lib/VMCore/iBranch.cpp index 05f35059a54..d0f437e293b 100644 --- a/lib/VMCore/iBranch.cpp +++ b/lib/VMCore/iBranch.cpp @@ -13,9 +13,17 @@ #endif BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond) - : TerminatorInst(Instruction::Br), TrueDest(True, this), - FalseDest(False, this), Condition(Cond, this) { + : TerminatorInst(Instruction::Br) { assert(True != 0 && "True branch destination may not be null!!!"); + Operands.reserve(False ? 3 : 1); + Operands.push_back(Use(True, this)); + if (False) { + Operands.push_back(Use(False, this)); + Operands.push_back(Use(Cond, this)); + } + + assert(!!False == !!Cond && + "Either both cond and false or neither can be specified!"); #ifndef NDEBUG if (Cond != 0 && Cond->getType() != Type::BoolTy) @@ -25,45 +33,12 @@ BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond) "May only branch on boolean predicates!!!!"); } -BranchInst::BranchInst(const BranchInst &BI) - : TerminatorInst(Instruction::Br), TrueDest(BI.TrueDest, this), - FalseDest(BI.FalseDest, this), Condition(BI.Condition, this) { -} - - -void BranchInst::dropAllReferences() { - Condition = 0; - TrueDest = FalseDest = 0; -} - -const Value *BranchInst::getOperand(unsigned i) const { - return (i == 0) ? (Value*)TrueDest : - ((i == 1) ? (Value*)FalseDest : - ((i == 2) ? (Value*)Condition : 0)); -} - -const BasicBlock *BranchInst::getSuccessor(unsigned i) const { - return (i == 0) ? (const BasicBlock*)TrueDest : - ((i == 1) ? (const BasicBlock*)FalseDest : 0); -} - -bool BranchInst::setOperand(unsigned i, Value *Val) { - switch (i) { - case 0: - assert(Val && "Can't change primary direction to 0!"); - assert(Val->getType() == Type::LabelTy); - TrueDest = (BasicBlock*)Val; - return true; - case 1: - assert(Val == 0 || Val->getType() == Type::LabelTy); - FalseDest = (BasicBlock*)Val; - return true; - case 2: - Condition = Val; - assert(!Condition || Condition->getType() == Type::BoolTy && - "Condition expr must be a boolean expression!"); - return true; - } - - return false; +BranchInst::BranchInst(const BranchInst &BI) : TerminatorInst(Instruction::Br) { + Operands.reserve(BI.Operands.size()); + Operands.push_back(Use(BI.Operands[0], this)); + if (BI.Operands.size() != 1) { + assert(BI.Operands.size() == 3 && "BR can have 1 or 3 operands!"); + Operands.push_back(Use(BI.Operands[1], this)); + Operands.push_back(Use(BI.Operands[2], this)); + } } diff --git a/lib/VMCore/iCall.cpp b/lib/VMCore/iCall.cpp index 7632798c66a..67826ff4bcb 100644 --- a/lib/VMCore/iCall.cpp +++ b/lib/VMCore/iCall.cpp @@ -1,6 +1,6 @@ -//===-- iCall.cpp - Implement the Call & Invoke instructions -----*- C++ -*--=// +//===-- iCall.cpp - Implement the call & icall instructions ------*- C++ -*--=// // -// This file implements the call and invoke instructions. +// This file implements the call and icall instructions. // //===----------------------------------------------------------------------===// @@ -8,9 +8,12 @@ #include "llvm/DerivedTypes.h" #include "llvm/Method.h" -CallInst::CallInst(Method *m, vector ¶ms, +CallInst::CallInst(Method *M, vector ¶ms, const string &Name) - : Instruction(m->getReturnType(), Instruction::Call, Name), M(m, this) { + : Instruction(M->getReturnType(), Instruction::Call, Name) { + + Operands.reserve(1+params.size()); + Operands.push_back(Use(M, this)); const MethodType* MT = M->getMethodType(); const MethodType::ParamTypes &PL = MT->getParamTypes(); @@ -19,29 +22,15 @@ CallInst::CallInst(Method *m, vector ¶ms, MethodType::ParamTypes::const_iterator It = PL.begin(); #endif for (unsigned i = 0; i < params.size(); i++) { - assert(*It++ == params[i]->getType()); - Params.push_back(Use(params[i], this)); + assert(*It++ == params[i]->getType() && "Call Operands not correct type!"); + Operands.push_back(Use(params[i], this)); } } CallInst::CallInst(const CallInst &CI) - : Instruction(CI.getType(), Instruction::Call), M(CI.M, this) { - for (unsigned i = 0; i < CI.Params.size(); i++) - Params.push_back(Use(CI.Params[i], this)); -} - -void CallInst::dropAllReferences() { - M = 0; - Params.clear(); + : Instruction(CI.getType(), Instruction::Call) { + Operands.reserve(CI.Operands.size()); + for (unsigned i = 0; i < CI.Operands.size(); ++i) + Operands.push_back(Use(CI.Operands[i], this)); } -bool CallInst::setOperand(unsigned i, Value *Val) { - if (i > Params.size()) return false; - if (i == 0) { - M = Val->castMethodAsserting(); - } else { - // TODO: assert = method arg type - Params[i-1] = Val; - } - return true; -} diff --git a/lib/VMCore/iReturn.cpp b/lib/VMCore/iReturn.cpp index 7fa04fb42c6..b28b04f6431 100644 --- a/lib/VMCore/iReturn.cpp +++ b/lib/VMCore/iReturn.cpp @@ -1,25 +1,3 @@ -//===-- iReturn.cpp - Implement the Return instruction -----------*- C++ -*--=// -// -// This file implements the Return instruction... -// -//===----------------------------------------------------------------------===// -#include "llvm/iTerminators.h" -ReturnInst::ReturnInst(Value *V) - : TerminatorInst(Instruction::Ret), Val(V, this) { -} -ReturnInst::ReturnInst(const ReturnInst &RI) - : TerminatorInst(Instruction::Ret), Val(RI.Val, this) { -} - -void ReturnInst::dropAllReferences() { - Val = 0; -} - -bool ReturnInst::setOperand(unsigned i, Value *V) { - if (i) return false; - Val = V; - return true; -} diff --git a/lib/VMCore/iSwitch.cpp b/lib/VMCore/iSwitch.cpp index 2a1eec26391..e5e3c50cfd5 100644 --- a/lib/VMCore/iSwitch.cpp +++ b/lib/VMCore/iSwitch.cpp @@ -10,72 +10,24 @@ #include "llvm/Type.h" #endif -SwitchInst::SwitchInst(Value *V, BasicBlock *DefV) - : TerminatorInst(Instruction::Switch), - DefaultDest(DefV, this), Val(V, this) { - assert(Val && DefV); +SwitchInst::SwitchInst(Value *V, BasicBlock *DefDest) + : TerminatorInst(Instruction::Switch) { + assert(V && DefDest); + Operands.push_back(Use(V, this)); + Operands.push_back(Use(DefDest, this)); } SwitchInst::SwitchInst(const SwitchInst &SI) - : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest), - Val(SI.Val) { + : TerminatorInst(Instruction::Switch) { + Operands.reserve(SI.Operands.size()); - for (dest_const_iterator I = SI.Destinations.begin(), - end = SI.Destinations.end(); I != end; ++I) - Destinations.push_back(dest_value(ConstPoolUse(I->first, this), - BasicBlockUse(I->second, this))); + for (unsigned i = 0, E = SI.Operands.size(); i != E; i+=2) { + Operands.push_back(Use(SI.Operands[i], this)); + Operands.push_back(Use(SI.Operands[i+1], this)); + } } - void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) { - Destinations.push_back(dest_value(ConstPoolUse(OnVal, this), - BasicBlockUse(Dest, this))); -} - -void SwitchInst::dropAllReferences() { - Val = 0; - DefaultDest = 0; - Destinations.clear(); -} - -const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const { - if (idx == 0) return DefaultDest; - if (idx > Destinations.size()) return 0; - return Destinations[idx-1].second; -} - -unsigned SwitchInst::getNumOperands() const { - return 2+Destinations.size(); -} - -const Value *SwitchInst::getOperand(unsigned i) const { - if (i == 0) return Val; - else if (i == 1) return DefaultDest; - - unsigned slot = (i-2) >> 1; - if (slot >= Destinations.size()) return 0; - - if (i & 1) return Destinations[slot].second; - return Destinations[slot].first; -} - -bool SwitchInst::setOperand(unsigned i, Value *V) { - if (i == 0) { Val = V; return true; } - else if (i == 1) { - assert(V->getType() == Type::LabelTy); - DefaultDest = (BasicBlock*)V; - return true; - } - - unsigned slot = (i-2) >> 1; - if (slot >= Destinations.size()) return 0; - - if (i & 1) { - assert(V->getType() == Type::LabelTy); - Destinations[slot].second = (BasicBlock*)V; - } else { - // TODO: assert constant - Destinations[slot].first = (ConstPoolVal*)V; - } - return true; + Operands.push_back(Use(OnVal, this)); + Operands.push_back(Use(Dest, this)); } -- 2.34.1