diff options
author | Dan Gohman <gohman@apple.com> | 2008-05-15 19:50:34 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-05-15 19:50:34 +0000 |
commit | 041e2eb51721bcfecee5d9c9fc409ff185526e47 (patch) | |
tree | bb8e3b74ffb3950147e74e621ffa5e8f14040cd2 /include | |
parent | d208a803a614a0ce6d5a8c6df045fd130f5dfed7 (diff) | |
download | llvm-041e2eb51721bcfecee5d9c9fc409ff185526e47.tar.gz llvm-041e2eb51721bcfecee5d9c9fc409ff185526e47.tar.bz2 llvm-041e2eb51721bcfecee5d9c9fc409ff185526e47.tar.xz |
IR support for extractvalue and insertvalue instructions. Also, begin
moving toward making structs and arrays first-class types.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51157 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/Constants.h | 9 | ||||
-rw-r--r-- | include/llvm/Instruction.def | 10 | ||||
-rw-r--r-- | include/llvm/Instructions.h | 358 | ||||
-rw-r--r-- | include/llvm/Support/InstVisitor.h | 2 |
4 files changed, 359 insertions, 20 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 87a29396ee..65c3a737c8 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -575,6 +575,11 @@ protected: Constant *Elt, Constant *Idx); static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1, Constant *V2, Constant *Mask); + static Constant *getExtractValueTy(const Type *Ty, Constant *Agg, + Constant * const *Idxs, unsigned NumIdxs); + static Constant *getInsertValueTy(const Type *Ty, Constant *Agg, + Constant *Val, + Constant * const *Idxs, unsigned NumIdxs); public: // Static methods to construct a ConstantExpr of different kinds. Note that @@ -706,6 +711,10 @@ public: static Constant *getExtractElement(Constant *Vec, Constant *Idx); static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx); static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask); + static Constant *getExtractValue(Constant *Agg, + Constant* const *IdxList, unsigned NumIdx); + static Constant *getInsertValue(Constant *Agg, Constant *Val, + Constant* const *IdxList, unsigned NumIdx); /// Floating point negation must be implemented with f(x) = -0.0 - x. This /// method returns the negative zero constant for floating point or vector diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index f5ed4531a0..2189c86cfb 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -161,15 +161,17 @@ HANDLE_OTHER_INST(44, Select , SelectInst ) // select instruction HANDLE_OTHER_INST(45, UserOp1, Instruction) // May be used internally in a pass HANDLE_OTHER_INST(46, UserOp2, Instruction) // Internal to passes only HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector. +HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value //from aggregate result -HANDLE_OTHER_INST(52, VICmp , VICmpInst ) // Vec Int comparison instruction. -HANDLE_OTHER_INST(53, VFCmp , VFCmpInst ) // Vec FP point comparison instr. +HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(53, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(54, VICmp , VICmpInst ) // Vec Int comparison instruction. +HANDLE_OTHER_INST(55, VFCmp , VFCmpInst ) // Vec FP point comparison instr. - LAST_OTHER_INST(53) + LAST_OTHER_INST(55) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index e5de229c74..d65657bd33 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -408,28 +408,23 @@ class GetElementPtrInst : public Instruction { /// pointer type. /// static const Type *getIndexedType(const Type *Ptr, - Value* const *Idx, unsigned NumIdx, - bool AllowStructLeaf = false); + Value* const *Idx, unsigned NumIdx); template<typename InputIterator> static const Type *getIndexedType(const Type *Ptr, InputIterator IdxBegin, InputIterator IdxEnd, - bool AllowStructLeaf, // This argument ensures that we // have an iterator we can do // arithmetic on in constant time std::random_access_iterator_tag) { unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); - if (NumIdx > 0) { + if (NumIdx > 0) // This requires that the iterator points to contiguous memory. - return(getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx, - AllowStructLeaf)); - } - else { - return(getIndexedType(Ptr, (Value *const*)0, NumIdx, AllowStructLeaf)); - } + return getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx); + else + return getIndexedType(Ptr, (Value *const*)0, NumIdx); } /// Constructors - Create a getelementptr instruction with a base pointer an @@ -508,11 +503,10 @@ public: template<typename InputIterator> static const Type *getIndexedType(const Type *Ptr, InputIterator IdxBegin, - InputIterator IdxEnd, - bool AllowStructLeaf = false) { - return(getIndexedType(Ptr, IdxBegin, IdxEnd, AllowStructLeaf, + InputIterator IdxEnd) { + return getIndexedType(Ptr, IdxBegin, IdxEnd, typename std::iterator_traits<InputIterator>:: - iterator_category())); + iterator_category()); } static const Type *getIndexedType(const Type *Ptr, Value *Idx); @@ -573,7 +567,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, Instruction *InsertBefore) : Instruction(PointerType::get(checkType( getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd, true)), + IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) ->getAddressSpace()), GetElementPtr, @@ -591,7 +585,7 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, BasicBlock *InsertAtEnd) : Instruction(PointerType::get(checkType( getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd, true)), + IdxBegin, IdxEnd)), cast<PointerType>(Ptr->getType()) ->getAddressSpace()), GetElementPtr, @@ -1498,6 +1492,338 @@ struct OperandTraits<ShuffleVectorInst> : FixedNumOperandTraits<3> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value) //===----------------------------------------------------------------------===// +// ExtractValueInst Class +//===----------------------------------------------------------------------===// + +/// ExtractValueInst - This instruction extracts a value +/// from an aggregate value +/// +class ExtractValueInst : public Instruction { + ExtractValueInst(const ExtractValueInst &EVI); + void init(Value *Agg, Value* const *Idx, unsigned NumIdx); + void init(Value *Agg, Value *Idx); + + template<typename InputIterator> + void init(Value *Agg, InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &Name, + // This argument ensures that we have an iterator we can + // do arithmetic on in constant time + std::random_access_iterator_tag) { + unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); + + if (NumIdx > 0) { + // This requires that the iterator points to contiguous memory. + init(Agg, &*IdxBegin, NumIdx); // FIXME: for the general case + // we have to build an array here + } + else { + init(Agg, 0, NumIdx); + } + + setName(Name); + } + + /// getIndexedType - Returns the type of the element that would be extracted + /// with an extractvalue instruction with the specified parameters. + /// + /// A null type is returned if the indices are invalid for the specified + /// pointer type. + /// + static const Type *getIndexedType(const Type *Agg, + Value* const *Idx, unsigned NumIdx); + + template<typename InputIterator> + static const Type *getIndexedType(const Type *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd, + // This argument ensures that we + // have an iterator we can do + // arithmetic on in constant time + std::random_access_iterator_tag) { + unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); + + if (NumIdx > 0) + // This requires that the iterator points to contiguous memory. + return getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx); + else + return getIndexedType(Ptr, (Value *const*)0, NumIdx); + } + + /// Constructors - Create a extractvalue instruction with a base pointer an + /// list of indices. The first ctor can optionally insert before an existing + /// instruction, the second appends the new instruction to the specified + /// BasicBlock. + template<typename InputIterator> + inline ExtractValueInst(Value *Agg, InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &Name, + Instruction *InsertBefore); + template<typename InputIterator> + inline ExtractValueInst(Value *Agg, + InputIterator IdxBegin, InputIterator IdxEnd, + unsigned Values, + const std::string &Name, BasicBlock *InsertAtEnd); + + /// Constructors - These two constructors are convenience methods because one + /// and two index extractvalue instructions are so common. + ExtractValueInst(Value *Agg, Value *Idx, const std::string &Name = "", + Instruction *InsertBefore = 0); + ExtractValueInst(Value *Agg, Value *Idx, + const std::string &Name, BasicBlock *InsertAtEnd); +public: + template<typename InputIterator> + static ExtractValueInst *Create(Value *Agg, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &Name = "", + Instruction *InsertBefore = 0) { + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + ExtractValueInst(Agg, IdxBegin, IdxEnd, Values, Name, InsertBefore); + } + template<typename InputIterator> + static ExtractValueInst *Create(Value *Agg, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &Name, + BasicBlock *InsertAtEnd) { + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + ExtractValueInst(Agg, IdxBegin, IdxEnd, Values, Name, InsertAtEnd); + } + + /// Constructors - These two creators are convenience methods because one + /// index extractvalue instructions are much more common than those with + /// more than one. + static ExtractValueInst *Create(Value *Agg, Value *Idx, + const std::string &Name = "", + Instruction *InsertBefore = 0) { + return new(2) ExtractValueInst(Agg, Idx, Name, InsertBefore); + } + static ExtractValueInst *Create(Value *Agg, Value *Idx, + const std::string &Name, + BasicBlock *InsertAtEnd) { + return new(2) ExtractValueInst(Agg, Idx, Name, InsertAtEnd); + } + + virtual ExtractValueInst *clone() const; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + // getType - Overload to return most specific pointer type... + const PointerType *getType() const { + return reinterpret_cast<const PointerType*>(Instruction::getType()); + } + + /// getIndexedType - Returns the type of the element that would be extracted + /// with an extractvalue instruction with the specified parameters. + /// + /// A null type is returned if the indices are invalid for the specified + /// pointer type. + /// + template<typename InputIterator> + static const Type *getIndexedType(const Type *Ptr, + InputIterator IdxBegin, + InputIterator IdxEnd) { + return getIndexedType(Ptr, IdxBegin, IdxEnd, + typename std::iterator_traits<InputIterator>:: + iterator_category()); + } + static const Type *getIndexedType(const Type *Ptr, Value *Idx); + + inline op_iterator idx_begin() { return op_begin()+1; } + inline const_op_iterator idx_begin() const { return op_begin()+1; } + inline op_iterator idx_end() { return op_end(); } + inline const_op_iterator idx_end() const { return op_end(); } + + Value *getAggregateOperand() { + return getOperand(0); + } + const Value *getAggregateOperand() const { + return getOperand(0); + } + static unsigned getAggregateOperandIndex() { + return 0U; // get index for modifying correct operand + } + + unsigned getNumIndices() const { // Note: always non-negative + return getNumOperands() - 1; + } + + bool hasIndices() const { + return getNumOperands() > 1; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ExtractValueInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::ExtractValue; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +template <> +struct OperandTraits<ExtractValueInst> : VariadicOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueInst, Value) + +//===----------------------------------------------------------------------===// +// InsertValueInst Class +//===----------------------------------------------------------------------===// + +/// InsertValueInst - This instruction extracts a value +/// from an aggregate value +/// +class InsertValueInst : public Instruction { + InsertValueInst(const InsertValueInst &IVI); + void init(Value *Agg, Value *Val, Value* const *Idx, unsigned NumIdx); + void init(Value *Agg, Value *Val, Value *Idx); + + template<typename InputIterator> + void init(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &Name, + // This argument ensures that we have an iterator we can + // do arithmetic on in constant time + std::random_access_iterator_tag) { + unsigned NumIdx = static_cast<unsigned>(std::distance(IdxBegin, IdxEnd)); + + if (NumIdx > 0) { + // This requires that the iterator points to contiguous memory. + init(Agg, Val, &*IdxBegin, NumIdx); // FIXME: for the general case + // we have to build an array here + } + else { + init(Agg, Val, 0, NumIdx); + } + + setName(Name); + } + + /// Constructors - Create a insertvalue instruction with a base pointer an + /// list of indices. The first ctor can optionally insert before an existing + /// instruction, the second appends the new instruction to the specified + /// BasicBlock. + template<typename InputIterator> + inline InsertValueInst(Value *Agg, Value *Val, InputIterator IdxBegin, + InputIterator IdxEnd, + unsigned Values, + const std::string &Name, + Instruction *InsertBefore); + template<typename InputIterator> + inline InsertValueInst(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + unsigned Values, + const std::string &Name, BasicBlock *InsertAtEnd); + + /// Constructors - These two constructors are convenience methods because one + /// and two index insertvalue instructions are so common. + InsertValueInst(Value *Agg, Value *Val, + Value *Idx, const std::string &Name = "", + Instruction *InsertBefore = 0); + InsertValueInst(Value *Agg, Value *Val, Value *Idx, + const std::string &Name, BasicBlock *InsertAtEnd); +public: + template<typename InputIterator> + static InsertValueInst *Create(Value *Agg, Value *Val, InputIterator IdxBegin, + InputIterator IdxEnd, + const std::string &Name = "", + Instruction *InsertBefore = 0) { + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + InsertValueInst(Agg, Val, IdxBegin, IdxEnd, Values, Name, InsertBefore); + } + template<typename InputIterator> + static InsertValueInst *Create(Value *Agg, Value *Val, + InputIterator IdxBegin, InputIterator IdxEnd, + const std::string &Name, + BasicBlock *InsertAtEnd) { + typename std::iterator_traits<InputIterator>::difference_type Values = + 1 + std::distance(IdxBegin, IdxEnd); + return new(Values) + InsertValueInst(Agg, Val, IdxBegin, IdxEnd, Values, Name, InsertAtEnd); + } + + /// Constructors - These two creators are convenience methods because one + /// index insertvalue instructions are much more common than those with + /// more than one. + static InsertValueInst *Create(Value *Agg, Value *Val, Value *Idx, + const std::string &Name = "", + Instruction *InsertBefore = 0) { + return new(3) InsertValueInst(Agg, Val, Idx, Name, InsertBefore); + } + static InsertValueInst *Create(Value *Agg, Value *Val, Value *Idx, + const std::string &Name, + BasicBlock *InsertAtEnd) { + return new(3) InsertValueInst(Agg, Val, Idx, Name, InsertAtEnd); + } + + virtual InsertValueInst *clone() const; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + // getType - Overload to return most specific pointer type... + const PointerType *getType() const { + return reinterpret_cast<const PointerType*>(Instruction::getType()); + } + + inline op_iterator idx_begin() { return op_begin()+1; } + inline const_op_iterator idx_begin() const { return op_begin()+1; } + inline op_iterator idx_end() { return op_end(); } + inline const_op_iterator idx_end() const { return op_end(); } + + Value *getAggregateOperand() { + return getOperand(0); + } + const Value *getAggregateOperand() const { + return getOperand(0); + } + static unsigned getAggregateOperandIndex() { + return 0U; // get index for modifying correct operand + } + + Value *getInsertedValueOperand() { + return getOperand(1); + } + const Value *getInsertedValueOperand() const { + return getOperand(1); + } + static unsigned getInsertedValueOperandIndex() { + return 1U; // get index for modifying correct operand + } + + unsigned getNumIndices() const { // Note: always non-negative + return getNumOperands() - 2; + } + + bool hasIndices() const { + return getNumOperands() > 2; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const InsertValueInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::InsertValue; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +template <> +struct OperandTraits<InsertValueInst> : VariadicOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) + +//===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 6e9a5c66ab..9606187508 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -197,6 +197,8 @@ public: RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); } RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } RetTy visitGetResultInst(GetResultInst &I) { DELEGATE(Instruction); } + RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} + RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } // Next level propagators... if the user does not overload a specific // instruction type, they can overload one of these to get the whole class |