Okay totally give up on trying to optimize aggregates that cannot be completely

broken up into their elements.  Too many programs break because of this.

llvm-svn: 6440
This commit is contained in:
Chris Lattner 2003-05-30 19:22:14 +00:00
parent 39dfa6a920
commit 0078d9c5bb
1 changed files with 6 additions and 40 deletions

View File

@ -23,8 +23,7 @@ namespace {
bool runOnFunction(Function &F); bool runOnFunction(Function &F);
private: private:
bool isSafeStructElementUse(Value *Ptr); bool isSafeElementUse(Value *Ptr);
bool isSafeArrayElementUse(Value *Ptr);
bool isSafeUseOfAllocation(Instruction *User); bool isSafeUseOfAllocation(Instruction *User);
bool isSafeStructAllocaToPromote(AllocationInst *AI); bool isSafeStructAllocaToPromote(AllocationInst *AI);
bool isSafeArrayAllocaToPromote(AllocationInst *AI); bool isSafeArrayAllocaToPromote(AllocationInst *AI);
@ -167,36 +166,10 @@ bool SROA::isSafeUseOfAllocation(Instruction *User) {
return true; return true;
} }
/// isSafeStructElementUse - It is illegal in C to take the address of a /// isSafeElementUse - Check to see if this use is an allowed use for a
/// structure sub-element, and then use pointer arithmetic to access other
/// elements of the struct. Despite the fact that this is illegal, some
/// programs do this, so do at least a simple check to try to avoid breaking
/// broken programs if possible.
///
bool SROA::isSafeStructElementUse(Value *Ptr) {
for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
I != E; ++I)
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*I)) {
if (GEP->getNumOperands() > 1) {
if (!isa<Constant>(GEP->getOperand(1)) ||
!cast<Constant>(GEP->getOperand(1))->isNullValue()) {
std::cerr << "WARNING: Undefined behavior found: " << *GEP
<< " ... uses pointer arithmetic to access other struct "
<< "elements!\n";
return false;
return false; // Using pointer arithmetic to navigate the array...
}
}
}
return true;
}
/// isSafeArrayElementUse - Check to see if this use is an allowed use for a
/// getelementptr instruction of an array aggregate allocation. /// getelementptr instruction of an array aggregate allocation.
/// ///
bool SROA::isSafeArrayElementUse(Value *Ptr) { bool SROA::isSafeElementUse(Value *Ptr) {
for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end(); for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
I != E; ++I) { I != E; ++I) {
Instruction *User = cast<Instruction>(*I); Instruction *User = cast<Instruction>(*I);
@ -209,15 +182,8 @@ bool SROA::isSafeArrayElementUse(Value *Ptr) {
if (!isa<Constant>(GEP->getOperand(1)) || if (!isa<Constant>(GEP->getOperand(1)) ||
!cast<Constant>(GEP->getOperand(1))->isNullValue()) !cast<Constant>(GEP->getOperand(1))->isNullValue())
return false; // Using pointer arithmetic to navigate the array... return false; // Using pointer arithmetic to navigate the array...
// Check to see if there are any structure indexes involved in this GEP.
// If so, then we can safely break the array up until at least the
// structure.
for (unsigned i = 2, e = GEP->getNumOperands(); i != e; ++i)
if (GEP->getOperand(i)->getType()->isUnsigned())
break;
} }
return isSafeArrayElementUse(GEP); return isSafeElementUse(GEP);
} }
default: default:
DEBUG(std::cerr << " Transformation preventing inst: " << *User); DEBUG(std::cerr << " Transformation preventing inst: " << *User);
@ -245,7 +211,7 @@ bool SROA::isSafeStructAllocaToPromote(AllocationInst *AI) {
// Pedantic check to avoid breaking broken programs... // Pedantic check to avoid breaking broken programs...
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*I)) if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*I))
if (GEPI->getNumOperands() == 3 && !isSafeStructElementUse(GEPI)) if (GEPI->getNumOperands() == 3 && !isSafeElementUse(GEPI))
return false; return false;
} }
return true; return true;
@ -285,7 +251,7 @@ bool SROA::isSafeArrayAllocaToPromote(AllocationInst *AI) {
// P = &A[0]; P = P + 1 // P = &A[0]; P = P + 1
// is legal, and should prevent promotion. // is legal, and should prevent promotion.
// //
if (!isSafeArrayElementUse(GEPI)) { if (!isSafeElementUse(GEPI)) {
DEBUG(std::cerr << "Cannot transform: " << *AI DEBUG(std::cerr << "Cannot transform: " << *AI
<< " due to uses of user: " << *GEPI); << " due to uses of user: " << *GEPI);
return false; return false;