mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-13 15:37:24 +00:00
IR, bitcode reader, bitcode writer, and asmparser changes to
insertvalue and extractvalue to use constant indices instead of Value* indices. And begin updating LangRef.html. There's definately more to come here, but I'm checking this basic support in now to make it available to people who are interested. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51806 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
652f7ea955
commit
81a0c0b44e
@ -2918,7 +2918,7 @@ or array element from an aggregate value.
|
||||
The first operand of an '<tt>extractvalue</tt>' instruction is a
|
||||
value of <a href="#t_struct">struct</a> or <a href="#t_array">array</a>
|
||||
type. The operands are constant indices to specify which value to extract
|
||||
in the same manner as indices in a
|
||||
in a similar manner as indices in a
|
||||
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
|
||||
</p>
|
||||
|
||||
@ -2932,7 +2932,7 @@ the index operands.
|
||||
<h5>Example:</h5>
|
||||
|
||||
<pre>
|
||||
%result = extractvalue {i32, float} %agg, i32 0 <i>; yields i32</i>
|
||||
%result = extractvalue {i32, float} %agg, 0 <i>; yields i32</i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -2947,7 +2947,7 @@ the index operands.
|
||||
<h5>Syntax:</h5>
|
||||
|
||||
<pre>
|
||||
<result> = insertvalue <aggregate type> <val>, <ty> <val>, i32 <idx> <i>; yields <n x <ty>></i>
|
||||
<result> = insertvalue <aggregate type> <val>, <ty> <val>, <idx> <i>; yields <n x <ty>></i>
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -2965,7 +2965,7 @@ The first operand of an '<tt>insertvalue</tt>' instruction is a
|
||||
value of <a href="#t_struct">struct</a> or <a href="#t_array">array</a> type.
|
||||
The second operand is a first-class value to insert.
|
||||
The following operands are constant indices
|
||||
indicating the position at which to insert the value in the same manner as
|
||||
indicating the position at which to insert the value in a similar manner as
|
||||
indices in a
|
||||
'<tt><a href="#i_getelementptr">getelementptr</a></tt>' instruction.
|
||||
The value to insert must have the same type as the value identified
|
||||
@ -2982,7 +2982,7 @@ specified by the indices is that of <tt>elt</tt>.
|
||||
<h5>Example:</h5>
|
||||
|
||||
<pre>
|
||||
%result = insertvalue {i32, float} %agg, i32 1, i32 0 <i>; yields {i32, float}</i>
|
||||
%result = insertvalue {i32, float} %agg, 1, 0 <i>; yields {i32, float}</i>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "llvm/OperandTraits.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -576,10 +577,10 @@ protected:
|
||||
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);
|
||||
const unsigned *Idxs, unsigned NumIdxs);
|
||||
static Constant *getInsertValueTy(const Type *Ty, Constant *Agg,
|
||||
Constant *Val,
|
||||
Constant * const *Idxs, unsigned NumIdxs);
|
||||
const unsigned *Idxs, unsigned NumIdxs);
|
||||
|
||||
public:
|
||||
// Static methods to construct a ConstantExpr of different kinds. Note that
|
||||
@ -656,6 +657,10 @@ public:
|
||||
/// @brief Return true if this is a compare constant expression
|
||||
bool isCompare() const;
|
||||
|
||||
/// @brief Return true if this is an insertvalue or extractvalue expression,
|
||||
/// and the getIndices() method may be used.
|
||||
bool hasIndices() const;
|
||||
|
||||
/// Select constant expr
|
||||
///
|
||||
static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
|
||||
@ -712,9 +717,9 @@ public:
|
||||
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);
|
||||
const unsigned *IdxList, unsigned NumIdx);
|
||||
static Constant *getInsertValue(Constant *Agg, Constant *Val,
|
||||
Constant* const *IdxList, unsigned NumIdx);
|
||||
const unsigned *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
|
||||
@ -732,6 +737,10 @@ public:
|
||||
/// not an ICMP or FCMP constant expression.
|
||||
unsigned getPredicate() const;
|
||||
|
||||
/// getIndices - Assert that this is an insertvalue or exactvalue
|
||||
/// expression and return the list of indices.
|
||||
const SmallVector<unsigned, 4> &getIndices() const;
|
||||
|
||||
/// getOpcodeName - Return a string representation for an opcode.
|
||||
const char *getOpcodeName() const;
|
||||
|
||||
|
@ -197,7 +197,9 @@ public:
|
||||
/// the element.
|
||||
///
|
||||
virtual const Type *getTypeAtIndex(const Value *V) const = 0;
|
||||
virtual const Type *getTypeAtIndex(unsigned Idx) const = 0;
|
||||
virtual bool indexValid(const Value *V) const = 0;
|
||||
virtual bool indexValid(unsigned Idx) const = 0;
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const CompositeType *) { return true; }
|
||||
@ -245,8 +247,10 @@ public:
|
||||
/// getTypeAtIndex - Given an index value into the type, return the type of
|
||||
/// the element. For a structure type, this must be a constant value...
|
||||
///
|
||||
virtual const Type *getTypeAtIndex(const Value *V) const ;
|
||||
virtual const Type *getTypeAtIndex(const Value *V) const;
|
||||
virtual const Type *getTypeAtIndex(unsigned Idx) const;
|
||||
virtual bool indexValid(const Value *V) const;
|
||||
virtual bool indexValid(unsigned Idx) const;
|
||||
|
||||
// Implement the AbstractTypeUser interface.
|
||||
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
|
||||
@ -288,6 +292,9 @@ public:
|
||||
inline const Type *getElementType() const { return ContainedTys[0]; }
|
||||
|
||||
virtual bool indexValid(const Value *V) const;
|
||||
virtual bool indexValid(unsigned Idx) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// getTypeAtIndex - Given an index value into the type, return the type of
|
||||
/// the element. For sequential types, there is only one subtype...
|
||||
@ -295,6 +302,9 @@ public:
|
||||
virtual const Type *getTypeAtIndex(const Value *) const {
|
||||
return ContainedTys[0];
|
||||
}
|
||||
virtual const Type *getTypeAtIndex(unsigned Idx) const {
|
||||
return ContainedTys[0];
|
||||
}
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const SequentialType *) { return true; }
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/ParameterAttributes.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -1518,9 +1519,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
|
||||
/// element value from an aggregate value.
|
||||
///
|
||||
class ExtractValueInst : public Instruction {
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
|
||||
ExtractValueInst(const ExtractValueInst &EVI);
|
||||
void init(Value *Agg, Value* const *Idx, unsigned NumIdx);
|
||||
void init(Value *Agg, Value *Idx);
|
||||
void init(Value *Agg, const unsigned *Idx, unsigned NumIdx);
|
||||
void init(Value *Agg, unsigned Idx);
|
||||
|
||||
template<typename InputIterator>
|
||||
void init(Value *Agg, InputIterator IdxBegin, InputIterator IdxEnd,
|
||||
@ -1530,14 +1533,15 @@ class ExtractValueInst : public Instruction {
|
||||
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);
|
||||
}
|
||||
// There's no fundamental reason why we require at least one index
|
||||
// (other than weirdness with &*IdxBegin being invalid; see
|
||||
// getelementptr's init routine for example). But there's no
|
||||
// present need to support it.
|
||||
assert(NumIdx > 0 && "ExtractValueInst must have at least one index");
|
||||
|
||||
// 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
|
||||
|
||||
setName(Name);
|
||||
}
|
||||
@ -1549,7 +1553,7 @@ class ExtractValueInst : public Instruction {
|
||||
/// pointer type.
|
||||
///
|
||||
static const Type *getIndexedType(const Type *Agg,
|
||||
Value* const *Idx, unsigned NumIdx);
|
||||
const unsigned *Idx, unsigned NumIdx);
|
||||
|
||||
template<typename InputIterator>
|
||||
static const Type *getIndexedType(const Type *Ptr,
|
||||
@ -1563,9 +1567,9 @@ class ExtractValueInst : public Instruction {
|
||||
|
||||
if (NumIdx > 0)
|
||||
// This requires that the iterator points to contiguous memory.
|
||||
return getIndexedType(Ptr, (Value *const *)&*IdxBegin, NumIdx);
|
||||
return getIndexedType(Ptr, (const unsigned *)&*IdxBegin, NumIdx);
|
||||
else
|
||||
return getIndexedType(Ptr, (Value *const*)0, NumIdx);
|
||||
return getIndexedType(Ptr, (const unsigned *)0, NumIdx);
|
||||
}
|
||||
|
||||
/// Constructors - Create a extractvalue instruction with a base aggregate
|
||||
@ -1575,55 +1579,53 @@ class ExtractValueInst : public Instruction {
|
||||
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 = "",
|
||||
ExtractValueInst(Value *Agg, unsigned Idx, const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
ExtractValueInst(Value *Agg, Value *Idx,
|
||||
ExtractValueInst(Value *Agg, unsigned Idx,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd);
|
||||
public:
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 1);
|
||||
}
|
||||
|
||||
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);
|
||||
return new
|
||||
ExtractValueInst(Agg, IdxBegin, IdxEnd, 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);
|
||||
return new ExtractValueInst(Agg, IdxBegin, IdxEnd, 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,
|
||||
static ExtractValueInst *Create(Value *Agg, unsigned Idx,
|
||||
const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new(2) ExtractValueInst(Agg, Idx, Name, InsertBefore);
|
||||
return new ExtractValueInst(Agg, Idx, Name, InsertBefore);
|
||||
}
|
||||
static ExtractValueInst *Create(Value *Agg, Value *Idx,
|
||||
static ExtractValueInst *Create(Value *Agg, unsigned Idx,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new(2) ExtractValueInst(Agg, Idx, Name, InsertAtEnd);
|
||||
return new ExtractValueInst(Agg, Idx, Name, InsertAtEnd);
|
||||
}
|
||||
|
||||
virtual ExtractValueInst *clone() const;
|
||||
@ -1650,7 +1652,7 @@ public:
|
||||
typename std::iterator_traits<InputIterator>::
|
||||
iterator_category());
|
||||
}
|
||||
static const Type *getIndexedType(const Type *Ptr, Value *Idx);
|
||||
static const Type *getIndexedType(const Type *Ptr, unsigned Idx);
|
||||
|
||||
inline op_iterator idx_begin() { return op_begin()+1; }
|
||||
inline const_op_iterator idx_begin() const { return op_begin()+1; }
|
||||
@ -1686,20 +1688,19 @@ public:
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ExtractValueInst> : VariadicOperandTraits<1> {
|
||||
struct OperandTraits<ExtractValueInst> : FixedNumOperandTraits<1> {
|
||||
};
|
||||
|
||||
template<typename InputIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
InputIterator IdxBegin,
|
||||
InputIterator IdxEnd,
|
||||
unsigned Values,
|
||||
const std::string &Name,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(checkType(getIndexedType(Agg->getType(), IdxBegin, IdxEnd)),
|
||||
ExtractValue,
|
||||
OperandTraits<ExtractValueInst>::op_end(this) - Values,
|
||||
Values, InsertBefore) {
|
||||
OperandTraits<ExtractValueInst>::op_begin(this),
|
||||
1, InsertBefore) {
|
||||
init(Agg, IdxBegin, IdxEnd, Name,
|
||||
typename std::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
@ -1707,17 +1708,12 @@ template<typename InputIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
InputIterator IdxBegin,
|
||||
InputIterator IdxEnd,
|
||||
unsigned Values,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(PointerType::get(checkType(
|
||||
getIndexedType(Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
cast<PointerType>(Agg->getType())
|
||||
->getAddressSpace()),
|
||||
: Instruction(checkType(getIndexedType(Agg->getType(), IdxBegin, IdxEnd)),
|
||||
ExtractValue,
|
||||
OperandTraits<ExtractValueInst>::op_end(this) - Values,
|
||||
Values, InsertAtEnd) {
|
||||
OperandTraits<ExtractValueInst>::op_begin(this),
|
||||
1, InsertAtEnd) {
|
||||
init(Agg, IdxBegin, IdxEnd, Name,
|
||||
typename std::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
@ -1733,9 +1729,12 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueInst, Value)
|
||||
/// value into an aggregate value.
|
||||
///
|
||||
class InsertValueInst : public Instruction {
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
|
||||
void *operator new(size_t, unsigned); // Do not implement
|
||||
InsertValueInst(const InsertValueInst &IVI);
|
||||
void init(Value *Agg, Value *Val, Value* const *Idx, unsigned NumIdx);
|
||||
void init(Value *Agg, Value *Val, Value *Idx);
|
||||
void init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx);
|
||||
void init(Value *Agg, Value *Val, unsigned Idx);
|
||||
|
||||
template<typename InputIterator>
|
||||
void init(Value *Agg, Value *Val,
|
||||
@ -1746,14 +1745,15 @@ class InsertValueInst : public Instruction {
|
||||
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);
|
||||
}
|
||||
// There's no fundamental reason why we require at least one index
|
||||
// (other than weirdness with &*IdxBegin being invalid; see
|
||||
// getelementptr's init routine for example). But there's no
|
||||
// present need to support it.
|
||||
assert(NumIdx > 0 && "InsertValueInst must have at least one index");
|
||||
|
||||
// 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
|
||||
|
||||
setName(Name);
|
||||
}
|
||||
@ -1765,56 +1765,55 @@ class InsertValueInst : public Instruction {
|
||||
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 = "",
|
||||
unsigned Idx, const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0);
|
||||
InsertValueInst(Value *Agg, Value *Val, Value *Idx,
|
||||
InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
|
||||
const std::string &Name, BasicBlock *InsertAtEnd);
|
||||
public:
|
||||
// allocate space for exactly two operands
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 2);
|
||||
}
|
||||
|
||||
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);
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
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);
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
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,
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx,
|
||||
const std::string &Name = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new(3) InsertValueInst(Agg, Val, Idx, Name, InsertBefore);
|
||||
return new InsertValueInst(Agg, Val, Idx, Name, InsertBefore);
|
||||
}
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val, Value *Idx,
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new(3) InsertValueInst(Agg, Val, Idx, Name, InsertAtEnd);
|
||||
return new InsertValueInst(Agg, Val, Idx, Name, InsertAtEnd);
|
||||
}
|
||||
|
||||
virtual InsertValueInst *clone() const;
|
||||
@ -1827,10 +1826,10 @@ public:
|
||||
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(); }
|
||||
inline unsigned *idx_begin() { return Indices.begin(); }
|
||||
inline const unsigned *idx_begin() const { return Indices.begin(); }
|
||||
inline unsigned *idx_end() { return Indices.end(); }
|
||||
inline const unsigned *idx_end() const { return Indices.end(); }
|
||||
|
||||
Value *getAggregateOperand() {
|
||||
return getOperand(0);
|
||||
@ -1871,7 +1870,7 @@ public:
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperandTraits<InsertValueInst> : VariadicOperandTraits<2> {
|
||||
struct OperandTraits<InsertValueInst> : FixedNumOperandTraits<2> {
|
||||
};
|
||||
|
||||
template<typename InputIterator>
|
||||
@ -1879,15 +1878,11 @@ InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
InputIterator IdxBegin,
|
||||
InputIterator IdxEnd,
|
||||
unsigned Values,
|
||||
const std::string &Name,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(checkType(ExtractValueInst::getIndexedType(
|
||||
Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_end(this) - Values,
|
||||
Values, InsertBefore) {
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertBefore) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, Name,
|
||||
typename std::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
@ -1896,18 +1891,11 @@ InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
InputIterator IdxBegin,
|
||||
InputIterator IdxEnd,
|
||||
unsigned Values,
|
||||
const std::string &Name,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(PointerType::get(checkType(
|
||||
ExtractValueInst::getIndexedType(
|
||||
Val->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
cast<PointerType>(Val->getType())
|
||||
->getAddressSpace()),
|
||||
InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_end(this) - Values,
|
||||
Values, InsertAtEnd) {
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertAtEnd) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, Name,
|
||||
typename std::iterator_traits<InputIterator>::iterator_category());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -354,7 +354,7 @@
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 949 "/Users/gohman/LLVM/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
#line 953 "/Users/gohman/LLVM/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
{
|
||||
llvm::Module *ModuleVal;
|
||||
llvm::Function *FunctionVal;
|
||||
@ -368,6 +368,7 @@ typedef union YYSTYPE
|
||||
llvm::PATypeHolder *TypeVal;
|
||||
llvm::Value *ValueVal;
|
||||
std::vector<llvm::Value*> *ValueList;
|
||||
std::vector<unsigned> *ConstantList;
|
||||
llvm::ArgListType *ArgList;
|
||||
llvm::TypeWithAttrs TypeWithAttrs;
|
||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||
@ -402,7 +403,7 @@ typedef union YYSTYPE
|
||||
llvm::FCmpInst::Predicate FPredicate;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 406 "llvmAsmParser.tab.h"
|
||||
#line 407 "llvmAsmParser.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
@ -963,6 +963,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
llvm::PATypeHolder *TypeVal;
|
||||
llvm::Value *ValueVal;
|
||||
std::vector<llvm::Value*> *ValueList;
|
||||
std::vector<unsigned> *ConstantList;
|
||||
llvm::ArgListType *ArgList;
|
||||
llvm::TypeWithAttrs TypeWithAttrs;
|
||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||
@ -1008,6 +1009,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%type <PHIList> PHIList
|
||||
%type <ParamList> ParamList // For call param lists & GEP indices
|
||||
%type <ValueList> IndexList // For GEP indices
|
||||
%type <ConstantList> ConstantIndexList // For insertvalue/extractvalue indices
|
||||
%type <TypeList> TypeListI
|
||||
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
||||
%type <TypeWithAttrs> ArgType
|
||||
@ -1974,46 +1976,20 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| EXTRACTVALUE '(' ConstVal IndexList ')' {
|
||||
| EXTRACTVALUE '(' ConstVal ConstantIndexList ')' {
|
||||
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||
GEN_ERROR("ExtractValue requires an aggregate operand");
|
||||
|
||||
const Type *IdxTy =
|
||||
ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
|
||||
if (!IdxTy)
|
||||
GEN_ERROR("Index list invalid for constant extractvalue");
|
||||
|
||||
SmallVector<Constant*, 8> IdxVec;
|
||||
for (unsigned i = 0, e = $4->size(); i != e; ++i)
|
||||
if (Constant *C = dyn_cast<Constant>((*$4)[i]))
|
||||
IdxVec.push_back(C);
|
||||
else
|
||||
GEN_ERROR("Indices to constant extractvalue must be constants");
|
||||
|
||||
$$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size());
|
||||
delete $4;
|
||||
|
||||
$$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
|
||||
| INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' {
|
||||
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||
GEN_ERROR("InsertValue requires an aggregate operand");
|
||||
|
||||
const Type *IdxTy =
|
||||
ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
|
||||
if (IdxTy != $5->getType())
|
||||
GEN_ERROR("Index list invalid for constant insertvalue");
|
||||
|
||||
SmallVector<Constant*, 8> IdxVec;
|
||||
for (unsigned i = 0, e = $6->size(); i != e; ++i)
|
||||
if (Constant *C = dyn_cast<Constant>((*$6)[i]))
|
||||
IdxVec.push_back(C);
|
||||
else
|
||||
GEN_ERROR("Indices to constant insertvalue must be constants");
|
||||
|
||||
$$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size());
|
||||
delete $6;
|
||||
|
||||
$$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
|
||||
CHECK_FOR_ERROR
|
||||
};
|
||||
|
||||
@ -2885,6 +2861,22 @@ IndexList // Used for gep instructions and constant expressions
|
||||
}
|
||||
;
|
||||
|
||||
ConstantIndexList // Used for insertvalue and extractvalue instructions
|
||||
: ',' EUINT64VAL {
|
||||
$$ = new std::vector<unsigned>();
|
||||
if ((unsigned)$2 != $2)
|
||||
GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue.");
|
||||
$$->push_back($2);
|
||||
}
|
||||
| ConstantIndexList ',' EUINT64VAL {
|
||||
$$ = $1;
|
||||
if ((unsigned)$3 != $3)
|
||||
GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue.");
|
||||
$$->push_back($3);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
;
|
||||
|
||||
OptTailCall : TAIL CALL {
|
||||
$$ = true;
|
||||
CHECK_FOR_ERROR
|
||||
@ -3245,7 +3237,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| EXTRACTVALUE Types ValueRef IndexList {
|
||||
| EXTRACTVALUE Types ValueRef ConstantIndexList {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||
@ -3260,7 +3252,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
|
||||
| INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||
|
@ -731,6 +731,10 @@ ParseGlobalVariable(std::string *NameStr,
|
||||
GenerateError("Cannot declare global vars of function type");
|
||||
return 0;
|
||||
}
|
||||
if (Ty == Type::LabelTy) {
|
||||
GenerateError("Cannot declare global vars of label type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const PointerType *PTy = PointerType::get(Ty, AddressSpace);
|
||||
|
||||
@ -959,6 +963,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
llvm::PATypeHolder *TypeVal;
|
||||
llvm::Value *ValueVal;
|
||||
std::vector<llvm::Value*> *ValueList;
|
||||
std::vector<unsigned> *ConstantList;
|
||||
llvm::ArgListType *ArgList;
|
||||
llvm::TypeWithAttrs TypeWithAttrs;
|
||||
llvm::TypeWithAttrsList *TypeWithAttrsList;
|
||||
@ -1004,6 +1009,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%type <PHIList> PHIList
|
||||
%type <ParamList> ParamList // For call param lists & GEP indices
|
||||
%type <ValueList> IndexList // For GEP indices
|
||||
%type <ConstantList> ConstantIndexList // For insertvalue/extractvalue indices
|
||||
%type <TypeList> TypeListI
|
||||
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
|
||||
%type <TypeWithAttrs> ArgType
|
||||
@ -1402,7 +1408,7 @@ Types
|
||||
}
|
||||
|
||||
| '[' EUINT64VAL 'x' Types ']' { // Sized array type?
|
||||
$$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, (unsigned)$2)));
|
||||
$$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2)));
|
||||
delete $4;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
@ -1850,12 +1856,14 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| INTTYPE TRUETOK { // Boolean constants
|
||||
assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
|
||||
if (cast<IntegerType>($1)->getBitWidth() != 1)
|
||||
GEN_ERROR("Constant true must have type i1");
|
||||
$$ = ConstantInt::getTrue();
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| INTTYPE FALSETOK { // Boolean constants
|
||||
assert(cast<IntegerType>($1)->getBitWidth() == 1 && "Not Bool?");
|
||||
if (cast<IntegerType>($1)->getBitWidth() != 1)
|
||||
GEN_ERROR("Constant false must have type i1");
|
||||
$$ = ConstantInt::getFalse();
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
@ -1968,46 +1976,20 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
|
||||
$$ = ConstantExpr::getShuffleVector($3, $5, $7);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| EXTRACTVALUE '(' ConstVal IndexList ')' {
|
||||
| EXTRACTVALUE '(' ConstVal ConstantIndexList ')' {
|
||||
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||
GEN_ERROR("ExtractValue requires an aggregate operand");
|
||||
|
||||
const Type *IdxTy =
|
||||
ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
|
||||
if (!IdxTy)
|
||||
GEN_ERROR("Index list invalid for constant extractvalue");
|
||||
|
||||
SmallVector<Constant*, 8> IdxVec;
|
||||
for (unsigned i = 0, e = $4->size(); i != e; ++i)
|
||||
if (Constant *C = dyn_cast<Constant>((*$4)[i]))
|
||||
IdxVec.push_back(C);
|
||||
else
|
||||
GEN_ERROR("Indices to constant extractvalue must be constants");
|
||||
|
||||
$$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size());
|
||||
delete $4;
|
||||
|
||||
$$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
|
||||
| INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' {
|
||||
if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
|
||||
GEN_ERROR("InsertValue requires an aggregate operand");
|
||||
|
||||
const Type *IdxTy =
|
||||
ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
|
||||
if (IdxTy != $5->getType())
|
||||
GEN_ERROR("Index list invalid for constant insertvalue");
|
||||
|
||||
SmallVector<Constant*, 8> IdxVec;
|
||||
for (unsigned i = 0, e = $6->size(); i != e; ++i)
|
||||
if (Constant *C = dyn_cast<Constant>((*$6)[i]))
|
||||
IdxVec.push_back(C);
|
||||
else
|
||||
GEN_ERROR("Indices to constant insertvalue must be constants");
|
||||
|
||||
$$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size());
|
||||
delete $6;
|
||||
|
||||
$$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
|
||||
CHECK_FOR_ERROR
|
||||
};
|
||||
|
||||
@ -2250,8 +2232,8 @@ LibList : LibList ',' STRINGCONSTANT {
|
||||
ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
|
||||
if (*$3 == Type::VoidTy)
|
||||
GEN_ERROR("void typed arguments are invalid");
|
||||
if (!(*$3)->isFirstClassType())
|
||||
GEN_ERROR("Argument types must be first-class");
|
||||
ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5;
|
||||
$$ = $1;
|
||||
$1->push_back(E);
|
||||
@ -2260,8 +2242,8 @@ ArgListH : ArgListH ',' Types OptParamAttrs OptLocalName {
|
||||
| Types OptParamAttrs OptLocalName {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
|
||||
if (*$1 == Type::VoidTy)
|
||||
GEN_ERROR("void typed arguments are invalid");
|
||||
if (!(*$1)->isFirstClassType())
|
||||
GEN_ERROR("Argument types must be first-class");
|
||||
ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3;
|
||||
$$ = new ArgListType;
|
||||
$$->push_back(E);
|
||||
@ -2498,6 +2480,9 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant
|
||||
| '<' ConstVector '>' { // Nonempty unsized packed vector
|
||||
const Type *ETy = (*$2)[0]->getType();
|
||||
int NumElements = $2->size();
|
||||
|
||||
if (!ETy->isInteger() && !ETy->isFloatingPoint())
|
||||
GEN_ERROR("Invalid vector element type: " + ETy->getDescription());
|
||||
|
||||
VectorType* pt = VectorType::get(ETy, NumElements);
|
||||
PATypeHolder* PTy = new PATypeHolder(
|
||||
@ -2639,7 +2624,8 @@ BBTerminatorInst :
|
||||
$$ = BranchInst::Create(tmpBB);
|
||||
} // Conditional Branch...
|
||||
| BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
|
||||
assert(cast<IntegerType>($2)->getBitWidth() == 1 && "Not Bool?");
|
||||
if (cast<IntegerType>($2)->getBitWidth() != 1)
|
||||
GEN_ERROR("Branch condition must have type i1");
|
||||
BasicBlock* tmpBBA = getBBVal($6);
|
||||
CHECK_FOR_ERROR
|
||||
BasicBlock* tmpBBB = getBBVal($9);
|
||||
@ -2875,6 +2861,22 @@ IndexList // Used for gep instructions and constant expressions
|
||||
}
|
||||
;
|
||||
|
||||
ConstantIndexList // Used for insertvalue and extractvalue instructions
|
||||
: ',' EUINT64VAL {
|
||||
$$ = new std::vector<unsigned>();
|
||||
if ((unsigned)$2 != $2)
|
||||
GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue.");
|
||||
$$->push_back($2);
|
||||
}
|
||||
| ConstantIndexList ',' EUINT64VAL {
|
||||
$$ = $1;
|
||||
if ((unsigned)$3 != $3)
|
||||
GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue.");
|
||||
$$->push_back($3);
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
;
|
||||
|
||||
OptTailCall : TAIL CALL {
|
||||
$$ = true;
|
||||
CHECK_FOR_ERROR
|
||||
@ -3149,6 +3151,8 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
| MALLOC Types ',' INTTYPE ValueRef OptCAlign {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if ($4 != Type::Int32Ty)
|
||||
GEN_ERROR("Malloc array size is not a 32-bit integer!");
|
||||
Value* tmpVal = getVal($4, $5);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = new MallocInst(*$2, tmpVal, $6);
|
||||
@ -3164,6 +3168,8 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
| ALLOCA Types ',' INTTYPE ValueRef OptCAlign {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if ($4 != Type::Int32Ty)
|
||||
GEN_ERROR("Alloca array size is not a 32-bit integer!");
|
||||
Value* tmpVal = getVal($4, $5);
|
||||
CHECK_FOR_ERROR
|
||||
$$ = new AllocaInst(*$2, tmpVal, $6);
|
||||
@ -3231,7 +3237,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| EXTRACTVALUE Types ValueRef IndexList {
|
||||
| EXTRACTVALUE Types ValueRef ConstantIndexList {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||
@ -3246,7 +3252,7 @@ MemoryInst : MALLOC Types OptCAlign {
|
||||
delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
|
||||
| INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList {
|
||||
if (!UpRefs.empty())
|
||||
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
|
||||
if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
|
||||
|
@ -770,27 +770,45 @@ bool BitcodeReader::ParseConstants() {
|
||||
V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_EXTRACTVAL: { // CE_EXTRACTVAL: [n x operands]
|
||||
if (Record.size() & 1) return Error("Invalid CE_EXTRACTVAL record");
|
||||
SmallVector<Constant*, 16> Elts;
|
||||
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||
const Type *ElTy = getTypeByID(Record[i]);
|
||||
if (!ElTy) return Error("Invalid CE_EXTRACTVAL record");
|
||||
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
|
||||
case bitc::CST_CODE_CE_EXTRACTVAL: {
|
||||
// CE_EXTRACTVAL: [opty, opval, n x indices]
|
||||
const Type *AggTy = getTypeByID(Record[0]);
|
||||
if (!AggTy || !AggTy->isAggregateType())
|
||||
return Error("Invalid CE_INSERTVAL record");
|
||||
Constant *Agg = ValueList.getConstantFwdRef(Record[1], AggTy);
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
for (unsigned i = 2, e = Record.size(); i != e; ++i) {
|
||||
uint64_t Index = Record[i];
|
||||
if ((unsigned)Index != Index)
|
||||
return Error("Invalid CE_EXTRACTVAL record");
|
||||
Indices.push_back((unsigned)Index);
|
||||
}
|
||||
V = ConstantExpr::getExtractValue(Elts[0], &Elts[1], Elts.size()-1);
|
||||
if (!ExtractValueInst::getIndexedType(AggTy,
|
||||
Indices.begin(), Indices.end()))
|
||||
return Error("Invalid CE_EXTRACTVAL record");
|
||||
V = ConstantExpr::getExtractValue(Agg, &Indices[0], Indices.size());
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_INSERTVAL: { // CE_INSERTVAL: [n x operands]
|
||||
if (Record.size() & 1) return Error("Invalid CE_INSERTVAL record");
|
||||
SmallVector<Constant*, 16> Elts;
|
||||
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||
const Type *ElTy = getTypeByID(Record[i]);
|
||||
if (!ElTy) return Error("Invalid CE_INSERTVAL record");
|
||||
Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
|
||||
case bitc::CST_CODE_CE_INSERTVAL: {
|
||||
// CE_INSERTVAL: [opty, opval, opty, opval, n x indices]
|
||||
const Type *AggTy = getTypeByID(Record[0]);
|
||||
if (!AggTy || !AggTy->isAggregateType())
|
||||
return Error("Invalid CE_INSERTVAL record");
|
||||
Constant *Agg = ValueList.getConstantFwdRef(Record[1], AggTy);
|
||||
const Type *ValTy = getTypeByID(Record[2]);
|
||||
Constant *Val = ValueList.getConstantFwdRef(Record[2], ValTy);
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
for (unsigned i = 4, e = Record.size(); i != e; ++i) {
|
||||
uint64_t Index = Record[i];
|
||||
if ((unsigned)Index != Index)
|
||||
return Error("Invalid CE_INSERTVAL record");
|
||||
Indices.push_back((unsigned)Index);
|
||||
}
|
||||
V = ConstantExpr::getInsertValue(Elts[0], Elts[1],
|
||||
&Elts[2], Elts.size()-1);
|
||||
if (ExtractValueInst::getIndexedType(AggTy,
|
||||
Indices.begin(),
|
||||
Indices.end()) != ValTy)
|
||||
return Error("Invalid CE_INSERTVAL record");
|
||||
V = ConstantExpr::getInsertValue(Agg, Val, &Indices[0], Indices.size());
|
||||
break;
|
||||
}
|
||||
case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
|
||||
@ -1324,18 +1342,20 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
break;
|
||||
}
|
||||
|
||||
case bitc::FUNC_CODE_INST_EXTRACTVAL: { // EXTRACTVAL: [n x operands]
|
||||
case bitc::FUNC_CODE_INST_EXTRACTVAL: {
|
||||
// EXTRACTVAL: [opty, opval, n x indices]
|
||||
unsigned OpNum = 0;
|
||||
Value *Agg;
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
|
||||
return Error("Invalid EXTRACTVAL record");
|
||||
|
||||
SmallVector<Value*, 16> EXTRACTVALIdx;
|
||||
while (OpNum != Record.size()) {
|
||||
Value *Op;
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
||||
return Error("Invalid EXTRACTVAL record");
|
||||
EXTRACTVALIdx.push_back(Op);
|
||||
SmallVector<unsigned, 4> EXTRACTVALIdx;
|
||||
for (unsigned RecSize = Record.size();
|
||||
OpNum != RecSize; ++OpNum) {
|
||||
uint64_t Index = Record[OpNum];
|
||||
if ((unsigned)Index != Index)
|
||||
return Error("Invalid EXTRACTVAL index");
|
||||
EXTRACTVALIdx.push_back((unsigned)Index);
|
||||
}
|
||||
|
||||
I = ExtractValueInst::Create(Agg,
|
||||
@ -1343,7 +1363,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
break;
|
||||
}
|
||||
|
||||
case bitc::FUNC_CODE_INST_INSERTVAL: { // INSERTVAL: [n x operands]
|
||||
case bitc::FUNC_CODE_INST_INSERTVAL: {
|
||||
// INSERTVAL: [opty, opval, opty, opval, n x indices]
|
||||
unsigned OpNum = 0;
|
||||
Value *Agg;
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Agg))
|
||||
@ -1352,12 +1373,13 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Val))
|
||||
return Error("Invalid INSERTVAL record");
|
||||
|
||||
SmallVector<Value*, 16> INSERTVALIdx;
|
||||
while (OpNum != Record.size()) {
|
||||
Value *Op;
|
||||
if (getValueTypePair(Record, OpNum, NextValueNo, Op))
|
||||
return Error("Invalid INSERTVAL record");
|
||||
INSERTVALIdx.push_back(Op);
|
||||
SmallVector<unsigned, 4> INSERTVALIdx;
|
||||
for (unsigned RecSize = Record.size();
|
||||
OpNum != RecSize; ++OpNum) {
|
||||
uint64_t Index = Record[OpNum];
|
||||
if ((unsigned)Index != Index)
|
||||
return Error("Invalid INSERTVAL index");
|
||||
INSERTVALIdx.push_back((unsigned)Index);
|
||||
}
|
||||
|
||||
I = InsertValueInst::Create(Agg, Val,
|
||||
|
@ -610,20 +610,26 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
|
||||
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||
}
|
||||
break;
|
||||
case Instruction::ExtractValue:
|
||||
case Instruction::ExtractValue: {
|
||||
Code = bitc::CST_CODE_CE_EXTRACTVAL;
|
||||
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
|
||||
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||
}
|
||||
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||
const SmallVector<unsigned, 4> &Indices = CE->getIndices();
|
||||
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
|
||||
Record.push_back(Indices[i]);
|
||||
break;
|
||||
case Instruction::InsertValue:
|
||||
}
|
||||
case Instruction::InsertValue: {
|
||||
Code = bitc::CST_CODE_CE_INSERTVAL;
|
||||
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
|
||||
Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(i)));
|
||||
}
|
||||
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||
Record.push_back(VE.getTypeID(C->getOperand(1)->getType()));
|
||||
Record.push_back(VE.getValueID(C->getOperand(1)));
|
||||
const SmallVector<unsigned, 4> &Indices = CE->getIndices();
|
||||
for (unsigned i = 0, e = Indices.size(); i != e; ++i)
|
||||
Record.push_back(Indices[i]);
|
||||
break;
|
||||
}
|
||||
case Instruction::Select:
|
||||
Code = bitc::CST_CODE_CE_SELECT;
|
||||
Record.push_back(VE.getValueID(C->getOperand(0)));
|
||||
|
@ -537,15 +537,23 @@ public:
|
||||
/// Constants.cpp, and is used behind the scenes to implement
|
||||
/// extractvalue constant exprs.
|
||||
class VISIBILITY_HIDDEN ExtractValueConstantExpr : public ConstantExpr {
|
||||
ExtractValueConstantExpr(Constant *Agg, const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy);
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
public:
|
||||
static ExtractValueConstantExpr *Create(Constant *Agg,
|
||||
const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy) {
|
||||
return
|
||||
new(IdxList.size() + 1) ExtractValueConstantExpr(Agg, IdxList, DestTy);
|
||||
// allocate space for exactly one operand
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 1);
|
||||
}
|
||||
ExtractValueConstantExpr(Constant *Agg,
|
||||
const SmallVector<unsigned, 4> &IdxList,
|
||||
const Type *DestTy)
|
||||
: ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
|
||||
Indices(IdxList) {
|
||||
Op<0>() = Agg;
|
||||
}
|
||||
|
||||
/// Indicies - These identify which value to extract.
|
||||
const SmallVector<unsigned, 4> Indices;
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
};
|
||||
@ -554,17 +562,24 @@ public:
|
||||
/// Constants.cpp, and is used behind the scenes to implement
|
||||
/// insertvalue constant exprs.
|
||||
class VISIBILITY_HIDDEN InsertValueConstantExpr : public ConstantExpr {
|
||||
InsertValueConstantExpr(Constant *Agg, Constant *Val,
|
||||
const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy);
|
||||
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
|
||||
public:
|
||||
static InsertValueConstantExpr *Create(Constant *Agg, Constant *Val,
|
||||
const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy) {
|
||||
return
|
||||
new(IdxList.size() + 2) InsertValueConstantExpr(Agg, Val,
|
||||
IdxList, DestTy);
|
||||
// allocate space for exactly one operand
|
||||
void *operator new(size_t s) {
|
||||
return User::operator new(s, 2);
|
||||
}
|
||||
InsertValueConstantExpr(Constant *Agg, Constant *Val,
|
||||
const SmallVector<unsigned, 4> &IdxList,
|
||||
const Type *DestTy)
|
||||
: ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
|
||||
Indices(IdxList) {
|
||||
Op<0>() = Agg;
|
||||
Op<1>() = Val;
|
||||
}
|
||||
|
||||
/// Indicies - These identify the position for the insertion.
|
||||
const SmallVector<unsigned, 4> Indices;
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
|
||||
};
|
||||
@ -639,45 +654,15 @@ struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> {
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
|
||||
|
||||
template <>
|
||||
struct OperandTraits<ExtractValueConstantExpr> : VariadicOperandTraits<1> {
|
||||
struct OperandTraits<ExtractValueConstantExpr> : FixedNumOperandTraits<1> {
|
||||
};
|
||||
|
||||
ExtractValueConstantExpr::ExtractValueConstantExpr
|
||||
(Constant *Agg,
|
||||
const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy)
|
||||
: ConstantExpr(DestTy, Instruction::ExtractValue,
|
||||
OperandTraits<ExtractValueConstantExpr>::op_end(this)
|
||||
- (IdxList.size()+1),
|
||||
IdxList.size()+1) {
|
||||
OperandList[0] = Agg;
|
||||
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
|
||||
OperandList[i+1] = IdxList[i];
|
||||
}
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
|
||||
|
||||
template <>
|
||||
struct OperandTraits<InsertValueConstantExpr> : VariadicOperandTraits<2> {
|
||||
struct OperandTraits<InsertValueConstantExpr> : FixedNumOperandTraits<2> {
|
||||
};
|
||||
|
||||
InsertValueConstantExpr::InsertValueConstantExpr
|
||||
(Constant *Agg, Constant *Val,
|
||||
const std::vector<Constant*> &IdxList,
|
||||
const Type *DestTy)
|
||||
: ConstantExpr(DestTy, Instruction::InsertValue,
|
||||
OperandTraits<InsertValueConstantExpr>::op_end(this)
|
||||
- (IdxList.size()+2),
|
||||
IdxList.size()+2) {
|
||||
OperandList[0] = Agg;
|
||||
OperandList[1] = Val;
|
||||
for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
|
||||
OperandList[i+2] = IdxList[i];
|
||||
}
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
|
||||
|
||||
|
||||
template <>
|
||||
struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> {
|
||||
};
|
||||
@ -718,6 +703,21 @@ bool ConstantExpr::isCompare() const {
|
||||
return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
|
||||
}
|
||||
|
||||
bool ConstantExpr::hasIndices() const {
|
||||
return getOpcode() == Instruction::ExtractValue ||
|
||||
getOpcode() == Instruction::InsertValue;
|
||||
}
|
||||
|
||||
const SmallVector<unsigned, 4> &ConstantExpr::getIndices() const {
|
||||
if (const ExtractValueConstantExpr *EVCE =
|
||||
dyn_cast<ExtractValueConstantExpr>(this))
|
||||
return EVCE->Indices;
|
||||
if (const InsertValueConstantExpr *IVCE =
|
||||
dyn_cast<InsertValueConstantExpr>(this))
|
||||
return IVCE->Indices;
|
||||
assert(0 && "ConstantExpr does not have indices!");
|
||||
}
|
||||
|
||||
/// ConstantExpr::get* - Return some common constants without having to
|
||||
/// specify the full Instruction::OPCODE identifier.
|
||||
///
|
||||
@ -829,29 +829,17 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
|
||||
Op2 = (OpNo == 2) ? Op : getOperand(2);
|
||||
return ConstantExpr::getShuffleVector(Op0, Op1, Op2);
|
||||
case Instruction::InsertValue: {
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
Ops.resize(getNumOperands()-2);
|
||||
for (unsigned i = 2, e = getNumOperands(); i != e; ++i)
|
||||
Ops[i-2] = getOperand(i);
|
||||
if (OpNo == 0)
|
||||
return ConstantExpr::getInsertValue(Op, getOperand(1),
|
||||
&Ops[0], Ops.size());
|
||||
if (OpNo == 1)
|
||||
return ConstantExpr::getInsertValue(getOperand(0), Op,
|
||||
&Ops[0], Ops.size());
|
||||
Ops[OpNo-2] = Op;
|
||||
return ConstantExpr::getInsertValue(getOperand(0), getOperand(1),
|
||||
&Ops[0], Ops.size());
|
||||
const SmallVector<unsigned, 4> Indices = getIndices();
|
||||
Op0 = (OpNo == 0) ? Op : getOperand(0);
|
||||
Op1 = (OpNo == 1) ? Op : getOperand(1);
|
||||
return ConstantExpr::getInsertValue(Op0, Op1,
|
||||
&Indices[0], Indices.size());
|
||||
}
|
||||
case Instruction::ExtractValue: {
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
Ops.resize(getNumOperands()-1);
|
||||
for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
|
||||
Ops[i-1] = getOperand(i);
|
||||
if (OpNo == 0)
|
||||
return ConstantExpr::getExtractValue(Op, &Ops[0], Ops.size());
|
||||
Ops[OpNo-1] = Op;
|
||||
return ConstantExpr::getExtractValue(getOperand(0), &Ops[0], Ops.size());
|
||||
assert(OpNo == 0 && "ExtractaValue has only one operand!");
|
||||
const SmallVector<unsigned, 4> Indices = getIndices();
|
||||
return
|
||||
ConstantExpr::getExtractValue(Op, &Indices[0], Indices.size());
|
||||
}
|
||||
case Instruction::GetElementPtr: {
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
@ -908,10 +896,16 @@ getWithOperands(const std::vector<Constant*> &Ops) const {
|
||||
return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
|
||||
case Instruction::ShuffleVector:
|
||||
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
|
||||
case Instruction::InsertValue:
|
||||
return ConstantExpr::getInsertValue(Ops[0], Ops[1], &Ops[2], Ops.size()-2);
|
||||
case Instruction::ExtractValue:
|
||||
return ConstantExpr::getExtractValue(Ops[0], &Ops[1], Ops.size()-1);
|
||||
case Instruction::InsertValue: {
|
||||
const SmallVector<unsigned, 4> Indices = getIndices();
|
||||
return ConstantExpr::getInsertValue(Ops[0], Ops[1],
|
||||
&Indices[0], Indices.size());
|
||||
}
|
||||
case Instruction::ExtractValue: {
|
||||
const SmallVector<unsigned, 4> Indices = getIndices();
|
||||
return ConstantExpr::getExtractValue(Ops[0],
|
||||
&Indices[0], Indices.size());
|
||||
}
|
||||
case Instruction::GetElementPtr:
|
||||
return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], Ops.size()-1);
|
||||
case Instruction::ICmp:
|
||||
@ -1624,21 +1618,30 @@ void UndefValue::destroyConstant() {
|
||||
namespace {
|
||||
|
||||
struct ExprMapKeyType {
|
||||
explicit ExprMapKeyType(unsigned opc, std::vector<Constant*> ops,
|
||||
unsigned short pred = 0) : opcode(opc), predicate(pred), operands(ops) { }
|
||||
typedef SmallVector<unsigned, 4> IndexList;
|
||||
|
||||
ExprMapKeyType(unsigned opc,
|
||||
const std::vector<Constant*> &ops,
|
||||
unsigned short pred = 0,
|
||||
const IndexList &inds = IndexList())
|
||||
: opcode(opc), predicate(pred), operands(ops), indices(inds) {}
|
||||
uint16_t opcode;
|
||||
uint16_t predicate;
|
||||
std::vector<Constant*> operands;
|
||||
IndexList indices;
|
||||
bool operator==(const ExprMapKeyType& that) const {
|
||||
return this->opcode == that.opcode &&
|
||||
this->predicate == that.predicate &&
|
||||
this->operands == that.operands;
|
||||
this->indices == that.indices;
|
||||
}
|
||||
bool operator<(const ExprMapKeyType & that) const {
|
||||
return this->opcode < that.opcode ||
|
||||
(this->opcode == that.opcode && this->predicate < that.predicate) ||
|
||||
(this->opcode == that.opcode && this->predicate == that.predicate &&
|
||||
this->operands < that.operands);
|
||||
this->operands < that.operands) ||
|
||||
(this->opcode == that.opcode && this->predicate == that.predicate &&
|
||||
this->operands == that.operands && this->indices < that.indices);
|
||||
}
|
||||
|
||||
bool operator!=(const ExprMapKeyType& that) const {
|
||||
@ -1669,15 +1672,11 @@ namespace llvm {
|
||||
if (V.opcode == Instruction::ShuffleVector)
|
||||
return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
|
||||
V.operands[2]);
|
||||
if (V.opcode == Instruction::InsertValue) {
|
||||
std::vector<Constant*> IdxList(V.operands.begin()+2, V.operands.end());
|
||||
return InsertValueConstantExpr::Create(V.operands[0], V.operands[1],
|
||||
IdxList, Ty);
|
||||
}
|
||||
if (V.opcode == Instruction::ExtractValue) {
|
||||
std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
|
||||
return ExtractValueConstantExpr::Create(V.operands[0], IdxList, Ty);
|
||||
}
|
||||
if (V.opcode == Instruction::InsertValue)
|
||||
return new InsertValueConstantExpr(V.operands[0], V.operands[1],
|
||||
V.indices, Ty);
|
||||
if (V.opcode == Instruction::ExtractValue)
|
||||
return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
|
||||
if (V.opcode == Instruction::GetElementPtr) {
|
||||
std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
|
||||
return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
|
||||
@ -1756,7 +1755,9 @@ static ExprMapKeyType getValType(ConstantExpr *CE) {
|
||||
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
|
||||
Operands.push_back(cast<Constant>(CE->getOperand(i)));
|
||||
return ExprMapKeyType(CE->getOpcode(), Operands,
|
||||
CE->isCompare() ? CE->getPredicate() : 0);
|
||||
CE->isCompare() ? CE->getPredicate() : 0,
|
||||
CE->hasIndices() ?
|
||||
CE->getIndices() : SmallVector<unsigned, 4>());
|
||||
}
|
||||
|
||||
static ManagedStatic<ValueMap<ExprMapKeyType, Type,
|
||||
@ -2298,31 +2299,26 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
|
||||
|
||||
Constant *ConstantExpr::getInsertValueTy(const Type *ReqTy, Constant *Agg,
|
||||
Constant *Val,
|
||||
Constant *const *Idxs, unsigned NumIdx) {
|
||||
const unsigned *Idxs, unsigned NumIdx) {
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
|
||||
Idxs+NumIdx) == Val->getType() &&
|
||||
"insertvalue indices invalid!");
|
||||
assert(Agg->getType() == ReqTy &&
|
||||
"insertvalue type invalid!");
|
||||
|
||||
if (Constant *FC = ConstantFoldInsertValue(Agg, Val, Idxs, NumIdx))
|
||||
return FC; // Fold a few common cases...
|
||||
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Non-first-class type for constant InsertValue expression");
|
||||
// Look up the constant in the table first to ensure uniqueness
|
||||
std::vector<Constant*> ArgVec;
|
||||
ArgVec.reserve(NumIdx+2);
|
||||
ArgVec.push_back(Agg);
|
||||
ArgVec.push_back(Val);
|
||||
for (unsigned i = 0; i != NumIdx; ++i)
|
||||
ArgVec.push_back(cast<Constant>(Idxs[i]));
|
||||
const ExprMapKeyType Key(Instruction::InsertValue, ArgVec);
|
||||
SmallVector<unsigned, 4> Indices(Idxs, Idxs + NumIdx);
|
||||
const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, Indices);
|
||||
return ExprConstants->getOrCreate(ReqTy, Key);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
|
||||
Constant* const *IdxList, unsigned NumIdx) {
|
||||
const unsigned *IdxList, unsigned NumIdx) {
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Tried to create insertelement operation on non-first-class type!");
|
||||
|
||||
@ -2334,28 +2330,22 @@ Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getExtractValueTy(const Type *ReqTy, Constant *Agg,
|
||||
Constant *const *Idxs, unsigned NumIdx) {
|
||||
const unsigned *Idxs, unsigned NumIdx) {
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
|
||||
Idxs+NumIdx) == ReqTy &&
|
||||
"extractvalue indices invalid!");
|
||||
|
||||
if (Constant *FC = ConstantFoldExtractValue(Agg, Idxs, NumIdx))
|
||||
return FC; // Fold a few common cases...
|
||||
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Non-first-class type for constant extractvalue expression");
|
||||
// Look up the constant in the table first to ensure uniqueness
|
||||
std::vector<Constant*> ArgVec;
|
||||
ArgVec.reserve(NumIdx+1);
|
||||
ArgVec.push_back(Agg);
|
||||
for (unsigned i = 0; i != NumIdx; ++i)
|
||||
ArgVec.push_back(cast<Constant>(Idxs[i]));
|
||||
const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec);
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, Indices);
|
||||
return ExprConstants->getOrCreate(ReqTy, Key);
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getExtractValue(Constant *Agg,
|
||||
Constant* const *IdxList, unsigned NumIdx) {
|
||||
const unsigned *IdxList, unsigned NumIdx) {
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Tried to create extractelement operation on non-first-class type!");
|
||||
|
||||
@ -2591,31 +2581,19 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
|
||||
Replacement = ConstantExpr::getGetElementPtr(Pointer,
|
||||
&Indices[0], Indices.size());
|
||||
} else if (getOpcode() == Instruction::ExtractValue) {
|
||||
SmallVector<Constant*, 8> Indices;
|
||||
Constant *Agg = getOperand(0);
|
||||
Indices.reserve(getNumOperands()-1);
|
||||
if (Agg == From) Agg = To;
|
||||
|
||||
for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
|
||||
Constant *Val = getOperand(i);
|
||||
if (Val == From) Val = To;
|
||||
Indices.push_back(Val);
|
||||
}
|
||||
const SmallVector<unsigned, 4> &Indices = getIndices();
|
||||
Replacement = ConstantExpr::getExtractValue(Agg,
|
||||
&Indices[0], Indices.size());
|
||||
} else if (getOpcode() == Instruction::InsertValue) {
|
||||
SmallVector<Constant*, 8> Indices;
|
||||
Constant *Agg = getOperand(0);
|
||||
Constant *Val = getOperand(1);
|
||||
Indices.reserve(getNumOperands()-2);
|
||||
if (Agg == From) Agg = To;
|
||||
if (Val == From) Val = To;
|
||||
|
||||
for (unsigned i = 2, e = getNumOperands(); i != e; ++i) {
|
||||
Constant *Val = getOperand(i);
|
||||
if (Val == From) Val = To;
|
||||
Indices.push_back(Val);
|
||||
}
|
||||
const SmallVector<unsigned, 4> &Indices = getIndices();
|
||||
Replacement = ConstantExpr::getInsertValue(Agg, Val,
|
||||
&Indices[0], Indices.size());
|
||||
} else if (isCast()) {
|
||||
|
@ -1058,7 +1058,22 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
|
||||
if (NumIdx == 0)
|
||||
return Agg;
|
||||
|
||||
return ExtractValueInst::getIndexedType(Agg, Idxs+1, Idxs+NumIdx);
|
||||
unsigned CurIdx = 1;
|
||||
for (; CurIdx != NumIdx; ++CurIdx) {
|
||||
const CompositeType *CT = dyn_cast<CompositeType>(Agg);
|
||||
if (!CT || isa<PointerType>(CT)) return 0;
|
||||
Value *Index = Idxs[CurIdx];
|
||||
if (!CT->indexValid(Index)) return 0;
|
||||
Agg = CT->getTypeAtIndex(Index);
|
||||
|
||||
// If the new type forwards to another type, then it is in the middle
|
||||
// of being refined to another type (and hence, may have dropped all
|
||||
// references to what it was using before). So, use the new forwarded
|
||||
// type.
|
||||
if (const Type *Ty = Agg->getForwardedType())
|
||||
Agg = Ty;
|
||||
}
|
||||
return CurIdx == NumIdx ? Agg : 0;
|
||||
}
|
||||
|
||||
const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, Value *Idx) {
|
||||
@ -1335,64 +1350,51 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const {
|
||||
// InsertValueInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, Value* const *Idx, unsigned NumIdx) {
|
||||
assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
|
||||
Use *OL = OperandList;
|
||||
OL[0] = Agg;
|
||||
OL[1] = Val;
|
||||
void InsertValueInst::init(Value *Agg, Value *Val,
|
||||
const unsigned *Idx, unsigned NumIdx) {
|
||||
assert(NumOperands == 2 && "NumOperands not initialized?");
|
||||
Op<0>() = Agg;
|
||||
Op<1>() = Val;
|
||||
|
||||
for (unsigned i = 0; i != NumIdx; ++i)
|
||||
OL[i+2] = Idx[i];
|
||||
Indices.insert(Indices.end(), Idx, Idx + NumIdx);
|
||||
}
|
||||
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, Value *Idx) {
|
||||
assert(NumOperands == 3 && "NumOperands not initialized?");
|
||||
Use *OL = OperandList;
|
||||
OL[0] = Agg;
|
||||
OL[1] = Val;
|
||||
OL[2] = Idx;
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx) {
|
||||
assert(NumOperands == 2 && "NumOperands not initialized?");
|
||||
Op<0>() = Agg;
|
||||
Op<1>() = Val;
|
||||
|
||||
Indices.push_back(Idx);
|
||||
}
|
||||
|
||||
InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
|
||||
: Instruction(IVI.getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_end(this)
|
||||
- IVI.getNumOperands(),
|
||||
IVI.getNumOperands()) {
|
||||
Use *OL = OperandList;
|
||||
Use *IVIOL = IVI.OperandList;
|
||||
for (unsigned i = 0, E = NumOperands; i != E; ++i)
|
||||
OL[i] = IVIOL[i];
|
||||
OperandTraits<InsertValueInst>::op_begin(this), 2),
|
||||
Indices(IVI.Indices) {
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExtractValueInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ExtractValueInst::init(Value *Agg, Value* const *Idx, unsigned NumIdx) {
|
||||
assert(NumOperands == 1+NumIdx && "NumOperands not initialized?");
|
||||
Use *OL = OperandList;
|
||||
OL[0] = Agg;
|
||||
void ExtractValueInst::init(Value *Agg, const unsigned *Idx, unsigned NumIdx) {
|
||||
assert(NumOperands == 1 && "NumOperands not initialized?");
|
||||
Op<0>() = Agg;
|
||||
|
||||
for (unsigned i = 0; i != NumIdx; ++i)
|
||||
OL[i+1] = Idx[i];
|
||||
Indices.insert(Indices.end(), Idx, Idx + NumIdx);
|
||||
}
|
||||
|
||||
void ExtractValueInst::init(Value *Agg, Value *Idx) {
|
||||
assert(NumOperands == 2 && "NumOperands not initialized?");
|
||||
Use *OL = OperandList;
|
||||
OL[0] = Agg;
|
||||
OL[1] = Idx;
|
||||
void ExtractValueInst::init(Value *Agg, unsigned Idx) {
|
||||
assert(NumOperands == 1 && "NumOperands not initialized?");
|
||||
Op<0>() = Agg;
|
||||
|
||||
Indices.push_back(Idx);
|
||||
}
|
||||
|
||||
ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
|
||||
: Instruction(reinterpret_cast<const Type*>(EVI.getType()), ExtractValue,
|
||||
OperandTraits<ExtractValueInst>::op_end(this)
|
||||
- EVI.getNumOperands(),
|
||||
EVI.getNumOperands()) {
|
||||
Use *OL = OperandList;
|
||||
Use *EVIOL = EVI.OperandList;
|
||||
for (unsigned i = 0, E = NumOperands; i != E; ++i)
|
||||
OL[i] = EVIOL[i];
|
||||
OperandTraits<ExtractValueInst>::op_begin(this), 1),
|
||||
Indices(EVI.Indices) {
|
||||
}
|
||||
|
||||
// getIndexedType - Returns the type of the element that would be extracted
|
||||
@ -1402,13 +1404,13 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
|
||||
// pointer type.
|
||||
//
|
||||
const Type* ExtractValueInst::getIndexedType(const Type *Agg,
|
||||
Value* const *Idxs,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx) {
|
||||
unsigned CurIdx = 0;
|
||||
for (; CurIdx != NumIdx; ++CurIdx) {
|
||||
const CompositeType *CT = dyn_cast<CompositeType>(Agg);
|
||||
if (!CT || isa<PointerType>(CT)) return 0;
|
||||
Value *Index = Idxs[CurIdx];
|
||||
if (!CT || isa<PointerType>(CT) || isa<VectorType>(CT)) return 0;
|
||||
unsigned Index = Idxs[CurIdx];
|
||||
if (!CT->indexValid(Index)) return 0;
|
||||
Agg = CT->getTypeAtIndex(Index);
|
||||
|
||||
@ -2869,10 +2871,10 @@ VICmpInst* VICmpInst::clone() const {
|
||||
}
|
||||
|
||||
ExtractValueInst *ExtractValueInst::clone() const {
|
||||
return new(getNumOperands()) ExtractValueInst(*this);
|
||||
return new ExtractValueInst(*this);
|
||||
}
|
||||
InsertValueInst *InsertValueInst::clone() const {
|
||||
return new(getNumOperands()) InsertValueInst(*this);
|
||||
return new InsertValueInst(*this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -396,16 +396,24 @@ bool StructType::indexValid(const Value *V) const {
|
||||
// Structure indexes require 32-bit integer constants.
|
||||
if (V->getType() == Type::Int32Ty)
|
||||
if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
|
||||
return CU->getZExtValue() < NumContainedTys;
|
||||
return indexValid(CU->getZExtValue());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool StructType::indexValid(unsigned V) const {
|
||||
return V < NumContainedTys;
|
||||
}
|
||||
|
||||
// getTypeAtIndex - Given an index value into the type, return the type of the
|
||||
// element. For a structure type, this must be a constant value...
|
||||
//
|
||||
const Type *StructType::getTypeAtIndex(const Value *V) const {
|
||||
assert(indexValid(V) && "Invalid structure index!");
|
||||
unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
|
||||
return getTypeAtIndex(Idx);
|
||||
}
|
||||
|
||||
const Type *StructType::getTypeAtIndex(unsigned Idx) const {
|
||||
assert(indexValid(Idx) && "Invalid structure index!");
|
||||
return ContainedTys[Idx];
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
; RUN: llvm-as < %s
|
||||
|
||||
;define float @foo({{i32},{float, double}}* %p) {
|
||||
;%t = load {{i32},{float, double}}* %p
|
||||
;%s = extractvalue {{i32},{float, double}} %t, i32 1, i32 0
|
||||
;%r = insertvalue {{i32},{float, double}} %t, double 2.0, i32 1, i32 1
|
||||
;store {{i32},{float, double}} %r, {{i32},{float, double}}* %p
|
||||
;ret float %s
|
||||
;}
|
||||
define float @bar({{i32},{float, double}}* %p) {
|
||||
store {{i32},{float, double}} insertvalue ({{i32},{float, double}}{{i32}{i32 4},{float, double}{float 4.0, double 5.0}}, double 20.0, i32 1, i32 1), {{i32},{float, double}}* %p
|
||||
ret float extractvalue ({{i32},{float, double}}{{i32}{i32 3},{float, double}{float 7.0, double 9.0}}, i32 1, i32 0)
|
||||
define float @foo({{i32},{float, double}}* %p) {
|
||||
%t = load {{i32},{float, double}}* %p
|
||||
%s = extractvalue {{i32},{float, double}} %t, 1, 0
|
||||
%r = insertvalue {{i32},{float, double}} %t, double 2.0, 1, 1
|
||||
store {{i32},{float, double}} %r, {{i32},{float, double}}* %p
|
||||
ret float %s
|
||||
}
|
||||
define float @bar({{i32},{float, double}}* %p) {
|
||||
store {{i32},{float, double}} insertvalue ({{i32},{float, double}}{{i32}{i32 4},{float, double}{float 4.0, double 5.0}}, double 20.0, 1, 1), {{i32},{float, double}}* %p
|
||||
ret float extractvalue ({{i32},{float, double}}{{i32}{i32 3},{float, double}{float 7.0, double 9.0}}, 1, 0)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user