mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-13 08:35:46 +00:00
Make SROA produce a vector only when the alloca is actually
accessed at least once as a vector. This prevents it from compiling the example in not-a-vector into: define double @test(double %A, double %B) { %tmp4 = insertelement <7 x double> undef, double %A, i32 0 %tmp = insertelement <7 x double> %tmp4, double %B, i32 4 %tmp2 = extractelement <7 x double> %tmp, i32 4 ret double %tmp2 } instead, producing the integer code. Producing vectors when they aren't otherwise in the program is dangerous because a lot of other code treats them carefully and doesn't want to break them down. OTOH, many things want to break down tasty i448's. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63638 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
67e3ba3f1d
commit
1a3257bbf5
@ -126,7 +126,7 @@ namespace {
|
||||
SmallVector<AllocaInst*, 32> &NewElts);
|
||||
|
||||
bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
|
||||
uint64_t Offset, unsigned AllocaSize);
|
||||
bool &SawVec, uint64_t Offset, unsigned AllocaSize);
|
||||
void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
|
||||
Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
|
||||
uint64_t Offset);
|
||||
@ -281,10 +281,17 @@ bool SROA::performScalarRepl(Function &F) {
|
||||
// but that has pointer arithmetic to set byte 3 of it or something.
|
||||
bool IsNotTrivial = false;
|
||||
const Type *VectorTy = 0;
|
||||
if (CanConvertToScalar(AI, IsNotTrivial, VectorTy,
|
||||
bool HadAVector = false;
|
||||
if (CanConvertToScalar(AI, IsNotTrivial, VectorTy, HadAVector,
|
||||
0, unsigned(AllocaSize)) && IsNotTrivial) {
|
||||
AllocaInst *NewAI;
|
||||
if (VectorTy && isa<VectorType>(VectorTy)) {
|
||||
// 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.
|
||||
if (VectorTy && isa<VectorType>(VectorTy) && HadAVector) {
|
||||
DOUT << "CONVERT TO VECTOR: " << *AI << " TYPE = " << *VectorTy <<"\n";
|
||||
|
||||
// Create and insert the vector alloca.
|
||||
@ -1229,8 +1236,11 @@ static void MergeInType(const Type *In, uint64_t Offset, const Type *&VecTy,
|
||||
/// completely trivial use that mem2reg could promote, set IsNotTrivial. Offset
|
||||
/// is the current offset from the base of the alloca being analyzed.
|
||||
///
|
||||
bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
|
||||
const Type *&VecTy, uint64_t Offset,
|
||||
/// If we see at least one access to the value that is as a vector type, set the
|
||||
/// SawVec flag.
|
||||
///
|
||||
bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
|
||||
bool &SawVec, uint64_t Offset,
|
||||
unsigned AllocaSize) {
|
||||
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) {
|
||||
Instruction *User = cast<Instruction>(*UI);
|
||||
@ -1240,6 +1250,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
|
||||
if (LI->isVolatile())
|
||||
return false;
|
||||
MergeInType(LI->getType(), Offset, VecTy, AllocaSize, *TD);
|
||||
SawVec |= isa<VectorType>(LI->getType());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1247,11 +1258,13 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
|
||||
// Storing the pointer, not into the value?
|
||||
if (SI->getOperand(0) == V || SI->isVolatile()) return 0;
|
||||
MergeInType(SI->getOperand(0)->getType(), Offset, VecTy, AllocaSize, *TD);
|
||||
SawVec |= isa<VectorType>(SI->getOperand(0)->getType());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
|
||||
if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, Offset, AllocaSize))
|
||||
if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, SawVec, Offset,
|
||||
AllocaSize))
|
||||
return false;
|
||||
IsNotTrivial = true;
|
||||
continue;
|
||||
@ -1267,7 +1280,7 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
|
||||
uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(),
|
||||
&Indices[0], Indices.size());
|
||||
// See if all uses can be converted.
|
||||
if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, Offset+GEPOffset,
|
||||
if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, SawVec,Offset+GEPOffset,
|
||||
AllocaSize))
|
||||
return false;
|
||||
IsNotTrivial = true;
|
||||
|
19
test/Transforms/ScalarRepl/not-a-vector.ll
Normal file
19
test/Transforms/ScalarRepl/not-a-vector.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
|
||||
; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep {7 x double}
|
||||
; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret double %B}
|
||||
|
||||
define double @test(double %A, double %B) {
|
||||
%ARR = alloca [7 x i64]
|
||||
%C = bitcast [7 x i64]* %ARR to double*
|
||||
store double %A, double* %C
|
||||
|
||||
%D = getelementptr [7 x i64]* %ARR, i32 0, i32 4
|
||||
%E = bitcast i64* %D to double*
|
||||
store double %B, double* %E
|
||||
|
||||
%F = getelementptr double* %C, i32 4
|
||||
%G = load double* %F
|
||||
ret double %G
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user