mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Remove CompositeType class.
The existence of the class is more confusing than helpful, I think; the commonality is mostly just "GEP is legal", which can be queried using APIs on GetElementPtrInst. Differential Revision: https://reviews.llvm.org/D75660
This commit is contained in:
parent
9b17097170
commit
3d34a8c48c
@ -392,7 +392,7 @@ public:
|
|||||||
/// use operands.
|
/// use operands.
|
||||||
class ConstantAggregate : public Constant {
|
class ConstantAggregate : public Constant {
|
||||||
protected:
|
protected:
|
||||||
ConstantAggregate(CompositeType *T, ValueTy VT, ArrayRef<Constant *> V);
|
ConstantAggregate(Type *T, ValueTy VT, ArrayRef<Constant *> V);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Transparently provide more efficient getOperand methods.
|
/// Transparently provide more efficient getOperand methods.
|
||||||
|
@ -195,26 +195,6 @@ private:
|
|||||||
Value *Callee = nullptr;
|
Value *Callee = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Common super class of ArrayType, StructType and VectorType.
|
|
||||||
class CompositeType : public Type {
|
|
||||||
protected:
|
|
||||||
explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Given an index value into the type, return the type of the element.
|
|
||||||
Type *getTypeAtIndex(const Value *V) const;
|
|
||||||
Type *getTypeAtIndex(unsigned Idx) const;
|
|
||||||
bool indexValid(const Value *V) const;
|
|
||||||
bool indexValid(unsigned Idx) const;
|
|
||||||
|
|
||||||
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
|
||||||
static bool classof(const Type *T) {
|
|
||||||
return T->getTypeID() == ArrayTyID ||
|
|
||||||
T->getTypeID() == StructTyID ||
|
|
||||||
T->getTypeID() == VectorTyID;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Class to represent struct types. There are two different kinds of struct
|
/// Class to represent struct types. There are two different kinds of struct
|
||||||
/// types: Literal structs and Identified structs.
|
/// types: Literal structs and Identified structs.
|
||||||
///
|
///
|
||||||
@ -235,8 +215,8 @@ public:
|
|||||||
/// elements as defined by DataLayout (which is required to match what the code
|
/// elements as defined by DataLayout (which is required to match what the code
|
||||||
/// generator for a target expects).
|
/// generator for a target expects).
|
||||||
///
|
///
|
||||||
class StructType : public CompositeType {
|
class StructType : public Type {
|
||||||
StructType(LLVMContext &C) : CompositeType(C, StructTyID) {}
|
StructType(LLVMContext &C) : Type(C, StructTyID) {}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/// This is the contents of the SubClassData field.
|
/// This is the contents of the SubClassData field.
|
||||||
@ -350,6 +330,11 @@ public:
|
|||||||
assert(N < NumContainedTys && "Element number out of range!");
|
assert(N < NumContainedTys && "Element number out of range!");
|
||||||
return ContainedTys[N];
|
return ContainedTys[N];
|
||||||
}
|
}
|
||||||
|
/// Given an index value into the type, return the type of the element.
|
||||||
|
Type *getTypeAtIndex(const Value *V) const;
|
||||||
|
Type *getTypeAtIndex(unsigned N) const { return getElementType(N); }
|
||||||
|
bool indexValid(const Value *V) const;
|
||||||
|
bool indexValid(unsigned Idx) const { return Idx < getNumElements(); }
|
||||||
|
|
||||||
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||||
static bool classof(const Type *T) {
|
static bool classof(const Type *T) {
|
||||||
@ -375,13 +360,13 @@ Type *Type::getStructElementType(unsigned N) const {
|
|||||||
/// for use of SIMD instructions. SequentialType holds the common features of
|
/// for use of SIMD instructions. SequentialType holds the common features of
|
||||||
/// both, which stem from the fact that both lay their components out in memory
|
/// both, which stem from the fact that both lay their components out in memory
|
||||||
/// identically.
|
/// identically.
|
||||||
class SequentialType : public CompositeType {
|
class SequentialType : public Type {
|
||||||
Type *ContainedType; ///< Storage for the single contained type.
|
Type *ContainedType; ///< Storage for the single contained type.
|
||||||
uint64_t NumElements;
|
uint64_t NumElements;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SequentialType(TypeID TID, Type *ElType, uint64_t NumElements)
|
SequentialType(TypeID TID, Type *ElType, uint64_t NumElements)
|
||||||
: CompositeType(ElType->getContext(), TID), ContainedType(ElType),
|
: Type(ElType->getContext(), TID), ContainedType(ElType),
|
||||||
NumElements(NumElements) {
|
NumElements(NumElements) {
|
||||||
ContainedTys = &ContainedType;
|
ContainedTys = &ContainedType;
|
||||||
NumContainedTys = 1;
|
NumContainedTys = 1;
|
||||||
|
@ -1008,16 +1008,23 @@ public:
|
|||||||
return getPointerAddressSpace();
|
return getPointerAddressSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of the element that would be loaded with
|
/// Returns the result type of a getelementptr with the given source
|
||||||
/// a load instruction with the specified parameters.
|
/// element type and indexes.
|
||||||
///
|
///
|
||||||
/// Null is returned if the indices are invalid for the specified
|
/// Null is returned if the indices are invalid for the specified
|
||||||
/// pointer type.
|
/// source element type.
|
||||||
///
|
|
||||||
static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
|
static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
|
||||||
static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
|
static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
|
||||||
static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
|
static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
|
||||||
|
|
||||||
|
/// Return the type of the element at the given index of an indexable
|
||||||
|
/// type. This is equivalent to "getIndexedType(Agg, {Zero, Idx})".
|
||||||
|
///
|
||||||
|
/// Returns null if the type can't be indexed, or the given index is not
|
||||||
|
/// legal for the given type.
|
||||||
|
static Type *getTypeAtIndex(Type *Ty, Value *Idx);
|
||||||
|
static Type *getTypeAtIndex(Type *Ty, uint64_t Idx);
|
||||||
|
|
||||||
inline op_iterator idx_begin() { return op_begin()+1; }
|
inline op_iterator idx_begin() { return op_begin()+1; }
|
||||||
inline const_op_iterator idx_begin() const { return op_begin()+1; }
|
inline const_op_iterator idx_begin() const { return op_begin()+1; }
|
||||||
inline op_iterator idx_end() { return op_end(); }
|
inline op_iterator idx_end() { return op_end(); }
|
||||||
|
@ -395,7 +395,7 @@ static bool slotOnlyDiscardsData(const Value *RetVal, const Value *CallVal,
|
|||||||
|
|
||||||
/// For an aggregate type, determine whether a given index is within bounds or
|
/// For an aggregate type, determine whether a given index is within bounds or
|
||||||
/// not.
|
/// not.
|
||||||
static bool indexReallyValid(CompositeType *T, unsigned Idx) {
|
static bool indexReallyValid(Type *T, unsigned Idx) {
|
||||||
if (ArrayType *AT = dyn_cast<ArrayType>(T))
|
if (ArrayType *AT = dyn_cast<ArrayType>(T))
|
||||||
return Idx < AT->getNumElements();
|
return Idx < AT->getNumElements();
|
||||||
|
|
||||||
@ -419,7 +419,7 @@ static bool indexReallyValid(CompositeType *T, unsigned Idx) {
|
|||||||
/// function again on a finished iterator will repeatedly return
|
/// function again on a finished iterator will repeatedly return
|
||||||
/// false. SubTypes.back()->getTypeAtIndex(Path.back()) is either an empty
|
/// false. SubTypes.back()->getTypeAtIndex(Path.back()) is either an empty
|
||||||
/// aggregate or a non-aggregate
|
/// aggregate or a non-aggregate
|
||||||
static bool advanceToNextLeafType(SmallVectorImpl<CompositeType *> &SubTypes,
|
static bool advanceToNextLeafType(SmallVectorImpl<Type *> &SubTypes,
|
||||||
SmallVectorImpl<unsigned> &Path) {
|
SmallVectorImpl<unsigned> &Path) {
|
||||||
// First march back up the tree until we can successfully increment one of the
|
// First march back up the tree until we can successfully increment one of the
|
||||||
// coordinates in Path.
|
// coordinates in Path.
|
||||||
@ -435,16 +435,16 @@ static bool advanceToNextLeafType(SmallVectorImpl<CompositeType *> &SubTypes,
|
|||||||
// We know there's *some* valid leaf now, so march back down the tree picking
|
// We know there's *some* valid leaf now, so march back down the tree picking
|
||||||
// out the left-most element at each node.
|
// out the left-most element at each node.
|
||||||
++Path.back();
|
++Path.back();
|
||||||
Type *DeeperType = SubTypes.back()->getTypeAtIndex(Path.back());
|
Type *DeeperType =
|
||||||
|
ExtractValueInst::getIndexedType(SubTypes.back(), Path.back());
|
||||||
while (DeeperType->isAggregateType()) {
|
while (DeeperType->isAggregateType()) {
|
||||||
CompositeType *CT = cast<CompositeType>(DeeperType);
|
if (!indexReallyValid(DeeperType, 0))
|
||||||
if (!indexReallyValid(CT, 0))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
SubTypes.push_back(CT);
|
SubTypes.push_back(DeeperType);
|
||||||
Path.push_back(0);
|
Path.push_back(0);
|
||||||
|
|
||||||
DeeperType = CT->getTypeAtIndex(0U);
|
DeeperType = ExtractValueInst::getIndexedType(DeeperType, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -460,17 +460,15 @@ static bool advanceToNextLeafType(SmallVectorImpl<CompositeType *> &SubTypes,
|
|||||||
/// For example, if Next was {[0 x i64], {{}, i32, {}}, i32} then we would setup
|
/// For example, if Next was {[0 x i64], {{}, i32, {}}, i32} then we would setup
|
||||||
/// Path as [1, 1] and SubTypes as [Next, {{}, i32, {}}] to represent the first
|
/// Path as [1, 1] and SubTypes as [Next, {{}, i32, {}}] to represent the first
|
||||||
/// i32 in that type.
|
/// i32 in that type.
|
||||||
static bool firstRealType(Type *Next,
|
static bool firstRealType(Type *Next, SmallVectorImpl<Type *> &SubTypes,
|
||||||
SmallVectorImpl<CompositeType *> &SubTypes,
|
|
||||||
SmallVectorImpl<unsigned> &Path) {
|
SmallVectorImpl<unsigned> &Path) {
|
||||||
// First initialise the iterator components to the first "leaf" node
|
// First initialise the iterator components to the first "leaf" node
|
||||||
// (i.e. node with no valid sub-type at any index, so {} does count as a leaf
|
// (i.e. node with no valid sub-type at any index, so {} does count as a leaf
|
||||||
// despite nominally being an aggregate).
|
// despite nominally being an aggregate).
|
||||||
while (Next->isAggregateType() &&
|
while (Type *FirstInner = ExtractValueInst::getIndexedType(Next, 0)) {
|
||||||
indexReallyValid(cast<CompositeType>(Next), 0)) {
|
SubTypes.push_back(Next);
|
||||||
SubTypes.push_back(cast<CompositeType>(Next));
|
|
||||||
Path.push_back(0);
|
Path.push_back(0);
|
||||||
Next = cast<CompositeType>(Next)->getTypeAtIndex(0U);
|
Next = FirstInner;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's no Path now, Next was originally scalar already (or empty
|
// If there's no Path now, Next was originally scalar already (or empty
|
||||||
@ -480,7 +478,8 @@ static bool firstRealType(Type *Next,
|
|||||||
|
|
||||||
// Otherwise, use normal iteration to keep looking through the tree until we
|
// Otherwise, use normal iteration to keep looking through the tree until we
|
||||||
// find a non-aggregate type.
|
// find a non-aggregate type.
|
||||||
while (SubTypes.back()->getTypeAtIndex(Path.back())->isAggregateType()) {
|
while (ExtractValueInst::getIndexedType(SubTypes.back(), Path.back())
|
||||||
|
->isAggregateType()) {
|
||||||
if (!advanceToNextLeafType(SubTypes, Path))
|
if (!advanceToNextLeafType(SubTypes, Path))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -490,14 +489,15 @@ static bool firstRealType(Type *Next,
|
|||||||
|
|
||||||
/// Set the iterator data-structures to the next non-empty, non-aggregate
|
/// Set the iterator data-structures to the next non-empty, non-aggregate
|
||||||
/// subtype.
|
/// subtype.
|
||||||
static bool nextRealType(SmallVectorImpl<CompositeType *> &SubTypes,
|
static bool nextRealType(SmallVectorImpl<Type *> &SubTypes,
|
||||||
SmallVectorImpl<unsigned> &Path) {
|
SmallVectorImpl<unsigned> &Path) {
|
||||||
do {
|
do {
|
||||||
if (!advanceToNextLeafType(SubTypes, Path))
|
if (!advanceToNextLeafType(SubTypes, Path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(!Path.empty() && "found a leaf but didn't set the path?");
|
assert(!Path.empty() && "found a leaf but didn't set the path?");
|
||||||
} while (SubTypes.back()->getTypeAtIndex(Path.back())->isAggregateType());
|
} while (ExtractValueInst::getIndexedType(SubTypes.back(), Path.back())
|
||||||
|
->isAggregateType());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -669,7 +669,7 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SmallVector<unsigned, 4> RetPath, CallPath;
|
SmallVector<unsigned, 4> RetPath, CallPath;
|
||||||
SmallVector<CompositeType *, 4> RetSubTypes, CallSubTypes;
|
SmallVector<Type *, 4> RetSubTypes, CallSubTypes;
|
||||||
|
|
||||||
bool RetEmpty = !firstRealType(RetVal->getType(), RetSubTypes, RetPath);
|
bool RetEmpty = !firstRealType(RetVal->getType(), RetSubTypes, RetPath);
|
||||||
bool CallEmpty = !firstRealType(CallVal->getType(), CallSubTypes, CallPath);
|
bool CallEmpty = !firstRealType(CallVal->getType(), CallSubTypes, CallPath);
|
||||||
@ -692,7 +692,8 @@ bool llvm::returnTypeIsEligibleForTailCall(const Function *F,
|
|||||||
// We've exhausted the values produced by the tail call instruction, the
|
// We've exhausted the values produced by the tail call instruction, the
|
||||||
// rest are essentially undef. The type doesn't really matter, but we need
|
// rest are essentially undef. The type doesn't really matter, but we need
|
||||||
// *something*.
|
// *something*.
|
||||||
Type *SlotType = RetSubTypes.back()->getTypeAtIndex(RetPath.back());
|
Type *SlotType =
|
||||||
|
ExtractValueInst::getIndexedType(RetSubTypes.back(), RetPath.back());
|
||||||
CallVal = UndefValue::get(SlotType);
|
CallVal = UndefValue::get(SlotType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,20 +244,24 @@ static SourcePred matchScalarInAggregate() {
|
|||||||
|
|
||||||
static SourcePred validInsertValueIndex() {
|
static SourcePred validInsertValueIndex() {
|
||||||
auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
|
auto Pred = [](ArrayRef<Value *> Cur, const Value *V) {
|
||||||
auto *CTy = cast<CompositeType>(Cur[0]->getType());
|
|
||||||
if (auto *CI = dyn_cast<ConstantInt>(V))
|
if (auto *CI = dyn_cast<ConstantInt>(V))
|
||||||
if (CI->getBitWidth() == 32 &&
|
if (CI->getBitWidth() == 32) {
|
||||||
CTy->getTypeAtIndex(CI->getZExtValue()) == Cur[1]->getType())
|
Type *Indexed = ExtractValueInst::getIndexedType(Cur[0]->getType(),
|
||||||
return true;
|
CI->getZExtValue());
|
||||||
|
return Indexed == Cur[1]->getType();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *> Ts) {
|
auto Make = [](ArrayRef<Value *> Cur, ArrayRef<Type *> Ts) {
|
||||||
std::vector<Constant *> Result;
|
std::vector<Constant *> Result;
|
||||||
auto *Int32Ty = Type::getInt32Ty(Cur[0]->getContext());
|
auto *Int32Ty = Type::getInt32Ty(Cur[0]->getContext());
|
||||||
auto *CTy = cast<CompositeType>(Cur[0]->getType());
|
auto *BaseTy = Cur[0]->getType();
|
||||||
for (int I = 0, E = getAggregateNumElements(CTy); I < E; ++I)
|
int I = 0;
|
||||||
if (CTy->getTypeAtIndex(I) == Cur[1]->getType())
|
while (Type *Indexed = ExtractValueInst::getIndexedType(BaseTy, I)) {
|
||||||
|
if (Indexed == Cur[1]->getType())
|
||||||
Result.push_back(ConstantInt::get(Int32Ty, I));
|
Result.push_back(ConstantInt::get(Int32Ty, I));
|
||||||
|
++I;
|
||||||
|
}
|
||||||
return Result;
|
return Result;
|
||||||
};
|
};
|
||||||
return {Pred, Make};
|
return {Pred, Make};
|
||||||
|
@ -2389,10 +2389,11 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
|
|||||||
SmallVector<Constant *, 8> NewIdxs;
|
SmallVector<Constant *, 8> NewIdxs;
|
||||||
Type *Ty = PointeeTy;
|
Type *Ty = PointeeTy;
|
||||||
Type *Prev = C->getType();
|
Type *Prev = C->getType();
|
||||||
|
auto GEPIter = gep_type_begin(PointeeTy, Idxs);
|
||||||
bool Unknown =
|
bool Unknown =
|
||||||
!isa<ConstantInt>(Idxs[0]) && !isa<ConstantDataVector>(Idxs[0]);
|
!isa<ConstantInt>(Idxs[0]) && !isa<ConstantDataVector>(Idxs[0]);
|
||||||
for (unsigned i = 1, e = Idxs.size(); i != e;
|
for (unsigned i = 1, e = Idxs.size(); i != e;
|
||||||
Prev = Ty, Ty = cast<CompositeType>(Ty)->getTypeAtIndex(Idxs[i]), ++i) {
|
Prev = Ty, Ty = (++GEPIter).getIndexedType(), ++i) {
|
||||||
if (!isa<ConstantInt>(Idxs[i]) && !isa<ConstantDataVector>(Idxs[i])) {
|
if (!isa<ConstantInt>(Idxs[i]) && !isa<ConstantDataVector>(Idxs[i])) {
|
||||||
// We don't know if it's in range or not.
|
// We don't know if it's in range or not.
|
||||||
Unknown = true;
|
Unknown = true;
|
||||||
|
@ -1047,19 +1047,20 @@ static Constant *getSequenceIfElementsMatch(Constant *C,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantAggregate::ConstantAggregate(CompositeType *T, ValueTy VT,
|
ConstantAggregate::ConstantAggregate(Type *T, ValueTy VT,
|
||||||
ArrayRef<Constant *> V)
|
ArrayRef<Constant *> V)
|
||||||
: Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
|
: Constant(T, VT, OperandTraits<ConstantAggregate>::op_end(this) - V.size(),
|
||||||
V.size()) {
|
V.size()) {
|
||||||
llvm::copy(V, op_begin());
|
llvm::copy(V, op_begin());
|
||||||
|
|
||||||
// Check that types match, unless this is an opaque struct.
|
// Check that types match, unless this is an opaque struct.
|
||||||
if (auto *ST = dyn_cast<StructType>(T))
|
if (auto *ST = dyn_cast<StructType>(T)) {
|
||||||
if (ST->isOpaque())
|
if (ST->isOpaque())
|
||||||
return;
|
return;
|
||||||
for (unsigned I = 0, E = V.size(); I != E; ++I)
|
for (unsigned I = 0, E = V.size(); I != E; ++I)
|
||||||
assert(V[I]->getType() == T->getTypeAtIndex(I) &&
|
assert(V[I]->getType() == ST->getTypeAtIndex(I) &&
|
||||||
"Initializer for composite element doesn't match!");
|
"Initializer for struct element doesn't match!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
|
ConstantArray::ConstantArray(ArrayType *T, ArrayRef<Constant *> V)
|
||||||
|
@ -1659,35 +1659,44 @@ GetElementPtrInst::GetElementPtrInst(const GetElementPtrInst &GEPI)
|
|||||||
SubclassOptionalData = GEPI.SubclassOptionalData;
|
SubclassOptionalData = GEPI.SubclassOptionalData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getIndexedType - Returns the type of the element that would be accessed with
|
Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, Value *Idx) {
|
||||||
/// a gep instruction with the specified parameters.
|
if (auto Struct = dyn_cast<StructType>(Ty)) {
|
||||||
///
|
if (!Struct->indexValid(Idx))
|
||||||
/// The Idxs pointer should point to a continuous piece of memory containing the
|
|
||||||
/// indices, either as Value* or uint64_t.
|
|
||||||
///
|
|
||||||
/// A null type is returned if the indices are invalid for the specified
|
|
||||||
/// pointer type.
|
|
||||||
///
|
|
||||||
template <typename IndexTy>
|
|
||||||
static Type *getIndexedTypeInternal(Type *Agg, ArrayRef<IndexTy> IdxList) {
|
|
||||||
// Handle the special case of the empty set index set, which is always valid.
|
|
||||||
if (IdxList.empty())
|
|
||||||
return Agg;
|
|
||||||
|
|
||||||
// If there is at least one index, the top level type must be sized, otherwise
|
|
||||||
// it cannot be 'stepped over'.
|
|
||||||
if (!Agg->isSized())
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
return Struct->getTypeAtIndex(Idx);
|
||||||
unsigned CurIdx = 1;
|
|
||||||
for (; CurIdx != IdxList.size(); ++CurIdx) {
|
|
||||||
CompositeType *CT = dyn_cast<CompositeType>(Agg);
|
|
||||||
if (!CT || CT->isPointerTy()) return nullptr;
|
|
||||||
IndexTy Index = IdxList[CurIdx];
|
|
||||||
if (!CT->indexValid(Index)) return nullptr;
|
|
||||||
Agg = CT->getTypeAtIndex(Index);
|
|
||||||
}
|
}
|
||||||
return CurIdx == IdxList.size() ? Agg : nullptr;
|
if (!Idx->getType()->isIntOrIntVectorTy())
|
||||||
|
return nullptr;
|
||||||
|
if (auto Array = dyn_cast<ArrayType>(Ty))
|
||||||
|
return Array->getElementType();
|
||||||
|
if (auto Vector = dyn_cast<VectorType>(Ty))
|
||||||
|
return Vector->getElementType();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type *GetElementPtrInst::getTypeAtIndex(Type *Ty, uint64_t Idx) {
|
||||||
|
if (auto Struct = dyn_cast<StructType>(Ty)) {
|
||||||
|
if (Idx >= Struct->getNumElements())
|
||||||
|
return nullptr;
|
||||||
|
return Struct->getElementType(Idx);
|
||||||
|
}
|
||||||
|
if (auto Array = dyn_cast<ArrayType>(Ty))
|
||||||
|
return Array->getElementType();
|
||||||
|
if (auto Vector = dyn_cast<VectorType>(Ty))
|
||||||
|
return Vector->getElementType();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IndexTy>
|
||||||
|
static Type *getIndexedTypeInternal(Type *Ty, ArrayRef<IndexTy> IdxList) {
|
||||||
|
if (IdxList.empty())
|
||||||
|
return Ty;
|
||||||
|
for (IndexTy V : IdxList.slice(1)) {
|
||||||
|
Ty = GetElementPtrInst::getTypeAtIndex(Ty, V);
|
||||||
|
if (!Ty)
|
||||||
|
return Ty;
|
||||||
|
}
|
||||||
|
return Ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) {
|
Type *GetElementPtrInst::getIndexedType(Type *Ty, ArrayRef<Value *> IdxList) {
|
||||||
@ -2220,15 +2229,15 @@ Type *ExtractValueInst::getIndexedType(Type *Agg,
|
|||||||
if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) {
|
if (ArrayType *AT = dyn_cast<ArrayType>(Agg)) {
|
||||||
if (Index >= AT->getNumElements())
|
if (Index >= AT->getNumElements())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Agg = AT->getElementType();
|
||||||
} else if (StructType *ST = dyn_cast<StructType>(Agg)) {
|
} else if (StructType *ST = dyn_cast<StructType>(Agg)) {
|
||||||
if (Index >= ST->getNumElements())
|
if (Index >= ST->getNumElements())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Agg = ST->getElementType(Index);
|
||||||
} else {
|
} else {
|
||||||
// Not a valid type to index into.
|
// Not a valid type to index into.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Agg = cast<CompositeType>(Agg)->getTypeAtIndex(Index);
|
|
||||||
}
|
}
|
||||||
return const_cast<Type*>(Agg);
|
return const_cast<Type*>(Agg);
|
||||||
}
|
}
|
||||||
|
@ -529,32 +529,13 @@ StructType *Module::getTypeByName(StringRef Name) const {
|
|||||||
return getContext().pImpl->NamedStructTypes.lookup(Name);
|
return getContext().pImpl->NamedStructTypes.lookup(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
Type *StructType::getTypeAtIndex(const Value *V) const {
|
||||||
// CompositeType Implementation
|
unsigned Idx = (unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
Type *CompositeType::getTypeAtIndex(const Value *V) const {
|
|
||||||
if (auto *STy = dyn_cast<StructType>(this)) {
|
|
||||||
unsigned Idx =
|
|
||||||
(unsigned)cast<Constant>(V)->getUniqueInteger().getZExtValue();
|
|
||||||
assert(indexValid(Idx) && "Invalid structure index!");
|
assert(indexValid(Idx) && "Invalid structure index!");
|
||||||
return STy->getElementType(Idx);
|
return getElementType(Idx);
|
||||||
}
|
|
||||||
|
|
||||||
return cast<SequentialType>(this)->getElementType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *CompositeType::getTypeAtIndex(unsigned Idx) const{
|
bool StructType::indexValid(const Value *V) const {
|
||||||
if (auto *STy = dyn_cast<StructType>(this)) {
|
|
||||||
assert(indexValid(Idx) && "Invalid structure index!");
|
|
||||||
return STy->getElementType(Idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cast<SequentialType>(this)->getElementType();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CompositeType::indexValid(const Value *V) const {
|
|
||||||
if (auto *STy = dyn_cast<StructType>(this)) {
|
|
||||||
// Structure indexes require (vectors of) 32-bit integer constants. In the
|
// Structure indexes require (vectors of) 32-bit integer constants. In the
|
||||||
// vector case all of the indices must be equal.
|
// vector case all of the indices must be equal.
|
||||||
if (!V->getType()->isIntOrIntVectorTy(32))
|
if (!V->getType()->isIntOrIntVectorTy(32))
|
||||||
@ -563,18 +544,7 @@ bool CompositeType::indexValid(const Value *V) const {
|
|||||||
if (C && V->getType()->isVectorTy())
|
if (C && V->getType()->isVectorTy())
|
||||||
C = C->getSplatValue();
|
C = C->getSplatValue();
|
||||||
const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C);
|
const ConstantInt *CU = dyn_cast_or_null<ConstantInt>(C);
|
||||||
return CU && CU->getZExtValue() < STy->getNumElements();
|
return CU && CU->getZExtValue() < getNumElements();
|
||||||
}
|
|
||||||
|
|
||||||
// Sequential types can be indexed by any integer.
|
|
||||||
return V->getType()->isIntOrIntVectorTy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CompositeType::indexValid(unsigned Idx) const {
|
|
||||||
if (auto *STy = dyn_cast<StructType>(this))
|
|
||||||
return Idx < STy->getNumElements();
|
|
||||||
// Sequential types can be indexed by any integer.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -17079,7 +17079,7 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
|
|||||||
case Intrinsic::arm_mve_vld4q: {
|
case Intrinsic::arm_mve_vld4q: {
|
||||||
Info.opc = ISD::INTRINSIC_W_CHAIN;
|
Info.opc = ISD::INTRINSIC_W_CHAIN;
|
||||||
// Conservatively set memVT to the entire set of vectors loaded.
|
// Conservatively set memVT to the entire set of vectors loaded.
|
||||||
Type *VecTy = cast<CompositeType>(I.getType())->getTypeAtIndex(1);
|
Type *VecTy = cast<StructType>(I.getType())->getElementType(1);
|
||||||
unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
|
unsigned Factor = Intrinsic == Intrinsic::arm_mve_vld2q ? 2 : 4;
|
||||||
Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
|
Info.memVT = EVT::getVectorVT(VecTy->getContext(), MVT::i64, Factor * 2);
|
||||||
Info.ptrVal = I.getArgOperand(0);
|
Info.ptrVal = I.getArgOperand(0);
|
||||||
|
@ -295,7 +295,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
|
|||||||
if (auto *ElPTy = dyn_cast<PointerType>(ElTy))
|
if (auto *ElPTy = dyn_cast<PointerType>(ElTy))
|
||||||
ElTy = ElPTy->getElementType();
|
ElTy = ElPTy->getElementType();
|
||||||
else
|
else
|
||||||
ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(II);
|
ElTy = GetElementPtrInst::getTypeAtIndex(ElTy, II);
|
||||||
}
|
}
|
||||||
// And create a GEP to extract those indices.
|
// And create a GEP to extract those indices.
|
||||||
V = IRB.CreateGEP(ArgIndex.first, V, Ops, V->getName() + ".idx");
|
V = IRB.CreateGEP(ArgIndex.first, V, Ops, V->getName() + ".idx");
|
||||||
@ -784,7 +784,7 @@ bool ArgumentPromotionPass::isDenselyPacked(Type *type, const DataLayout &DL) {
|
|||||||
if (DL.getTypeSizeInBits(type) != DL.getTypeAllocSizeInBits(type))
|
if (DL.getTypeSizeInBits(type) != DL.getTypeAllocSizeInBits(type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isa<CompositeType>(type))
|
if (!isa<StructType>(type) && !isa<SequentialType>(type))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// For homogenous sequential types, check for padding within members.
|
// For homogenous sequential types, check for padding within members.
|
||||||
|
@ -142,7 +142,7 @@ static bool isLeakCheckerRoot(GlobalVariable *GV) {
|
|||||||
E = STy->element_end(); I != E; ++I) {
|
E = STy->element_end(); I != E; ++I) {
|
||||||
Type *InnerTy = *I;
|
Type *InnerTy = *I;
|
||||||
if (isa<PointerType>(InnerTy)) return true;
|
if (isa<PointerType>(InnerTy)) return true;
|
||||||
if (isa<CompositeType>(InnerTy))
|
if (isa<StructType>(InnerTy) || isa<SequentialType>(InnerTy))
|
||||||
Types.push_back(InnerTy);
|
Types.push_back(InnerTy);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -147,10 +147,12 @@ static void RemoveDeadConstant(Constant *C) {
|
|||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
|
||||||
if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
|
if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
|
||||||
GV->eraseFromParent();
|
GV->eraseFromParent();
|
||||||
}
|
} else if (!isa<Function>(C)) {
|
||||||
else if (!isa<Function>(C))
|
// FIXME: Why does the type of the constant matter here?
|
||||||
if (isa<CompositeType>(C->getType()))
|
if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType()) ||
|
||||||
|
isa<VectorType>(C->getType()))
|
||||||
C->destroyConstant();
|
C->destroyConstant();
|
||||||
|
}
|
||||||
|
|
||||||
// If the constant referenced anything, see if we can delete it as well.
|
// If the constant referenced anything, see if we can delete it as well.
|
||||||
for (Constant *O : Operands)
|
for (Constant *O : Operands)
|
||||||
|
@ -2421,10 +2421,8 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
|
|||||||
// to a getelementptr X, 0, 0, 0... turn it into the appropriate gep.
|
// to a getelementptr X, 0, 0, 0... turn it into the appropriate gep.
|
||||||
// This can enhance SROA and other transforms that want type-safe pointers.
|
// This can enhance SROA and other transforms that want type-safe pointers.
|
||||||
unsigned NumZeros = 0;
|
unsigned NumZeros = 0;
|
||||||
while (SrcElTy != DstElTy &&
|
while (SrcElTy && SrcElTy != DstElTy) {
|
||||||
isa<CompositeType>(SrcElTy) && !SrcElTy->isPointerTy() &&
|
SrcElTy = GetElementPtrInst::getTypeAtIndex(SrcElTy, (uint64_t)0);
|
||||||
SrcElTy->getNumContainedTypes() /* not "{}" */) {
|
|
||||||
SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(0U);
|
|
||||||
++NumZeros;
|
++NumZeros;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1961,10 +1961,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
|
|||||||
if (J > 0) {
|
if (J > 0) {
|
||||||
if (J == 1) {
|
if (J == 1) {
|
||||||
CurTy = Op1->getSourceElementType();
|
CurTy = Op1->getSourceElementType();
|
||||||
} else if (auto *CT = dyn_cast<CompositeType>(CurTy)) {
|
|
||||||
CurTy = CT->getTypeAtIndex(Op1->getOperand(J));
|
|
||||||
} else {
|
} else {
|
||||||
CurTy = nullptr;
|
CurTy =
|
||||||
|
GetElementPtrInst::getTypeAtIndex(CurTy, Op1->getOperand(J));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3131,7 +3131,7 @@ unsigned BoUpSLP::canMapToVector(Type *T, const DataLayout &DL) const {
|
|||||||
unsigned N = 1;
|
unsigned N = 1;
|
||||||
Type *EltTy = T;
|
Type *EltTy = T;
|
||||||
|
|
||||||
while (isa<CompositeType>(EltTy)) {
|
while (isa<StructType>(EltTy) || isa<SequentialType>(EltTy)) {
|
||||||
if (auto *ST = dyn_cast<StructType>(EltTy)) {
|
if (auto *ST = dyn_cast<StructType>(EltTy)) {
|
||||||
// Check that struct is homogeneous.
|
// Check that struct is homogeneous.
|
||||||
for (const auto *Ty : ST->elements())
|
for (const auto *Ty : ST->elements())
|
||||||
|
Loading…
Reference in New Issue
Block a user