mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
Convert InsertValueInst and ExtractValueInst APIs to use ArrayRef.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5d4f9909c4
commit
fc6d3a4986
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_ANALYSIS_VALUETRACKING_H
|
||||
#define LLVM_ANALYSIS_VALUETRACKING_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
|
||||
@ -108,18 +109,9 @@ namespace llvm {
|
||||
/// If InsertBefore is not null, this function will duplicate (modified)
|
||||
/// insertvalues when a part of a nested struct is extracted.
|
||||
Value *FindInsertedValue(Value *V,
|
||||
const unsigned *idx_begin,
|
||||
const unsigned *idx_end,
|
||||
ArrayRef<unsigned> idx_range,
|
||||
Instruction *InsertBefore = 0);
|
||||
|
||||
/// This is a convenience wrapper for finding values indexed by a single index
|
||||
/// only.
|
||||
inline Value *FindInsertedValue(Value *V, const unsigned Idx,
|
||||
Instruction *InsertBefore = 0) {
|
||||
const unsigned Idxs[1] = { Idx };
|
||||
return FindInsertedValue(V, &Idxs[0], &Idxs[1], InsertBefore);
|
||||
}
|
||||
|
||||
/// GetPointerBaseWithConstantOffset - Analyze the specified pointer to see if
|
||||
/// it can be expressed as a base pointer plus a constant offset. Return the
|
||||
/// base and offset to the caller.
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
@ -37,6 +38,12 @@ unsigned ComputeLinearIndex(const Type *Ty,
|
||||
const unsigned *IndicesEnd,
|
||||
unsigned CurIndex = 0);
|
||||
|
||||
inline unsigned ComputeLinearIndex(const Type *Ty,
|
||||
ArrayRef<unsigned> Indices,
|
||||
unsigned CurIndex = 0) {
|
||||
return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex);
|
||||
}
|
||||
|
||||
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
|
||||
/// EVTs that represent all the individual underlying
|
||||
/// non-aggregate types that comprise it.
|
||||
|
@ -855,10 +855,9 @@ 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,
|
||||
const unsigned *IdxList, unsigned NumIdx);
|
||||
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs);
|
||||
static Constant *getInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx);
|
||||
ArrayRef<unsigned> Idxs);
|
||||
|
||||
/// isNullValue - Return true if this is the value that would be returned by
|
||||
/// getNullValue.
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <iterator>
|
||||
|
||||
@ -1428,70 +1429,18 @@ class ExtractValueInst : public UnaryInstruction {
|
||||
SmallVector<unsigned, 4> Indices;
|
||||
|
||||
ExtractValueInst(const ExtractValueInst &EVI);
|
||||
void init(const unsigned *Idx, unsigned NumIdx,
|
||||
const Twine &NameStr);
|
||||
void init(unsigned Idx, const Twine &NameStr);
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
void init(RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
const Twine &NameStr,
|
||||
// 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));
|
||||
|
||||
// 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(&*IdxBegin, NumIdx, NameStr); // FIXME: for the general case
|
||||
// we have to build an array here
|
||||
}
|
||||
|
||||
/// getIndexedType - Returns the type of the element that would be extracted
|
||||
/// with an extractvalue instruction with the specified parameters.
|
||||
///
|
||||
/// Null is returned if the indices are invalid for the specified type.
|
||||
///
|
||||
/// FIXME: Use ArrayRef
|
||||
static Type *getIndexedType(const Type *Agg,
|
||||
const unsigned *Idx, unsigned NumIdx);
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
static Type *getIndexedType(const Type *Ptr,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator 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, &*IdxBegin, NumIdx);
|
||||
else
|
||||
return getIndexedType(Ptr, (const unsigned *)0, NumIdx);
|
||||
}
|
||||
void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
|
||||
|
||||
/// Constructors - Create a extractvalue instruction with a base aggregate
|
||||
/// value and a 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 RandomAccessIterator>
|
||||
inline ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
template<typename RandomAccessIterator>
|
||||
inline ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
// allocate space for exactly one operand
|
||||
@ -1502,55 +1451,25 @@ protected:
|
||||
virtual ExtractValueInst *clone_impl() const;
|
||||
|
||||
public:
|
||||
template<typename RandomAccessIterator>
|
||||
static ExtractValueInst *Create(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new
|
||||
ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, InsertBefore);
|
||||
ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static ExtractValueInst *Create(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new ExtractValueInst(Agg, IdxBegin, IdxEnd, NameStr, 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, unsigned Idx,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
unsigned Idxs[1] = { Idx };
|
||||
return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertBefore);
|
||||
}
|
||||
static ExtractValueInst *Create(Value *Agg, unsigned Idx,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
unsigned Idxs[1] = { Idx };
|
||||
return new ExtractValueInst(Agg, Idxs, Idxs + 1, NameStr, InsertAtEnd);
|
||||
return new ExtractValueInst(Agg, Idxs, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
/// getIndexedType - Returns the type of the element that would be extracted
|
||||
/// with an extractvalue instruction with the specified parameters.
|
||||
///
|
||||
/// Null is returned if the indices are invalid for the specified type.
|
||||
///
|
||||
/// FIXME: Remove the templates and just use ArrayRef.
|
||||
template<typename RandomAccessIterator>
|
||||
static Type *getIndexedType(const Type *Ptr,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd) {
|
||||
return getIndexedType(Ptr, IdxBegin, IdxEnd,
|
||||
typename std::iterator_traits<RandomAccessIterator>::
|
||||
iterator_category());
|
||||
}
|
||||
static Type *getIndexedType(const Type *Ptr, unsigned Idx);
|
||||
static Type *getIndexedType(const Type *Agg, ArrayRef<unsigned> Idxs);
|
||||
|
||||
typedef const unsigned* idx_iterator;
|
||||
inline idx_iterator idx_begin() const { return Indices.begin(); }
|
||||
@ -1566,7 +1485,11 @@ public:
|
||||
return 0U; // get index for modifying correct operand
|
||||
}
|
||||
|
||||
unsigned getNumIndices() const { // Note: always non-negative
|
||||
ArrayRef<unsigned> getIndices() const {
|
||||
return Indices;
|
||||
}
|
||||
|
||||
unsigned getNumIndices() const {
|
||||
return (unsigned)Indices.size();
|
||||
}
|
||||
|
||||
@ -1584,31 +1507,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
|
||||
ExtractValue, Agg, InsertBefore) {
|
||||
init(IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Idxs, NameStr);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
ExtractValueInst::ExtractValueInst(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(),
|
||||
IdxBegin, IdxEnd)),
|
||||
: UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
|
||||
ExtractValue, Agg, InsertAtEnd) {
|
||||
init(IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Idxs, NameStr);
|
||||
}
|
||||
|
||||
|
||||
@ -1624,44 +1537,19 @@ class InsertValueInst : public Instruction {
|
||||
|
||||
void *operator new(size_t, unsigned); // Do not implement
|
||||
InsertValueInst(const InsertValueInst &IVI);
|
||||
void init(Value *Agg, Value *Val, const unsigned *Idx, unsigned NumIdx,
|
||||
void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr);
|
||||
void init(Value *Agg, Value *Val, unsigned Idx, const Twine &NameStr);
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
void init(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin, RandomAccessIterator IdxEnd,
|
||||
const Twine &NameStr,
|
||||
// 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));
|
||||
|
||||
// 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, NameStr); // FIXME: for the general case
|
||||
// we have to build an array here
|
||||
}
|
||||
|
||||
/// Constructors - Create a insertvalue instruction with a base aggregate
|
||||
/// value, a value to insert, and a 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 RandomAccessIterator>
|
||||
inline InsertValueInst(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore);
|
||||
template<typename RandomAccessIterator>
|
||||
inline InsertValueInst(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr, BasicBlock *InsertAtEnd);
|
||||
|
||||
/// Constructors - These two constructors are convenience methods because one
|
||||
@ -1679,37 +1567,17 @@ public:
|
||||
return User::operator new(s, 2);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
NameStr, InsertBefore);
|
||||
return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new InsertValueInst(Agg, Val, IdxBegin, IdxEnd,
|
||||
NameStr, 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, unsigned Idx,
|
||||
const Twine &NameStr = "",
|
||||
Instruction *InsertBefore = 0) {
|
||||
return new InsertValueInst(Agg, Val, Idx, NameStr, InsertBefore);
|
||||
}
|
||||
static InsertValueInst *Create(Value *Agg, Value *Val, unsigned Idx,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd) {
|
||||
return new InsertValueInst(Agg, Val, Idx, NameStr, InsertAtEnd);
|
||||
return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertAtEnd);
|
||||
}
|
||||
|
||||
/// Transparently provide more efficient getOperand methods.
|
||||
@ -1739,7 +1607,11 @@ public:
|
||||
return 1U; // get index for modifying correct operand
|
||||
}
|
||||
|
||||
unsigned getNumIndices() const { // Note: always non-negative
|
||||
ArrayRef<unsigned> getIndices() const {
|
||||
return Indices;
|
||||
}
|
||||
|
||||
unsigned getNumIndices() const {
|
||||
return (unsigned)Indices.size();
|
||||
}
|
||||
|
||||
@ -1762,33 +1634,25 @@ struct OperandTraits<InsertValueInst> :
|
||||
public FixedNumOperandTraits<InsertValueInst, 2> {
|
||||
};
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertBefore) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Agg, Val, Idxs, NameStr);
|
||||
}
|
||||
template<typename RandomAccessIterator>
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &NameStr,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertAtEnd) {
|
||||
init(Agg, Val, IdxBegin, IdxEnd, NameStr,
|
||||
typename std::iterator_traits<RandomAccessIterator>
|
||||
::iterator_category());
|
||||
init(Agg, Val, Idxs, NameStr);
|
||||
}
|
||||
|
||||
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
|
||||
|
@ -210,14 +210,14 @@ public:
|
||||
return ConstantExpr::getShuffleVector(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return ConstantExpr::getExtractValue(Agg, IdxList, NumIdx);
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getExtractValue(Agg, IdxList);
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx) const {
|
||||
return ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx);
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ConstantExpr::getInsertValue(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1194,43 +1194,21 @@ public:
|
||||
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
|
||||
}
|
||||
|
||||
Value *CreateExtractValue(Value *Agg, unsigned Idx,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
return Insert(Folder.CreateExtractValue(AggC, &Idx, 1), Name);
|
||||
return Insert(ExtractValueInst::Create(Agg, Idx), Name);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
Value *CreateExtractValue(Value *Agg,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
return Insert(Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd-IdxBegin),
|
||||
Name);
|
||||
return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
|
||||
return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
|
||||
return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
|
||||
}
|
||||
|
||||
Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
if (Constant *ValC = dyn_cast<Constant>(Val))
|
||||
return Insert(Folder.CreateInsertValue(AggC, ValC, &Idx, 1), Name);
|
||||
return Insert(InsertValueInst::Create(Agg, Val, Idx), Name);
|
||||
}
|
||||
|
||||
template<typename RandomAccessIterator>
|
||||
Value *CreateInsertValue(Value *Agg, Value *Val,
|
||||
RandomAccessIterator IdxBegin,
|
||||
RandomAccessIterator IdxEnd,
|
||||
ArrayRef<unsigned> Idxs,
|
||||
const Twine &Name = "") {
|
||||
if (Constant *AggC = dyn_cast<Constant>(Agg))
|
||||
if (Constant *ValC = dyn_cast<Constant>(Val))
|
||||
return Insert(Folder.CreateInsertValue(AggC, ValC, IdxBegin,
|
||||
IdxEnd - IdxBegin),
|
||||
Name);
|
||||
return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
|
||||
return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
|
||||
return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -22,6 +22,7 @@
|
||||
#ifndef LLVM_SUPPORT_NOFOLDER_H
|
||||
#define LLVM_SUPPORT_NOFOLDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
|
||||
@ -269,15 +270,14 @@ public:
|
||||
return new ShuffleVectorInst(V1, V2, Mask);
|
||||
}
|
||||
|
||||
Instruction *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return ExtractValueInst::Create(Agg, IdxList, IdxList+NumIdx);
|
||||
Instruction *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return ExtractValueInst::Create(Agg, IdxList);
|
||||
}
|
||||
|
||||
Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return InsertValueInst::Create(Agg, Val, IdxList, IdxList+NumIdx);
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return InsertValueInst::Create(Agg, Val, IdxList);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/InstrTypes.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Analysis/ConstantFolding.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -226,14 +227,14 @@ public:
|
||||
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
|
||||
}
|
||||
|
||||
Constant *CreateExtractValue(Constant *Agg, const unsigned *IdxList,
|
||||
unsigned NumIdx) const {
|
||||
return Fold(ConstantExpr::getExtractValue(Agg, IdxList, NumIdx));
|
||||
Constant *CreateExtractValue(Constant *Agg,
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
|
||||
}
|
||||
|
||||
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *IdxList, unsigned NumIdx) const {
|
||||
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList, NumIdx));
|
||||
ArrayRef<unsigned> IdxList) const {
|
||||
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -771,12 +771,12 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
|
||||
return ConstantExpr::getInsertValue(
|
||||
cast<Constant>(IVI->getAggregateOperand()),
|
||||
cast<Constant>(IVI->getInsertedValueOperand()),
|
||||
IVI->idx_begin(), IVI->getNumIndices());
|
||||
IVI->getIndices());
|
||||
|
||||
if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(I))
|
||||
return ConstantExpr::getExtractValue(
|
||||
cast<Constant>(EVI->getAggregateOperand()),
|
||||
EVI->idx_begin(), EVI->getNumIndices());
|
||||
EVI->getIndices());
|
||||
|
||||
return ConstantFoldInstOperands(I->getOpcode(), I->getType(),
|
||||
Ops.data(), Ops.size(), TD);
|
||||
|
@ -592,8 +592,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
||||
return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
|
||||
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
|
||||
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
|
||||
Ex->idx_begin(),
|
||||
Ex->idx_end()))
|
||||
Ex->getIndices()))
|
||||
if (W != V)
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
|
||||
@ -607,9 +606,7 @@ Value *Lint::findValueImpl(Value *V, bool OffsetOk,
|
||||
return findValueImpl(CE->getOperand(0), OffsetOk, Visited);
|
||||
} else if (CE->getOpcode() == Instruction::ExtractValue) {
|
||||
ArrayRef<unsigned> Indices = CE->getIndices();
|
||||
if (Value *W = FindInsertedValue(CE->getOperand(0),
|
||||
Indices.begin(),
|
||||
Indices.end()))
|
||||
if (Value *W = FindInsertedValue(CE->getOperand(0), Indices))
|
||||
if (W != V)
|
||||
return findValueImpl(W, OffsetOk, Visited);
|
||||
}
|
||||
|
@ -1352,14 +1352,15 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
// we might be able to find the complete struct somewhere.
|
||||
|
||||
// Find the value that is at that particular spot
|
||||
Value *V = FindInsertedValue(From, Idxs.begin(), Idxs.end());
|
||||
Value *V = FindInsertedValue(From, Idxs);
|
||||
|
||||
if (!V)
|
||||
return NULL;
|
||||
|
||||
// Insert the value in the new (sub) aggregrate
|
||||
return llvm::InsertValueInst::Create(To, V, Idxs.begin() + IdxSkip,
|
||||
Idxs.end(), "tmp", InsertBefore);
|
||||
return llvm::InsertValueInst::Create(To, V,
|
||||
ArrayRef<unsigned>(Idxs).slice(IdxSkip),
|
||||
"tmp", InsertBefore);
|
||||
}
|
||||
|
||||
// This helper takes a nested struct and extracts a part of it (which is again a
|
||||
@ -1374,15 +1375,13 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType,
|
||||
// insertvalue instruction somewhere).
|
||||
//
|
||||
// All inserted insertvalue instructions are inserted before InsertBefore
|
||||
static Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
|
||||
const unsigned *idx_end,
|
||||
static Value *BuildSubAggregate(Value *From, ArrayRef<unsigned> idx_range,
|
||||
Instruction *InsertBefore) {
|
||||
assert(InsertBefore && "Must have someplace to insert!");
|
||||
const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(),
|
||||
idx_begin,
|
||||
idx_end);
|
||||
idx_range);
|
||||
Value *To = UndefValue::get(IndexedType);
|
||||
SmallVector<unsigned, 10> Idxs(idx_begin, idx_end);
|
||||
SmallVector<unsigned, 10> Idxs(idx_range.begin(), idx_range.end());
|
||||
unsigned IdxSkip = Idxs.size();
|
||||
|
||||
return BuildSubAggregate(From, To, IndexedType, Idxs, IdxSkip, InsertBefore);
|
||||
@ -1394,39 +1393,37 @@ static Value *BuildSubAggregate(Value *From, const unsigned *idx_begin,
|
||||
///
|
||||
/// If InsertBefore is not null, this function will duplicate (modified)
|
||||
/// insertvalues when a part of a nested struct is extracted.
|
||||
Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
const unsigned *idx_end, Instruction *InsertBefore) {
|
||||
Value *llvm::FindInsertedValue(Value *V, ArrayRef<unsigned> idx_range,
|
||||
Instruction *InsertBefore) {
|
||||
// Nothing to index? Just return V then (this is useful at the end of our
|
||||
// recursion)
|
||||
if (idx_begin == idx_end)
|
||||
if (idx_range.empty())
|
||||
return V;
|
||||
// We have indices, so V should have an indexable type
|
||||
assert((V->getType()->isStructTy() || V->getType()->isArrayTy())
|
||||
&& "Not looking at a struct or array?");
|
||||
assert(ExtractValueInst::getIndexedType(V->getType(), idx_begin, idx_end)
|
||||
assert(ExtractValueInst::getIndexedType(V->getType(), idx_range)
|
||||
&& "Invalid indices for type?");
|
||||
const CompositeType *PTy = cast<CompositeType>(V->getType());
|
||||
|
||||
if (isa<UndefValue>(V))
|
||||
return UndefValue::get(ExtractValueInst::getIndexedType(PTy,
|
||||
idx_begin,
|
||||
idx_end));
|
||||
idx_range));
|
||||
else if (isa<ConstantAggregateZero>(V))
|
||||
return Constant::getNullValue(ExtractValueInst::getIndexedType(PTy,
|
||||
idx_begin,
|
||||
idx_end));
|
||||
idx_range));
|
||||
else if (Constant *C = dyn_cast<Constant>(V)) {
|
||||
if (isa<ConstantArray>(C) || isa<ConstantStruct>(C))
|
||||
// Recursively process this constant
|
||||
return FindInsertedValue(C->getOperand(*idx_begin), idx_begin + 1,
|
||||
idx_end, InsertBefore);
|
||||
return FindInsertedValue(C->getOperand(idx_range[0]), idx_range.slice(1),
|
||||
InsertBefore);
|
||||
} else if (InsertValueInst *I = dyn_cast<InsertValueInst>(V)) {
|
||||
// Loop the indices for the insertvalue instruction in parallel with the
|
||||
// requested indices
|
||||
const unsigned *req_idx = idx_begin;
|
||||
const unsigned *req_idx = idx_range.begin();
|
||||
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
|
||||
i != e; ++i, ++req_idx) {
|
||||
if (req_idx == idx_end) {
|
||||
if (req_idx == idx_range.end()) {
|
||||
if (InsertBefore)
|
||||
// The requested index identifies a part of a nested aggregate. Handle
|
||||
// this specially. For example,
|
||||
@ -1438,7 +1435,10 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
// %C = insertvalue {i32, i32 } %A, i32 11, 1
|
||||
// which allows the unused 0,0 element from the nested struct to be
|
||||
// removed.
|
||||
return BuildSubAggregate(V, idx_begin, req_idx, InsertBefore);
|
||||
return BuildSubAggregate(V,
|
||||
ArrayRef<unsigned>(idx_range.begin(),
|
||||
req_idx),
|
||||
InsertBefore);
|
||||
else
|
||||
// We can't handle this without inserting insertvalues
|
||||
return 0;
|
||||
@ -1448,13 +1448,14 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
// See if the (aggregrate) value inserted into has the value we are
|
||||
// looking for, then.
|
||||
if (*req_idx != *i)
|
||||
return FindInsertedValue(I->getAggregateOperand(), idx_begin, idx_end,
|
||||
return FindInsertedValue(I->getAggregateOperand(), idx_range,
|
||||
InsertBefore);
|
||||
}
|
||||
// If we end up here, the indices of the insertvalue match with those
|
||||
// requested (though possibly only partially). Now we recursively look at
|
||||
// the inserted value, passing any remaining indices.
|
||||
return FindInsertedValue(I->getInsertedValueOperand(), req_idx, idx_end,
|
||||
return FindInsertedValue(I->getInsertedValueOperand(),
|
||||
ArrayRef<unsigned>(req_idx, idx_range.end()),
|
||||
InsertBefore);
|
||||
} else if (ExtractValueInst *I = dyn_cast<ExtractValueInst>(V)) {
|
||||
// If we're extracting a value from an aggregrate that was extracted from
|
||||
@ -1462,24 +1463,20 @@ Value *llvm::FindInsertedValue(Value *V, const unsigned *idx_begin,
|
||||
// However, we will need to chain I's indices with the requested indices.
|
||||
|
||||
// Calculate the number of indices required
|
||||
unsigned size = I->getNumIndices() + (idx_end - idx_begin);
|
||||
unsigned size = I->getNumIndices() + idx_range.size();
|
||||
// Allocate some space to put the new indices in
|
||||
SmallVector<unsigned, 5> Idxs;
|
||||
Idxs.reserve(size);
|
||||
// Add indices from the extract value instruction
|
||||
for (const unsigned *i = I->idx_begin(), *e = I->idx_end();
|
||||
i != e; ++i)
|
||||
Idxs.push_back(*i);
|
||||
Idxs.append(I->idx_begin(), I->idx_end());
|
||||
|
||||
// Add requested indices
|
||||
for (const unsigned *i = idx_begin, *e = idx_end; i != e; ++i)
|
||||
Idxs.push_back(*i);
|
||||
Idxs.append(idx_range.begin(), idx_range.end());
|
||||
|
||||
assert(Idxs.size() == size
|
||||
&& "Number of indices added not correct?");
|
||||
|
||||
return FindInsertedValue(I->getAggregateOperand(), Idxs.begin(), Idxs.end(),
|
||||
InsertBefore);
|
||||
return FindInsertedValue(I->getAggregateOperand(), Idxs, InsertBefore);
|
||||
}
|
||||
// Otherwise, we don't know (such as, extracting from a function return value
|
||||
// or load instruction)
|
||||
|
@ -2086,11 +2086,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
||||
|
||||
if (!Val->getType()->isAggregateType())
|
||||
return Error(ID.Loc, "extractvalue operand must be aggregate type");
|
||||
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
|
||||
Indices.end()))
|
||||
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
|
||||
return Error(ID.Loc, "invalid indices for extractvalue");
|
||||
ID.ConstantVal =
|
||||
ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size());
|
||||
ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -2107,11 +2105,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
|
||||
return true;
|
||||
if (!Val0->getType()->isAggregateType())
|
||||
return Error(ID.Loc, "insertvalue operand must be aggregate type");
|
||||
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
|
||||
Indices.end()))
|
||||
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
|
||||
return Error(ID.Loc, "invalid indices for insertvalue");
|
||||
ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1,
|
||||
Indices.data(), Indices.size());
|
||||
ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices);
|
||||
ID.Kind = ValID::t_Constant;
|
||||
return false;
|
||||
}
|
||||
@ -3690,10 +3686,9 @@ int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
if (!Val->getType()->isAggregateType())
|
||||
return Error(Loc, "extractvalue operand must be aggregate type");
|
||||
|
||||
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
|
||||
Indices.end()))
|
||||
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
|
||||
return Error(Loc, "invalid indices for extractvalue");
|
||||
Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end());
|
||||
Inst = ExtractValueInst::Create(Val, Indices);
|
||||
return AteExtraComma ? InstExtraComma : InstNormal;
|
||||
}
|
||||
|
||||
@ -3712,10 +3707,9 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
if (!Val0->getType()->isAggregateType())
|
||||
return Error(Loc0, "insertvalue operand must be aggregate type");
|
||||
|
||||
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
|
||||
Indices.end()))
|
||||
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
|
||||
return Error(Loc0, "invalid indices for insertvalue");
|
||||
Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
|
||||
Inst = InsertValueInst::Create(Val0, Val1, Indices);
|
||||
return AteExtraComma ? InstExtraComma : InstNormal;
|
||||
}
|
||||
|
||||
|
@ -2206,8 +2206,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
EXTRACTVALIdx.push_back((unsigned)Index);
|
||||
}
|
||||
|
||||
I = ExtractValueInst::Create(Agg,
|
||||
EXTRACTVALIdx.begin(), EXTRACTVALIdx.end());
|
||||
I = ExtractValueInst::Create(Agg, EXTRACTVALIdx);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
@ -2231,8 +2230,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
||||
INSERTVALIdx.push_back((unsigned)Index);
|
||||
}
|
||||
|
||||
I = InsertValueInst::Create(Agg, Val,
|
||||
INSERTVALIdx.begin(), INSERTVALIdx.end());
|
||||
I = InsertValueInst::Create(Agg, Val, INSERTVALIdx);
|
||||
InstructionList.push_back(I);
|
||||
break;
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ FastISel::SelectExtractValue(const User *U) {
|
||||
return false; // fast-isel can't handle aggregate constants at the moment
|
||||
|
||||
// Get the actual result register, which is an offset from the base register.
|
||||
unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->idx_begin(), EVI->idx_end());
|
||||
unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->getIndices());
|
||||
|
||||
SmallVector<EVT, 4> AggValueVTs;
|
||||
ComputeValueVTs(TLI, AggTy, AggValueVTs);
|
||||
|
@ -2883,7 +2883,7 @@ void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) {
|
||||
bool IntoUndef = isa<UndefValue>(Op0);
|
||||
bool FromUndef = isa<UndefValue>(Op1);
|
||||
|
||||
unsigned LinearIndex = ComputeLinearIndex(AggTy, I.idx_begin(), I.idx_end());
|
||||
unsigned LinearIndex = ComputeLinearIndex(AggTy, I.getIndices());
|
||||
|
||||
SmallVector<EVT, 4> AggValueVTs;
|
||||
ComputeValueVTs(TLI, AggTy, AggValueVTs);
|
||||
@ -2923,7 +2923,7 @@ void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) {
|
||||
const Type *ValTy = I.getType();
|
||||
bool OutOfUndef = isa<UndefValue>(Op0);
|
||||
|
||||
unsigned LinearIndex = ComputeLinearIndex(AggTy, I.idx_begin(), I.idx_end());
|
||||
unsigned LinearIndex = ComputeLinearIndex(AggTy, I.getIndices());
|
||||
|
||||
SmallVector<EVT, 4> ValValueVTs;
|
||||
ComputeValueVTs(TLI, ValTy, ValValueVTs);
|
||||
|
@ -3560,7 +3560,8 @@ void CWriter::visitInsertValueInst(InsertValueInst &IVI) {
|
||||
for (const unsigned *b = IVI.idx_begin(), *i = b, *e = IVI.idx_end();
|
||||
i != e; ++i) {
|
||||
const Type *IndexedTy =
|
||||
ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(), b, i+1);
|
||||
ExtractValueInst::getIndexedType(IVI.getOperand(0)->getType(),
|
||||
ArrayRef<unsigned>(b, i+1));
|
||||
if (IndexedTy->isArrayTy())
|
||||
Out << ".array[" << *i << "]";
|
||||
else
|
||||
@ -3581,7 +3582,8 @@ void CWriter::visitExtractValueInst(ExtractValueInst &EVI) {
|
||||
for (const unsigned *b = EVI.idx_begin(), *i = b, *e = EVI.idx_end();
|
||||
i != e; ++i) {
|
||||
const Type *IndexedTy =
|
||||
ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(), b, i+1);
|
||||
ExtractValueInst::getIndexedType(EVI.getOperand(0)->getType(),
|
||||
ArrayRef<unsigned>(b, i+1));
|
||||
if (IndexedTy->isArrayTy())
|
||||
Out << ".array[" << *i << "]";
|
||||
else
|
||||
|
@ -278,8 +278,7 @@ FoldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP, GlobalVariable *GV,
|
||||
|
||||
// If this is indexing an array of structures, get the structure element.
|
||||
if (!LaterIndices.empty())
|
||||
Elt = ConstantExpr::getExtractValue(Elt, LaterIndices.data(),
|
||||
LaterIndices.size());
|
||||
Elt = ConstantExpr::getExtractValue(Elt, LaterIndices);
|
||||
|
||||
// If the element is masked, handle it.
|
||||
if (AndCst) Elt = ConstantExpr::getAnd(Elt, AndCst);
|
||||
|
@ -1199,7 +1199,7 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
if (EV.getNumIndices() > 1)
|
||||
// Extract the remaining indices out of the constant indexed by the
|
||||
// first index
|
||||
return ExtractValueInst::Create(V, EV.idx_begin() + 1, EV.idx_end());
|
||||
return ExtractValueInst::Create(V, EV.getIndices().slice(1));
|
||||
else
|
||||
return ReplaceInstUsesWith(EV, V);
|
||||
}
|
||||
@ -1222,7 +1222,7 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
// with
|
||||
// %E = extractvalue { i32, { i32 } } %A, 0
|
||||
return ExtractValueInst::Create(IV->getAggregateOperand(),
|
||||
EV.idx_begin(), EV.idx_end());
|
||||
EV.getIndices());
|
||||
}
|
||||
if (exti == exte && insi == inse)
|
||||
// Both iterators are at the end: Index lists are identical. Replace
|
||||
@ -1240,9 +1240,9 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
// by switching the order of the insert and extract (though the
|
||||
// insertvalue should be left in, since it may have other uses).
|
||||
Value *NewEV = Builder->CreateExtractValue(IV->getAggregateOperand(),
|
||||
EV.idx_begin(), EV.idx_end());
|
||||
EV.getIndices());
|
||||
return InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(),
|
||||
insi, inse);
|
||||
ArrayRef<unsigned>(insi, inse));
|
||||
}
|
||||
if (insi == inse)
|
||||
// The insert list is a prefix of the extract list
|
||||
@ -1254,7 +1254,7 @@ Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) {
|
||||
// with
|
||||
// %E extractvalue { i32 } { i32 42 }, 0
|
||||
return ExtractValueInst::Create(IV->getInsertedValueOperand(),
|
||||
exti, exte);
|
||||
ArrayRef<unsigned>(exti, exte));
|
||||
}
|
||||
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Agg)) {
|
||||
// We're extracting from an intrinsic, see if we're the only user, which
|
||||
|
@ -880,42 +880,38 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1,
|
||||
}
|
||||
|
||||
Constant *llvm::ConstantFoldExtractValueInstruction(Constant *Agg,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx) {
|
||||
ArrayRef<unsigned> Idxs) {
|
||||
// Base case: no indices, so return the entire value.
|
||||
if (NumIdx == 0)
|
||||
if (Idxs.empty())
|
||||
return Agg;
|
||||
|
||||
if (isa<UndefValue>(Agg)) // ev(undef, x) -> undef
|
||||
return UndefValue::get(ExtractValueInst::getIndexedType(Agg->getType(),
|
||||
Idxs,
|
||||
Idxs + NumIdx));
|
||||
Idxs));
|
||||
|
||||
if (isa<ConstantAggregateZero>(Agg)) // ev(0, x) -> 0
|
||||
return
|
||||
Constant::getNullValue(ExtractValueInst::getIndexedType(Agg->getType(),
|
||||
Idxs,
|
||||
Idxs + NumIdx));
|
||||
Idxs));
|
||||
|
||||
// Otherwise recurse.
|
||||
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg))
|
||||
return ConstantFoldExtractValueInstruction(CS->getOperand(*Idxs),
|
||||
Idxs+1, NumIdx-1);
|
||||
return ConstantFoldExtractValueInstruction(CS->getOperand(Idxs[0]),
|
||||
Idxs.slice(1));
|
||||
|
||||
if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg))
|
||||
return ConstantFoldExtractValueInstruction(CA->getOperand(*Idxs),
|
||||
Idxs+1, NumIdx-1);
|
||||
return ConstantFoldExtractValueInstruction(CA->getOperand(Idxs[0]),
|
||||
Idxs.slice(1));
|
||||
ConstantVector *CV = cast<ConstantVector>(Agg);
|
||||
return ConstantFoldExtractValueInstruction(CV->getOperand(*Idxs),
|
||||
Idxs+1, NumIdx-1);
|
||||
return ConstantFoldExtractValueInstruction(CV->getOperand(Idxs[0]),
|
||||
Idxs.slice(1));
|
||||
}
|
||||
|
||||
Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
|
||||
Constant *Val,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx) {
|
||||
ArrayRef<unsigned> Idxs) {
|
||||
// Base case: no indices, so replace the entire value.
|
||||
if (NumIdx == 0)
|
||||
if (Idxs.empty())
|
||||
return Val;
|
||||
|
||||
if (isa<UndefValue>(Agg)) {
|
||||
@ -937,9 +933,9 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
|
||||
for (unsigned i = 0; i < numOps; ++i) {
|
||||
const Type *MemberTy = AggTy->getTypeAtIndex(i);
|
||||
Constant *Op =
|
||||
(*Idxs == i) ?
|
||||
(Idxs[0] == i) ?
|
||||
ConstantFoldInsertValueInstruction(UndefValue::get(MemberTy),
|
||||
Val, Idxs+1, NumIdx-1) :
|
||||
Val, Idxs.slice(1)) :
|
||||
UndefValue::get(MemberTy);
|
||||
Ops[i] = Op;
|
||||
}
|
||||
@ -968,9 +964,9 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
|
||||
for (unsigned i = 0; i < numOps; ++i) {
|
||||
const Type *MemberTy = AggTy->getTypeAtIndex(i);
|
||||
Constant *Op =
|
||||
(*Idxs == i) ?
|
||||
(Idxs[0] == i) ?
|
||||
ConstantFoldInsertValueInstruction(Constant::getNullValue(MemberTy),
|
||||
Val, Idxs+1, NumIdx-1) :
|
||||
Val, Idxs.slice(1)) :
|
||||
Constant::getNullValue(MemberTy);
|
||||
Ops[i] = Op;
|
||||
}
|
||||
@ -985,8 +981,8 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
|
||||
std::vector<Constant*> Ops(Agg->getNumOperands());
|
||||
for (unsigned i = 0; i < Agg->getNumOperands(); ++i) {
|
||||
Constant *Op = cast<Constant>(Agg->getOperand(i));
|
||||
if (*Idxs == i)
|
||||
Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs+1, NumIdx-1);
|
||||
if (Idxs[0] == i)
|
||||
Op = ConstantFoldInsertValueInstruction(Op, Val, Idxs.slice(1));
|
||||
Ops[i] = Op;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef CONSTANTFOLDING_H
|
||||
#define CONSTANTFOLDING_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
namespace llvm {
|
||||
class Value;
|
||||
class Constant;
|
||||
@ -38,11 +40,9 @@ namespace llvm {
|
||||
Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
|
||||
Constant *Mask);
|
||||
Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx);
|
||||
ArrayRef<unsigned> Idxs);
|
||||
Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx);
|
||||
ArrayRef<unsigned> Idxs);
|
||||
Constant *ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1,
|
||||
Constant *V2);
|
||||
Constant *ConstantFoldCompareInstruction(unsigned short predicate,
|
||||
|
@ -1715,30 +1715,29 @@ Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2,
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
|
||||
const unsigned *Idxs, unsigned NumIdx) {
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs,
|
||||
Idxs+NumIdx) == Val->getType() &&
|
||||
ArrayRef<unsigned> Idxs) {
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(),
|
||||
Idxs) == Val->getType() &&
|
||||
"insertvalue indices invalid!");
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Non-first-class type for constant insertvalue expression");
|
||||
Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
|
||||
Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs);
|
||||
assert(FC && "insertvalue constant expr couldn't be folded!");
|
||||
return FC;
|
||||
}
|
||||
|
||||
Constant *ConstantExpr::getExtractValue(Constant *Agg,
|
||||
const unsigned *Idxs, unsigned NumIdx) {
|
||||
ArrayRef<unsigned> Idxs) {
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Tried to create extractelement operation on non-first-class type!");
|
||||
|
||||
const Type *ReqTy =
|
||||
ExtractValueInst::getIndexedType(Agg->getType(), Idxs, Idxs+NumIdx);
|
||||
const Type *ReqTy = ExtractValueInst::getIndexedType(Agg->getType(), Idxs);
|
||||
(void)ReqTy;
|
||||
assert(ReqTy && "extractvalue indices invalid!");
|
||||
|
||||
assert(Agg->getType()->isFirstClassType() &&
|
||||
"Non-first-class type for constant extractvalue expression");
|
||||
Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
|
||||
Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs);
|
||||
assert(FC && "ExtractValue constant expr couldn't be folded!");
|
||||
return FC;
|
||||
}
|
||||
@ -2086,8 +2085,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
|
||||
if (Agg == From) Agg = To;
|
||||
|
||||
ArrayRef<unsigned> Indices = getIndices();
|
||||
Replacement = ConstantExpr::getExtractValue(Agg,
|
||||
&Indices[0], Indices.size());
|
||||
Replacement = ConstantExpr::getExtractValue(Agg, Indices);
|
||||
} else if (getOpcode() == Instruction::InsertValue) {
|
||||
Constant *Agg = getOperand(0);
|
||||
Constant *Val = getOperand(1);
|
||||
@ -2095,8 +2093,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV,
|
||||
if (Val == From) Val = To;
|
||||
|
||||
ArrayRef<unsigned> Indices = getIndices();
|
||||
Replacement = ConstantExpr::getInsertValue(Agg, Val,
|
||||
&Indices[0], Indices.size());
|
||||
Replacement = ConstantExpr::getInsertValue(Agg, Val, Indices);
|
||||
} else if (isCast()) {
|
||||
assert(getOperand(0) == From && "Cast only has one use!");
|
||||
Replacement = ConstantExpr::getCast(getOpcode(), To, getType());
|
||||
|
@ -913,7 +913,8 @@ LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant,
|
||||
LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
|
||||
unsigned NumIdx) {
|
||||
return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant),
|
||||
IdxList, NumIdx));
|
||||
ArrayRef<unsigned>(IdxList,
|
||||
NumIdx)));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
|
||||
@ -921,7 +922,8 @@ LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant,
|
||||
unsigned *IdxList, unsigned NumIdx) {
|
||||
return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant),
|
||||
unwrap<Constant>(ElementValueConstant),
|
||||
IdxList, NumIdx));
|
||||
ArrayRef<unsigned>(IdxList,
|
||||
NumIdx)));
|
||||
}
|
||||
|
||||
LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString,
|
||||
|
@ -204,22 +204,10 @@ bool Instruction::isIdenticalToWhenDefined(const Instruction *I) const {
|
||||
if (const InvokeInst *CI = dyn_cast<InvokeInst>(this))
|
||||
return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() &&
|
||||
CI->getAttributes() == cast<InvokeInst>(I)->getAttributes();
|
||||
if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) {
|
||||
if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices())
|
||||
return false;
|
||||
for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i)
|
||||
if (IVI->idx_begin()[i] != cast<InsertValueInst>(I)->idx_begin()[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) {
|
||||
if (EVI->getNumIndices() != cast<ExtractValueInst>(I)->getNumIndices())
|
||||
return false;
|
||||
for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i)
|
||||
if (EVI->idx_begin()[i] != cast<ExtractValueInst>(I)->idx_begin()[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this))
|
||||
return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices();
|
||||
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this))
|
||||
return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -256,22 +244,10 @@ bool Instruction::isSameOperationAs(const Instruction *I) const {
|
||||
return CI->getCallingConv() == cast<InvokeInst>(I)->getCallingConv() &&
|
||||
CI->getAttributes() ==
|
||||
cast<InvokeInst>(I)->getAttributes();
|
||||
if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this)) {
|
||||
if (IVI->getNumIndices() != cast<InsertValueInst>(I)->getNumIndices())
|
||||
return false;
|
||||
for (unsigned i = 0, e = IVI->getNumIndices(); i != e; ++i)
|
||||
if (IVI->idx_begin()[i] != cast<InsertValueInst>(I)->idx_begin()[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this)) {
|
||||
if (EVI->getNumIndices() != cast<ExtractValueInst>(I)->getNumIndices())
|
||||
return false;
|
||||
for (unsigned i = 0, e = EVI->getNumIndices(); i != e; ++i)
|
||||
if (EVI->idx_begin()[i] != cast<ExtractValueInst>(I)->idx_begin()[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (const InsertValueInst *IVI = dyn_cast<InsertValueInst>(this))
|
||||
return IVI->getIndices() == cast<InsertValueInst>(I)->getIndices();
|
||||
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(this))
|
||||
return EVI->getIndices() == cast<ExtractValueInst>(I)->getIndices();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1386,27 +1386,22 @@ int ShuffleVectorInst::getMaskValue(unsigned i) const {
|
||||
// InsertValueInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, const unsigned *Idx,
|
||||
unsigned NumIdx, const Twine &Name) {
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
|
||||
const Twine &Name) {
|
||||
assert(NumOperands == 2 && "NumOperands not initialized?");
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx, Idx + 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(Idxs.size() > 0 && "InsertValueInst must have at least one index");
|
||||
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idxs) ==
|
||||
Val->getType() && "Inserted value must match indexed type!");
|
||||
Op<0>() = Agg;
|
||||
Op<1>() = Val;
|
||||
|
||||
Indices.append(Idx, Idx + NumIdx);
|
||||
setName(Name);
|
||||
}
|
||||
|
||||
void InsertValueInst::init(Value *Agg, Value *Val, unsigned Idx,
|
||||
const Twine &Name) {
|
||||
assert(NumOperands == 2 && "NumOperands not initialized?");
|
||||
assert(ExtractValueInst::getIndexedType(Agg->getType(), Idx) == Val->getType()
|
||||
&& "Inserted value must match indexed type!");
|
||||
Op<0>() = Agg;
|
||||
Op<1>() = Val;
|
||||
|
||||
Indices.push_back(Idx);
|
||||
Indices.append(Idxs.begin(), Idxs.end());
|
||||
setName(Name);
|
||||
}
|
||||
|
||||
@ -1419,44 +1414,18 @@ InsertValueInst::InsertValueInst(const InsertValueInst &IVI)
|
||||
SubclassOptionalData = IVI.SubclassOptionalData;
|
||||
}
|
||||
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
unsigned Idx,
|
||||
const Twine &Name,
|
||||
Instruction *InsertBefore)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertBefore) {
|
||||
init(Agg, Val, Idx, Name);
|
||||
}
|
||||
|
||||
InsertValueInst::InsertValueInst(Value *Agg,
|
||||
Value *Val,
|
||||
unsigned Idx,
|
||||
const Twine &Name,
|
||||
BasicBlock *InsertAtEnd)
|
||||
: Instruction(Agg->getType(), InsertValue,
|
||||
OperandTraits<InsertValueInst>::op_begin(this),
|
||||
2, InsertAtEnd) {
|
||||
init(Agg, Val, Idx, Name);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ExtractValueInst Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void ExtractValueInst::init(const unsigned *Idx, unsigned NumIdx,
|
||||
const Twine &Name) {
|
||||
void ExtractValueInst::init(ArrayRef<unsigned> Idxs, const Twine &Name) {
|
||||
assert(NumOperands == 1 && "NumOperands not initialized?");
|
||||
|
||||
Indices.append(Idx, Idx + NumIdx);
|
||||
setName(Name);
|
||||
}
|
||||
// There's no fundamental reason why we require at least one index.
|
||||
// But there's no present need to support it.
|
||||
assert(Idxs.size() > 0 && "ExtractValueInst must have at least one index");
|
||||
|
||||
void ExtractValueInst::init(unsigned Idx, const Twine &Name) {
|
||||
assert(NumOperands == 1 && "NumOperands not initialized?");
|
||||
|
||||
Indices.push_back(Idx);
|
||||
Indices.append(Idxs.begin(), Idxs.end());
|
||||
setName(Name);
|
||||
}
|
||||
|
||||
@ -1473,9 +1442,8 @@ ExtractValueInst::ExtractValueInst(const ExtractValueInst &EVI)
|
||||
// pointer type.
|
||||
//
|
||||
Type *ExtractValueInst::getIndexedType(const Type *Agg,
|
||||
const unsigned *Idxs,
|
||||
unsigned NumIdx) {
|
||||
for (unsigned CurIdx = 0; CurIdx != NumIdx; ++CurIdx) {
|
||||
ArrayRef<unsigned> Idxs) {
|
||||
for (unsigned CurIdx = 0; CurIdx != Idxs.size(); ++CurIdx) {
|
||||
unsigned Index = Idxs[CurIdx];
|
||||
// We can't use CompositeType::indexValid(Index) here.
|
||||
// indexValid() always returns true for arrays because getelementptr allows
|
||||
@ -1499,10 +1467,6 @@ Type *ExtractValueInst::getIndexedType(const Type *Agg,
|
||||
return const_cast<Type*>(Agg);
|
||||
}
|
||||
|
||||
Type *ExtractValueInst::getIndexedType(const Type *Agg, unsigned Idx) {
|
||||
return getIndexedType(Agg, &Idx, 1);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BinaryOperator Class
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1318,7 +1318,7 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
|
||||
|
||||
void Verifier::visitExtractValueInst(ExtractValueInst &EVI) {
|
||||
Assert1(ExtractValueInst::getIndexedType(EVI.getAggregateOperand()->getType(),
|
||||
EVI.idx_begin(), EVI.idx_end()) ==
|
||||
EVI.getIndices()) ==
|
||||
EVI.getType(),
|
||||
"Invalid ExtractValueInst operands!", &EVI);
|
||||
|
||||
@ -1327,7 +1327,7 @@ void Verifier::visitExtractValueInst(ExtractValueInst &EVI) {
|
||||
|
||||
void Verifier::visitInsertValueInst(InsertValueInst &IVI) {
|
||||
Assert1(ExtractValueInst::getIndexedType(IVI.getAggregateOperand()->getType(),
|
||||
IVI.idx_begin(), IVI.idx_end()) ==
|
||||
IVI.getIndices()) ==
|
||||
IVI.getOperand(1)->getType(),
|
||||
"Invalid InsertValueInst operands!", &IVI);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user