X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FInstructions.h;h=146d1f50a645d0aede3f2ff7e934766f01a0e15a;hb=7adb53e7b1a4ec0cda17cbc946da44147c141d69;hp=99ed63ba6d378bdc9a434ffa02ca4ff6a2854133;hpb=fb11053815ee4b3c6593c12aff06fefea96d7d0a;p=oota-llvm.git diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 99ed63ba6d3..146d1f50a64 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -23,7 +23,10 @@ namespace llvm { class BasicBlock; class ConstantInt; class PointerType; -class PackedType; +class VectorType; +class ConstantRange; +class APInt; +class ParamAttrsList; //===----------------------------------------------------------------------===// // AllocationInst Class @@ -189,8 +192,6 @@ public: virtual FreeInst *clone() const; - virtual bool mayWriteToMemory() const { return true; } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const FreeInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -210,9 +211,11 @@ public: /// SubclassData field in Value to store whether or not the load is volatile. /// class LoadInst : public UnaryInstruction { + LoadInst(const LoadInst &LI) : UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) { setVolatile(LI.isVolatile()); + setAlignment(LI.getAlignment()); #ifndef NDEBUG AssertOK(); @@ -222,23 +225,40 @@ class LoadInst : public UnaryInstruction { public: LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore); LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd); - explicit LoadInst(Value *Ptr, const std::string &Name = "", - bool isVolatile = false, Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false, + Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align, + Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, BasicBlock *InsertAtEnd); + LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore); + LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd); + explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false, + Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const char *Name, bool isVolatile, + BasicBlock *InsertAtEnd); + /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return SubclassData; } + bool isVolatile() const { return SubclassData & 1; } /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { SubclassData = V; } + void setVolatile(bool V) { + SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0); + } virtual LoadInst *clone() const; - virtual bool mayWriteToMemory() const { return isVolatile(); } + /// getAlignment - Return the alignment of the access that is being performed + /// + unsigned getAlignment() const { + return (1 << (SubclassData>>1)) >> 1; + } + + void setAlignment(unsigned Align); Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } @@ -263,10 +283,13 @@ public: /// class StoreInst : public Instruction { Use Ops[2]; + StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) { Ops[0].init(SI.Ops[0], this); Ops[1].init(SI.Ops[1], this); setVolatile(SI.isVolatile()); + setAlignment(SI.getAlignment()); + #ifndef NDEBUG AssertOK(); #endif @@ -277,17 +300,21 @@ public: StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, Instruction *InsertBefore = 0); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, + unsigned Align, Instruction *InsertBefore = 0); StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); /// isVolatile - Return true if this is a load from a volatile memory /// location. /// - bool isVolatile() const { return SubclassData; } + bool isVolatile() const { return SubclassData & 1; } /// setVolatile - Specify whether this is a volatile load or not. /// - void setVolatile(bool V) { SubclassData = V; } + void setVolatile(bool V) { + SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0); + } /// Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { @@ -300,11 +327,16 @@ public: } unsigned getNumOperands() const { return 2; } - + /// getAlignment - Return the alignment of the access that is being performed + /// + unsigned getAlignment() const { + return (1 << (SubclassData>>1)) >> 1; + } + + void setAlignment(unsigned Align); + virtual StoreInst *clone() const; - virtual bool mayWriteToMemory() const { return true; } - Value *getPointerOperand() { return getOperand(1); } const Value *getPointerOperand() const { return getOperand(1); } static unsigned getPointerOperandIndex() { return 1U; } @@ -336,7 +368,7 @@ class GetElementPtrInst : public Instruction { for (unsigned i = 0, E = NumOperands; i != E; ++i) OL[i].init(GEPIOL[i], this); } - void init(Value *Ptr, const std::vector &Idx); + void init(Value *Ptr, Value* const *Idx, unsigned NumIdx); void init(Value *Ptr, Value *Idx0, Value *Idx1); void init(Value *Ptr, Value *Idx); public: @@ -344,10 +376,6 @@ public: /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. - GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name = "", Instruction *InsertBefore =0); - GetElementPtrInst(Value *Ptr, const std::vector &Idx, - const std::string &Name, BasicBlock *InsertAtEnd); GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx, const std::string &Name = "", Instruction *InsertBefore =0); GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx, @@ -382,11 +410,6 @@ public: Value* const *Idx, unsigned NumIdx, bool AllowStructLeaf = false); - static const Type *getIndexedType(const Type *Ptr, - const std::vector &Indices, - bool AllowStructLeaf = false) { - return getIndexedType(Ptr, &Indices[0], Indices.size(), AllowStructLeaf); - } static const Type *getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1, bool AllowStructLeaf = false); static const Type *getIndexedType(const Type *Ptr, Value *Idx); @@ -413,6 +436,17 @@ public: inline bool hasIndices() const { return getNumOperands() > 1; } + + /// hasAllZeroIndices - Return true if all of the indices of this GEP are + /// zeros. If so, the result pointer and the first operand have the same + /// value, just potentially different types. + bool hasAllZeroIndices() const; + + /// hasAllConstantIndices - Return true if all of the indices of this GEP are + /// constant integers. If so, the result pointer and the first operand have + /// a constant offset between them. + bool hasAllConstantIndices() const; + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GetElementPtrInst *) { return true; } @@ -544,6 +578,10 @@ public: /// @brief Determine if the predicate is signed. static bool isSignedPredicate(Predicate pred); + /// Initialize a set of values that all satisfy the predicate with C. + /// @brief Make a ConstantRange for a relation with a constant value. + static ConstantRange makeConstantRange(Predicate pred, const APInt &C); + /// Exchange the two operands to this instruction in such a way that it does /// not modify the semantics of the instruction. The predicate value may be /// changed to retain the same result if the predicate is order dependent @@ -696,18 +734,19 @@ public: /// hold the calling convention of the call. /// class CallInst : public Instruction { + ParamAttrsList *ParamAttrs; ///< parameter attributes for call CallInst(const CallInst &CI); - void init(Value *Func, const std::vector &Params); + void init(Value *Func, Value* const *Params, unsigned NumParams); void init(Value *Func, Value *Actual1, Value *Actual2); void init(Value *Func, Value *Actual); void init(Value *Func); public: - CallInst(Value *F, const std::vector &Par, + CallInst(Value *F, Value* const *Args, unsigned NumArgs, const std::string &Name = "", Instruction *InsertBefore = 0); - CallInst(Value *F, const std::vector &Par, + CallInst(Value *F, Value *const *Args, unsigned NumArgs, const std::string &Name, BasicBlock *InsertAtEnd); - + // Alternate CallInst ctors w/ two actuals, w/ one actual and no // actuals, respectively. CallInst(Value *F, Value *Actual1, Value *Actual2, @@ -724,8 +763,7 @@ public: ~CallInst(); virtual CallInst *clone() const; - bool mayWriteToMemory() const { return true; } - + bool isTailCall() const { return SubclassData & 1; } void setTailCall(bool isTailCall = true) { SubclassData = (SubclassData & ~1) | unsigned(isTailCall); @@ -738,6 +776,17 @@ public: SubclassData = (SubclassData & 1) | (CC << 1); } + /// Obtains a pointer to the ParamAttrsList object which holds the + /// parameter attributes information, if any. + /// @returns 0 if no attributes have been set. + /// @brief Get the parameter attributes. + ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + + /// Sets the parameter attributes for this CallInst. To construct a + /// ParamAttrsList, see ParameterAttributes.h + /// @brief Set the parameter attributes. + void setParamAttrs(ParamAttrsList *attrs); + /// getCalledFunction - Return the function being called by this instruction /// if it is a direct call. If it is a call through a function pointer, /// return null. @@ -760,83 +809,6 @@ public: } }; - -//===----------------------------------------------------------------------===// -// ShiftInst Class -//===----------------------------------------------------------------------===// - -/// ShiftInst - This class represents left and right shift instructions. -/// -class ShiftInst : public Instruction { - Use Ops[2]; - ShiftInst(const ShiftInst &SI) - : Instruction(SI.getType(), SI.getOpcode(), Ops, 2) { - Ops[0].init(SI.Ops[0], this); - Ops[1].init(SI.Ops[1], this); - } - void init(OtherOps Opcode, Value *S, Value *SA) { - assert((Opcode == Shl || Opcode == LShr || Opcode == AShr) && - "ShiftInst Opcode invalid!"); - Ops[0].init(S, this); - Ops[1].init(SA, this); - } - -public: - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "", - Instruction *InsertBefore = 0) - : Instruction(S->getType(), Opcode, Ops, 2, Name, InsertBefore) { - init(Opcode, S, SA); - } - ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name, - BasicBlock *InsertAtEnd) - : Instruction(S->getType(), Opcode, Ops, 2, Name, InsertAtEnd) { - init(Opcode, S, SA); - } - - OtherOps getOpcode() const { - return static_cast(Instruction::getOpcode()); - } - - /// Transparently provide more efficient getOperand methods. - Value *getOperand(unsigned i) const { - assert(i < 2 && "getOperand() out of range!"); - return Ops[i]; - } - void setOperand(unsigned i, Value *Val) { - assert(i < 2 && "setOperand() out of range!"); - Ops[i] = Val; - } - unsigned getNumOperands() const { return 2; } - - /// isLogicalShift - Return true if this is a logical shift left or a logical - /// shift right. - bool isLogicalShift() const { - unsigned opcode = getOpcode(); - return opcode == Instruction::Shl || opcode == Instruction::LShr; - } - - - /// isArithmeticShift - Return true if this is a sign-extending shift right - /// operation. - bool isArithmeticShift() const { - return !isLogicalShift(); - } - - - virtual ShiftInst *clone() const; - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const ShiftInst *) { return true; } - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::LShr) | - (I->getOpcode() == Instruction::AShr) | - (I->getOpcode() == Instruction::Shl); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - //===----------------------------------------------------------------------===// // SelectInst Class //===----------------------------------------------------------------------===// @@ -859,15 +831,15 @@ class SelectInst : public Instruction { public: SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "", Instruction *InsertBefore = 0) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, - Name, InsertBefore) { + : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertBefore) { init(C, S1, S2); + setName(Name); } SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(S1->getType(), Instruction::Select, Ops, 3, - Name, InsertAtEnd) { + : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertAtEnd) { init(C, S1, S2); + setName(Name); } Value *getCondition() const { return Ops[0]; } @@ -914,15 +886,16 @@ class VAArgInst : public UnaryInstruction { public: VAArgInst(Value *List, const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) - : UnaryInstruction(Ty, VAArg, List, Name, InsertBefore) { + : UnaryInstruction(Ty, VAArg, List, InsertBefore) { + setName(Name); } VAArgInst(Value *List, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : UnaryInstruction(Ty, VAArg, List, Name, InsertAtEnd) { + : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) { + setName(Name); } virtual VAArgInst *clone() const; - bool mayWriteToMemory() const { return true; } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const VAArgInst *) { return true; } @@ -939,7 +912,7 @@ public: //===----------------------------------------------------------------------===// /// ExtractElementInst - This instruction extracts a single (scalar) -/// element from a PackedType value +/// element from a VectorType value /// class ExtractElementInst : public Instruction { Use Ops[2]; @@ -965,8 +938,6 @@ public: virtual ExtractElementInst *clone() const; - virtual bool mayWriteToMemory() const { return false; } - /// Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { assert(i < 2 && "getOperand() out of range!"); @@ -993,7 +964,7 @@ public: //===----------------------------------------------------------------------===// /// InsertElementInst - This instruction inserts a single (scalar) -/// element into a PackedType value +/// element into a VectorType value /// class InsertElementInst : public Instruction { Use Ops[3]; @@ -1015,12 +986,10 @@ public: virtual InsertElementInst *clone() const; - virtual bool mayWriteToMemory() const { return false; } - - /// getType - Overload to return most specific packed type. + /// getType - Overload to return most specific vector type. /// - inline const PackedType *getType() const { - return reinterpret_cast(Instruction::getType()); + inline const VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. @@ -1067,12 +1036,10 @@ public: virtual ShuffleVectorInst *clone() const; - virtual bool mayWriteToMemory() const { return false; } - - /// getType - Overload to return most specific packed type. + /// getType - Overload to return most specific vector type. /// - inline const PackedType *getType() const { - return reinterpret_cast(Instruction::getType()); + inline const VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. @@ -1113,13 +1080,15 @@ class PHINode : public Instruction { public: explicit PHINode(const Type *Ty, const std::string &Name = "", Instruction *InsertBefore = 0) - : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertBefore), + : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), ReservedSpace(0) { + setName(Name); } PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd) - : Instruction(Ty, Instruction::PHI, 0, 0, Name, InsertAtEnd), + : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), ReservedSpace(0) { + setName(Name); } ~PHINode(); @@ -1234,13 +1203,8 @@ public: /// does not continue in this function any longer. /// class ReturnInst : public TerminatorInst { - Use RetVal; // Possibly null retval. - ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret, &RetVal, - RI.getNumOperands()) { - if (RI.getNumOperands()) - RetVal.init(RI.RetVal, this); - } - + Use RetVal; // Return Value: null if 'void'. + ReturnInst(const ReturnInst &RI); void init(Value *RetVal); public: @@ -1255,17 +1219,9 @@ public: // // NOTE: If the Value* passed is of type void then the constructor behaves as // if it was passed NULL. - explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertBefore) { - init(retVal); - } - ReturnInst(Value *retVal, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { - init(retVal); - } - explicit ReturnInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Ret, &RetVal, 0, InsertAtEnd) { - } + explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0); + ReturnInst(Value *retVal, BasicBlock *InsertAtEnd); + explicit ReturnInst(BasicBlock *InsertAtEnd); virtual ReturnInst *clone() const; @@ -1319,39 +1275,12 @@ public: // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I // BranchInst(BB* B, BB *I) - 'br B' insert at end // BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end - explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Br, Ops, 1, InsertBefore) { - assert(IfTrue != 0 && "Branch destination may not be null!"); - Ops[0].init(reinterpret_cast(IfTrue), this); - } + explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, - Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Br, Ops, 3, InsertBefore) { - Ops[0].init(reinterpret_cast(IfTrue), this); - Ops[1].init(reinterpret_cast(IfFalse), this); - Ops[2].init(Cond, this); -#ifndef NDEBUG - AssertOK(); -#endif - } - - BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Br, Ops, 1, InsertAtEnd) { - assert(IfTrue != 0 && "Branch destination may not be null!"); - Ops[0].init(reinterpret_cast(IfTrue), this); - } - + Instruction *InsertBefore = 0); + BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd); BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond, - BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Br, Ops, 3, InsertAtEnd) { - Ops[0].init(reinterpret_cast(IfTrue), this); - Ops[1].init(reinterpret_cast(IfFalse), this); - Ops[2].init(Cond, this); -#ifndef NDEBUG - AssertOK(); -#endif - } - + BasicBlock *InsertAtEnd); /// Transparently provide more efficient getOperand methods. Value *getOperand(unsigned i) const { @@ -1439,20 +1368,14 @@ public: /// be specified here to make memory allocation more efficient. This /// constructor can also autoinsert before another instruction. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, - Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Switch, 0, 0, InsertBefore) { - init(Value, Default, NumCases); - } - + Instruction *InsertBefore = 0); + /// SwitchInst ctor - Create a new switch instruction, specifying a value to /// switch on and a default destination. The number of additional cases can /// be specified here to make memory allocation more efficient. This /// constructor also autoinserts at the end of the specified BasicBlock. SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases, - BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Switch, 0, 0, InsertAtEnd) { - init(Value, Default, NumCases); - } + BasicBlock *InsertAtEnd); ~SwitchInst(); @@ -1562,22 +1485,21 @@ private: /// calling convention of the call. /// class InvokeInst : public TerminatorInst { + ParamAttrsList *ParamAttrs; InvokeInst(const InvokeInst &BI); void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params); + Value* const *Args, unsigned NumArgs); public: InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params, const std::string &Name = "", + Value* const* Args, unsigned NumArgs, const std::string &Name = "", Instruction *InsertBefore = 0); InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, - const std::vector &Params, const std::string &Name, + Value* const* Args, unsigned NumArgs, const std::string &Name, BasicBlock *InsertAtEnd); ~InvokeInst(); virtual InvokeInst *clone() const; - bool mayWriteToMemory() const { return true; } - /// getCallingConv/setCallingConv - Get or set the calling convention of this /// function call. unsigned getCallingConv() const { return SubclassData; } @@ -1585,6 +1507,17 @@ public: SubclassData = CC; } + /// Obtains a pointer to the ParamAttrsList object which holds the + /// parameter attributes information, if any. + /// @returns 0 if no attributes have been set. + /// @brief Get the parameter attributes. + ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + + /// Sets the parameter attributes for this InvokeInst. To construct a + /// ParamAttrsList, see ParameterAttributes.h + /// @brief Set the parameter attributes. + void setParamAttrs(ParamAttrsList *attrs); + /// getCalledFunction - Return the function called, or null if this is an /// indirect function invocation. /// @@ -1647,12 +1580,8 @@ private: /// class UnwindInst : public TerminatorInst { public: - explicit UnwindInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unwind, 0, 0, InsertBefore) { - } - explicit UnwindInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unwind, 0, 0, InsertAtEnd) { - } + explicit UnwindInst(Instruction *InsertBefore = 0); + explicit UnwindInst(BasicBlock *InsertAtEnd); virtual UnwindInst *clone() const; @@ -1683,12 +1612,8 @@ private: /// class UnreachableInst : public TerminatorInst { public: - explicit UnreachableInst(Instruction *InsertBefore = 0) - : TerminatorInst(Instruction::Unreachable, 0, 0, InsertBefore) { - } - explicit UnreachableInst(BasicBlock *InsertAtEnd) - : TerminatorInst(Instruction::Unreachable, 0, 0, InsertAtEnd) { - } + explicit UnreachableInst(Instruction *InsertBefore = 0); + explicit UnreachableInst(BasicBlock *InsertAtEnd); virtual UnreachableInst *clone() const;