mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
improve comments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0b09e12bc7
commit
a001b66498
@ -148,14 +148,27 @@ FunctionPass *llvm::createScalarReplAggregatesPass(signed int Threshold) {
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
/// ConvertToScalarInfo - This struct is used by CanConvertToScalar
|
/// ConvertToScalarInfo - This class implements the "Convert To Scalar"
|
||||||
|
/// optimization, which scans the uses of an alloca and determines if it can
|
||||||
|
/// rewrite it in terms of a single new alloca that can be mem2reg'd.
|
||||||
class ConvertToScalarInfo {
|
class ConvertToScalarInfo {
|
||||||
/// AllocaSize - The size of the alloca being considered.
|
/// AllocaSize - The size of the alloca being considered.
|
||||||
unsigned AllocaSize;
|
unsigned AllocaSize;
|
||||||
const TargetData &TD;
|
const TargetData &TD;
|
||||||
|
|
||||||
|
/// IsNotTrivial - This is set to true if there is somee access to the object
|
||||||
|
/// which means that mem2reg can't promote it.
|
||||||
bool IsNotTrivial;
|
bool IsNotTrivial;
|
||||||
|
|
||||||
|
/// VectorTy - This tracks the type that we should promote the vector to if
|
||||||
|
/// it is possible to turn it into a vector. This starts out null, and if it
|
||||||
|
/// isn't possible to turn into a vector type, it gets set to VoidTy.
|
||||||
const Type *VectorTy;
|
const Type *VectorTy;
|
||||||
|
|
||||||
|
/// HadAVector - True if there is at least one vector access to the alloca.
|
||||||
|
/// We don't want to turn random arrays into vectors and use vector element
|
||||||
|
/// insert/extract, but if there are element accesses to something that is
|
||||||
|
/// also declared as a vector, we do want to promote to a vector.
|
||||||
bool HadAVector;
|
bool HadAVector;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -166,33 +179,7 @@ public:
|
|||||||
HadAVector = false;
|
HadAVector = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocaInst *TryConvert(AllocaInst *AI) {
|
AllocaInst *TryConvert(AllocaInst *AI);
|
||||||
// If we can't convert this scalar, or if mem2reg can trivially do it, bail
|
|
||||||
// out.
|
|
||||||
if (!CanConvertToScalar(AI, 0) || !IsNotTrivial)
|
|
||||||
// FIXME: In the trivial case, just use mem2reg.
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If we were able to find a vector type that can handle this with
|
|
||||||
// insert/extract elements, and if there was at least one use that had
|
|
||||||
// a vector type, promote this to a vector. We don't want to promote
|
|
||||||
// random stuff that doesn't use vectors (e.g. <9 x double>) because then
|
|
||||||
// we just get a lot of insert/extracts. If at least one vector is
|
|
||||||
// involved, then we probably really do have a union of vector/array.
|
|
||||||
const Type *NewTy;
|
|
||||||
if (VectorTy && VectorTy->isVectorTy() && HadAVector) {
|
|
||||||
DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = "
|
|
||||||
<< *VectorTy << '\n');
|
|
||||||
NewTy = VectorTy; // Use the vector type.
|
|
||||||
} else {
|
|
||||||
DEBUG(dbgs() << "CONVERT TO SCALAR INTEGER: " << *AI << "\n");
|
|
||||||
// Create and insert the integer alloca.
|
|
||||||
NewTy = IntegerType::get(AI->getContext(), AllocaSize*8);
|
|
||||||
}
|
|
||||||
AllocaInst *NewAI = new AllocaInst(NewTy, 0, "", AI->getParent()->begin());
|
|
||||||
ConvertUsesToScalar(AI, NewAI, 0);
|
|
||||||
return NewAI;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CanConvertToScalar(Value *V, uint64_t Offset);
|
bool CanConvertToScalar(Value *V, uint64_t Offset);
|
||||||
@ -206,8 +193,38 @@ private:
|
|||||||
};
|
};
|
||||||
} // end anonymous namespace.
|
} // end anonymous namespace.
|
||||||
|
|
||||||
/// MergeInType - Add the 'In' type to the accumulated type (Accum) so far at
|
/// TryConvert - Analyze the specified alloca, and if it is safe to do so,
|
||||||
/// the offset specified by Offset (which is specified in bytes).
|
/// rewrite it to be a new alloca which is mem2reg'able. This returns the new
|
||||||
|
/// alloca if possible or null if not.
|
||||||
|
AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) {
|
||||||
|
// If we can't convert this scalar, or if mem2reg can trivially do it, bail
|
||||||
|
// out.
|
||||||
|
if (!CanConvertToScalar(AI, 0) || !IsNotTrivial)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// If we were able to find a vector type that can handle this with
|
||||||
|
// insert/extract elements, and if there was at least one use that had
|
||||||
|
// a vector type, promote this to a vector. We don't want to promote
|
||||||
|
// random stuff that doesn't use vectors (e.g. <9 x double>) because then
|
||||||
|
// we just get a lot of insert/extracts. If at least one vector is
|
||||||
|
// involved, then we probably really do have a union of vector/array.
|
||||||
|
const Type *NewTy;
|
||||||
|
if (VectorTy && VectorTy->isVectorTy() && HadAVector) {
|
||||||
|
DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = "
|
||||||
|
<< *VectorTy << '\n');
|
||||||
|
NewTy = VectorTy; // Use the vector type.
|
||||||
|
} else {
|
||||||
|
DEBUG(dbgs() << "CONVERT TO SCALAR INTEGER: " << *AI << "\n");
|
||||||
|
// Create and insert the integer alloca.
|
||||||
|
NewTy = IntegerType::get(AI->getContext(), AllocaSize*8);
|
||||||
|
}
|
||||||
|
AllocaInst *NewAI = new AllocaInst(NewTy, 0, "", AI->getParent()->begin());
|
||||||
|
ConvertUsesToScalar(AI, NewAI, 0);
|
||||||
|
return NewAI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MergeInType - Add the 'In' type to the accumulated vector type (VectorTy)
|
||||||
|
/// so far at the offset specified by Offset (which is specified in bytes).
|
||||||
///
|
///
|
||||||
/// There are two cases we handle here:
|
/// There are two cases we handle here:
|
||||||
/// 1) A union of vector types of the same size and potentially its elements.
|
/// 1) A union of vector types of the same size and potentially its elements.
|
||||||
@ -216,11 +233,11 @@ private:
|
|||||||
/// into a <4 x float> that uses insert element.
|
/// into a <4 x float> that uses insert element.
|
||||||
/// 2) A fully general blob of memory, which we turn into some (potentially
|
/// 2) A fully general blob of memory, which we turn into some (potentially
|
||||||
/// large) integer type with extract and insert operations where the loads
|
/// large) integer type with extract and insert operations where the loads
|
||||||
/// and stores would mutate the memory.
|
/// and stores would mutate the memory. We mark this by setting VectorTy
|
||||||
|
/// to VoidTy.
|
||||||
void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset) {
|
void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset) {
|
||||||
// Remember if we saw a vector type.
|
// If we already decided to turn this into a blob of integer memory, there is
|
||||||
HadAVector |= In->isVectorTy();
|
// nothing to be done.
|
||||||
|
|
||||||
if (VectorTy && VectorTy->isVoidTy())
|
if (VectorTy && VectorTy->isVoidTy())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -229,10 +246,15 @@ void ConvertToScalarInfo::MergeInType(const Type *In, uint64_t Offset) {
|
|||||||
// If the In type is a vector that is the same size as the alloca, see if it
|
// If the In type is a vector that is the same size as the alloca, see if it
|
||||||
// matches the existing VecTy.
|
// matches the existing VecTy.
|
||||||
if (const VectorType *VInTy = dyn_cast<VectorType>(In)) {
|
if (const VectorType *VInTy = dyn_cast<VectorType>(In)) {
|
||||||
|
// Remember if we saw a vector type.
|
||||||
|
HadAVector = true;
|
||||||
|
|
||||||
if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) {
|
if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) {
|
||||||
// If we're storing/loading a vector of the right size, allow it as a
|
// If we're storing/loading a vector of the right size, allow it as a
|
||||||
// vector. If this the first vector we see, remember the type so that
|
// vector. If this the first vector we see, remember the type so that
|
||||||
// we know the element size.
|
// we know the element size. If this is a subsequent access, ignore it
|
||||||
|
// even if it is a differing type but the same size. Worst case we can
|
||||||
|
// bitcast the resultant vectors.
|
||||||
if (VectorTy == 0)
|
if (VectorTy == 0)
|
||||||
VectorTy = VInTy;
|
VectorTy = VInTy;
|
||||||
return;
|
return;
|
||||||
@ -288,9 +310,9 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t Offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
|
if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
|
||||||
|
IsNotTrivial = true; // Can't be mem2reg'd.
|
||||||
if (!CanConvertToScalar(BCI, Offset))
|
if (!CanConvertToScalar(BCI, Offset))
|
||||||
return false;
|
return false;
|
||||||
IsNotTrivial = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +328,7 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t Offset) {
|
|||||||
// See if all uses can be converted.
|
// See if all uses can be converted.
|
||||||
if (!CanConvertToScalar(GEP, Offset+GEPOffset))
|
if (!CanConvertToScalar(GEP, Offset+GEPOffset))
|
||||||
return false;
|
return false;
|
||||||
IsNotTrivial = true;
|
IsNotTrivial = true; // Can't be mem2reg'd.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,21 +336,22 @@ bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t Offset) {
|
|||||||
// handle it.
|
// handle it.
|
||||||
if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
|
if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
|
||||||
// Store of constant value and constant size.
|
// Store of constant value and constant size.
|
||||||
if (isa<ConstantInt>(MSI->getValue()) &&
|
if (!isa<ConstantInt>(MSI->getValue()) ||
|
||||||
isa<ConstantInt>(MSI->getLength())) {
|
!isa<ConstantInt>(MSI->getLength()))
|
||||||
IsNotTrivial = true;
|
return false;
|
||||||
continue;
|
IsNotTrivial = true; // Can't be mem2reg'd.
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a memcpy or memmove into or out of the whole allocation, we
|
// If this is a memcpy or memmove into or out of the whole allocation, we
|
||||||
// can handle it like a load or store of the scalar type.
|
// can handle it like a load or store of the scalar type.
|
||||||
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(User)) {
|
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(User)) {
|
||||||
if (ConstantInt *Len = dyn_cast<ConstantInt>(MTI->getLength()))
|
ConstantInt *Len = dyn_cast<ConstantInt>(MTI->getLength());
|
||||||
if (Len->getZExtValue() == AllocaSize && Offset == 0) {
|
if (Len == 0 || Len->getZExtValue() != AllocaSize || Offset != 0)
|
||||||
IsNotTrivial = true;
|
return false;
|
||||||
continue;
|
|
||||||
}
|
IsNotTrivial = true; // Can't be mem2reg'd.
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we cannot handle this!
|
// Otherwise, we cannot handle this!
|
||||||
|
Loading…
Reference in New Issue
Block a user