summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-05-15 19:50:34 +0000
committerDan Gohman <gohman@apple.com>2008-05-15 19:50:34 +0000
commit041e2eb51721bcfecee5d9c9fc409ff185526e47 (patch)
treebb8e3b74ffb3950147e74e621ffa5e8f14040cd2 /include
parentd208a803a614a0ce6d5a8c6df045fd130f5dfed7 (diff)
downloadllvm-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.h9
-rw-r--r--include/llvm/Instruction.def10
-rw-r--r--include/llvm/Instructions.h358
-rw-r--r--include/llvm/Support/InstVisitor.h2
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