[llvm-commits] [llvm] r41930 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Chris Lattner
sabre at nondot.org
Thu Sep 13 11:00:32 PDT 2007
Author: lattner
Date: Thu Sep 13 13:00:31 2007
New Revision: 41930
URL: http://llvm.org/viewvc/llvm-project?rev=41930&view=rev
Log:
be tolerant of PHI nodes when rewriting heap SROA code. This is a step
along the way of PR1639
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=41930&r1=41929&r2=41930&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Sep 13 13:00:31 2007
@@ -844,17 +844,23 @@
static void ReplaceUsesOfMallocWithGlobal(Instruction *Alloc,
GlobalVariable *GV) {
while (!Alloc->use_empty()) {
- Instruction *U = Alloc->use_back();
+ Instruction *U = cast<Instruction>(*Alloc->use_begin());
+ Instruction *InsertPt = U;
if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
// If this is the store of the allocation into the global, remove it.
if (SI->getOperand(1) == GV) {
SI->eraseFromParent();
continue;
}
+ } else if (PHINode *PN = dyn_cast<PHINode>(U)) {
+ // Insert the load in the corresponding predecessor, not right before the
+ // PHI.
+ unsigned PredNo = Alloc->use_begin().getOperandNo()/2;
+ InsertPt = PN->getIncomingBlock(PredNo)->getTerminator();
}
// Insert a load from the global, and use it instead of the malloc.
- Value *NL = new LoadInst(GV, GV->getName()+".val", U);
+ Value *NL = new LoadInst(GV, GV->getName()+".val", InsertPt);
U->replaceUsesOfWith(Alloc, NL);
}
}
@@ -891,6 +897,20 @@
return true;
}
+/// GetHeapSROALoad - Return the load for the specified field of the HeapSROA'd
+/// value, lazily creating it on demand.
+static Value *GetHeapSROALoad(LoadInst *Load, unsigned FieldNo,
+ const std::vector<GlobalVariable*> &FieldGlobals,
+ std::vector<Value *> &InsertedLoadsForPtr) {
+ if (InsertedLoadsForPtr.size() <= FieldNo)
+ InsertedLoadsForPtr.resize(FieldNo+1);
+ if (InsertedLoadsForPtr[FieldNo] == 0)
+ InsertedLoadsForPtr[FieldNo] = new LoadInst(FieldGlobals[FieldNo],
+ Load->getName()+".f" +
+ utostr(FieldNo), Load);
+ return InsertedLoadsForPtr[FieldNo];
+}
+
/// RewriteHeapSROALoadUser - Given a load instruction and a value derived from
/// the load, rewrite the derived value to use the HeapSRoA'd load.
static void RewriteHeapSROALoadUser(LoadInst *Load, Instruction *LoadUser,
@@ -903,8 +923,7 @@
// field.
Value *NPtr;
if (InsertedLoadsForPtr.empty()) {
- NPtr = new LoadInst(FieldGlobals[0], Load->getName()+".f0", Load);
- InsertedLoadsForPtr.push_back(Load);
+ NPtr = GetHeapSROALoad(Load, 0, FieldGlobals, InsertedLoadsForPtr);
} else {
NPtr = InsertedLoadsForPtr.back();
}
@@ -917,30 +936,35 @@
return;
}
- // Otherwise, this should be: 'getelementptr Ptr, Idx, uint FieldNo ...'
- GetElementPtrInst *GEPI = cast<GetElementPtrInst>(LoadUser);
- assert(GEPI->getNumOperands() >= 3 && isa<ConstantInt>(GEPI->getOperand(2))
- && "Unexpected GEPI!");
-
- // Load the pointer for this field.
- unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
- if (InsertedLoadsForPtr.size() <= FieldNo)
- InsertedLoadsForPtr.resize(FieldNo+1);
- if (InsertedLoadsForPtr[FieldNo] == 0)
- InsertedLoadsForPtr[FieldNo] = new LoadInst(FieldGlobals[FieldNo],
- Load->getName()+".f" +
- utostr(FieldNo), Load);
- Value *NewPtr = InsertedLoadsForPtr[FieldNo];
+ // Handle 'getelementptr Ptr, Idx, uint FieldNo ...'
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(LoadUser)) {
+ assert(GEPI->getNumOperands() >= 3 && isa<ConstantInt>(GEPI->getOperand(2))
+ && "Unexpected GEPI!");
+
+ // Load the pointer for this field.
+ unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
+ Value *NewPtr = GetHeapSROALoad(Load, FieldNo,
+ FieldGlobals, InsertedLoadsForPtr);
+
+ // Create the new GEP idx vector.
+ SmallVector<Value*, 8> GEPIdx;
+ GEPIdx.push_back(GEPI->getOperand(1));
+ GEPIdx.append(GEPI->op_begin()+3, GEPI->op_end());
+
+ Value *NGEPI = new GetElementPtrInst(NewPtr, GEPIdx.begin(), GEPIdx.end(),
+ GEPI->getName(), GEPI);
+ GEPI->replaceAllUsesWith(NGEPI);
+ GEPI->eraseFromParent();
+ return;
+ }
- // Create the new GEP idx vector.
- SmallVector<Value*, 8> GEPIdx;
- GEPIdx.push_back(GEPI->getOperand(1));
- GEPIdx.append(GEPI->op_begin()+3, GEPI->op_end());
-
- Value *NGEPI = new GetElementPtrInst(NewPtr, GEPIdx.begin(), GEPIdx.end(),
- GEPI->getName(), GEPI);
- GEPI->replaceAllUsesWith(NGEPI);
- GEPI->eraseFromParent();
+ // Handle PHI nodes. All PHI nodes must be merging in the same values, so
+ // just treat them like a copy.
+ PHINode *PN = cast<PHINode>(LoadUser);
+ while (!PN->use_empty())
+ RewriteHeapSROALoadUser(Load, PN->use_back(),
+ FieldGlobals, InsertedLoadsForPtr);
+ PN->eraseFromParent();
}
/// RewriteUsesOfLoadForHeapSRoA - We are performing Heap SRoA on a global. Ptr
More information about the llvm-commits
mailing list