[llvm-commits] CVS: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Nov 13 20:24:42 PST 2004
Changes in directory llvm/lib/Transforms/Scalar:
ScalarReplAggregates.cpp updated: 1.26 -> 1.27
---
Log message:
Rearrange some code, no functionality changes.
---
Diffs of the changes: (+68 -49)
Index: llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
diff -u llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.26 llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.27
--- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp:1.26 Sun Sep 19 23:43:15 2004
+++ llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp Sat Nov 13 22:24:28 2004
@@ -54,9 +54,10 @@
}
private:
- bool isSafeElementUse(Value *Ptr);
- bool isSafeUseOfAllocation(Instruction *User);
- bool isSafeAllocaToPromote(AllocationInst *AI);
+ int isSafeElementUse(Value *Ptr);
+ int isSafeUseOfAllocation(Instruction *User);
+ int isSafeAllocaToScalarRepl(AllocationInst *AI);
+ void CanonicalizeAllocaUsers(AllocationInst *AI);
AllocaInst *AddNewAlloca(Function &F, const Type *Ty, AllocationInst *Base);
};
@@ -141,8 +142,15 @@
// Check that all of the users of the allocation are capable of being
// transformed.
- if (!isSafeAllocaToPromote(AI))
+ switch (isSafeAllocaToScalarRepl(AI)) {
+ default: assert(0 && "Unexpected value!");
+ case 0: // Not safe to scalar replace.
continue;
+ case 1: // Safe, but requires cleanup/canonicalizations first
+ CanonicalizeAllocaUsers(AI);
+ case 3: // Safe to scalar replace.
+ break;
+ }
DEBUG(std::cerr << "Found inst to xform: " << *AI);
Changed = true;
@@ -217,11 +225,42 @@
}
+/// isSafeElementUse - Check to see if this use is an allowed use for a
+/// getelementptr instruction of an array aggregate allocation.
+///
+int SROA::isSafeElementUse(Value *Ptr) {
+ for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
+ I != E; ++I) {
+ Instruction *User = cast<Instruction>(*I);
+ switch (User->getOpcode()) {
+ case Instruction::Load: break;
+ case Instruction::Store:
+ // Store is ok if storing INTO the pointer, not storing the pointer
+ if (User->getOperand(0) == Ptr) return 0;
+ break;
+ case Instruction::GetElementPtr: {
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(User);
+ if (GEP->getNumOperands() > 1) {
+ if (!isa<Constant>(GEP->getOperand(1)) ||
+ !cast<Constant>(GEP->getOperand(1))->isNullValue())
+ return 0; // Using pointer arithmetic to navigate the array...
+ }
+ if (!isSafeElementUse(GEP)) return 0;
+ break;
+ }
+ default:
+ DEBUG(std::cerr << " Transformation preventing inst: " << *User);
+ return 0;
+ }
+ }
+ return 3; // All users look ok :)
+}
+
/// isSafeUseOfAllocation - Check to see if this user is an allowed use for an
/// aggregate allocation.
///
-bool SROA::isSafeUseOfAllocation(Instruction *User) {
- if (!isa<GetElementPtrInst>(User)) return false;
+int SROA::isSafeUseOfAllocation(Instruction *User) {
+ if (!isa<GetElementPtrInst>(User)) return 0;
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User);
gep_type_iterator I = gep_type_begin(GEPI), E = gep_type_end(GEPI);
@@ -229,11 +268,11 @@
// The GEP is safe to transform if it is of the form GEP <ptr>, 0, <cst>
if (I == E ||
I.getOperand() != Constant::getNullValue(I.getOperand()->getType()))
- return false;
+ return 0;
++I;
if (I == E || !isa<ConstantInt>(I.getOperand()))
- return false;
+ return 0;
// If this is a use of an array allocation, do a bit more checking for sanity.
if (const ArrayType *AT = dyn_cast<ArrayType>(*I)) {
@@ -243,7 +282,7 @@
// something funny is going on, so we won't do the optimization.
//
if (cast<ConstantInt>(GEPI->getOperand(2))->getRawValue() >= NumElements)
- return false;
+ return 0;
}
// If there are any non-simple uses of this getelementptr, make sure to reject
@@ -251,51 +290,31 @@
return isSafeElementUse(GEPI);
}
-/// isSafeElementUse - Check to see if this use is an allowed use for a
-/// getelementptr instruction of an array aggregate allocation.
+/// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of
+/// an aggregate can be broken down into elements. Return 0 if not, 3 if safe,
+/// or 1 if safe after canonicalization has been performed.
///
-bool SROA::isSafeElementUse(Value *Ptr) {
- for (Value::use_iterator I = Ptr->use_begin(), E = Ptr->use_end();
- I != E; ++I) {
- Instruction *User = cast<Instruction>(*I);
- switch (User->getOpcode()) {
- case Instruction::Load: break;
- case Instruction::Store:
- // Store is ok if storing INTO the pointer, not storing the pointer
- if (User->getOperand(0) == Ptr) return false;
- break;
- case Instruction::GetElementPtr: {
- GetElementPtrInst *GEP = cast<GetElementPtrInst>(User);
- if (GEP->getNumOperands() > 1) {
- if (!isa<Constant>(GEP->getOperand(1)) ||
- !cast<Constant>(GEP->getOperand(1))->isNullValue())
- return false; // Using pointer arithmetic to navigate the array...
- }
- if (!isSafeElementUse(GEP)) return false;
- break;
- }
- default:
- DEBUG(std::cerr << " Transformation preventing inst: " << *User);
- return false;
- }
- }
- return true; // All users look ok :)
-}
-
-
-/// isSafeStructAllocaToPromote - Check to see if the specified allocation of a
-/// structure can be broken down into elements.
-///
-bool SROA::isSafeAllocaToPromote(AllocationInst *AI) {
+int SROA::isSafeAllocaToScalarRepl(AllocationInst *AI) {
// Loop over the use list of the alloca. We can only transform it if all of
// the users are safe to transform.
//
+ int isSafe = 3;
for (Value::use_iterator I = AI->use_begin(), E = AI->use_end();
- I != E; ++I)
- if (!isSafeUseOfAllocation(cast<Instruction>(*I))) {
+ I != E; ++I) {
+ isSafe &= isSafeUseOfAllocation(cast<Instruction>(*I));
+ if (isSafe == 0) {
DEBUG(std::cerr << "Cannot transform: " << *AI << " due to user: "
- << **I);
- return false;
+ << **I);
+ return 0;
}
- return true;
+ }
+ // If we require cleanup, isSafe is now 1, otherwise it is 3.
+ return isSafe;
+}
+
+/// CanonicalizeAllocaUsers - If SROA reported that it can promote the specified
+/// allocation, but only if cleaned up, perform the cleanups required.
+void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) {
+
+
}
More information about the llvm-commits
mailing list