[llvm-commits] CVS: llvm/lib/Analysis/LoadValueNumbering.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jan 28 22:32:06 PST 2005
Changes in directory llvm/lib/Analysis:
LoadValueNumbering.cpp updated: 1.26 -> 1.27
---
Log message:
Before doing expensive global analysis, check to make sure the pointer is
not invalidated on entry and on exit of the block. This fixes some N^2
behavior in common cases, and speeds up gcc another 5% to 22.35s.
---
Diffs of the changes: (+50 -46)
LoadValueNumbering.cpp | 96 +++++++++++++++++++++++++------------------------
1 files changed, 50 insertions(+), 46 deletions(-)
Index: llvm/lib/Analysis/LoadValueNumbering.cpp
diff -u llvm/lib/Analysis/LoadValueNumbering.cpp:1.26 llvm/lib/Analysis/LoadValueNumbering.cpp:1.27
--- llvm/lib/Analysis/LoadValueNumbering.cpp:1.26 Sat Jan 29 00:20:55 2005
+++ llvm/lib/Analysis/LoadValueNumbering.cpp Sat Jan 29 00:31:53 2005
@@ -284,43 +284,13 @@
if (LI->isVolatile())
return getAnalysis<ValueNumbering>().getEqualNumberNodes(V, RetVals);
- Value *PointerSource = LI->getOperand(0);
+ Value *LoadPtr = LI->getOperand(0);
BasicBlock *LoadBB = LI->getParent();
Function *F = LoadBB->getParent();
-
- // Now that we know the set of equivalent source pointers for the load
- // instruction, look to see if there are any load or store candidates that are
- // identical.
- //
- std::map<BasicBlock*, std::vector<LoadInst*> > CandidateLoads;
- std::map<BasicBlock*, std::vector<StoreInst*> > CandidateStores;
-
- for (Value::use_iterator UI = PointerSource->use_begin(),
- UE = PointerSource->use_end(); UI != UE; ++UI)
- if (LoadInst *Cand = dyn_cast<LoadInst>(*UI)) {// Is a load of source?
- if (Cand->getParent()->getParent() == F && // In the same function?
- Cand != LI && !Cand->isVolatile()) // Not LI itself?
- CandidateLoads[Cand->getParent()].push_back(Cand); // Got one...
- } else if (StoreInst *Cand = dyn_cast<StoreInst>(*UI)) {
- if (Cand->getParent()->getParent() == F && !Cand->isVolatile() &&
- Cand->getOperand(1) == PointerSource) // It's a store THROUGH the ptr.
- CandidateStores[Cand->getParent()].push_back(Cand);
- }
-
- // Get alias analysis & dominators.
- AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
- DominatorSet &DomSetInfo = getAnalysis<DominatorSet>();
- Value *LoadPtr = LI->getOperand(0);
+
// Find out how many bytes of memory are loaded by the load instruction...
unsigned LoadSize = getAnalysis<TargetData>().getTypeSize(LI->getType());
-
- // Find all of the candidate loads and stores that are in the same block as
- // the defining instruction.
- std::set<Instruction*> Instrs;
- Instrs.insert(CandidateLoads[LoadBB].begin(), CandidateLoads[LoadBB].end());
- CandidateLoads.erase(LoadBB);
- Instrs.insert(CandidateStores[LoadBB].begin(), CandidateStores[LoadBB].end());
- CandidateStores.erase(LoadBB);
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
// Figure out if the load is invalidated from the entry of the block it is in
// until the actual instruction. This scans the block backwards from LI. If
@@ -332,27 +302,26 @@
// If this instruction is a candidate load before LI, we know there are no
// invalidating instructions between it and LI, so they have the same value
// number.
- if (isa<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == PointerSource) {
+ if (isa<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == LoadPtr) {
RetVals.push_back(I);
- Instrs.erase(I);
- } else if (AllocationInst *AI = dyn_cast<AllocationInst>(I)) {
+ } else if (I == LoadPtr) {
// If we run into an allocation of the value being loaded, then the
// contents are not initialized.
- if ((Value*)AI == PointerSource) {
- LoadInvalidatedInBBBefore = true;
+ if (isa<AllocationInst>(I))
RetVals.push_back(UndefValue::get(LI->getType()));
- break;
- }
+
+ // Otherwise, since this is the definition of what we are loading, this
+ // loaded value cannot occur before this block.
+ LoadInvalidatedInBBBefore = true;
+ break;
}
if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
// If the invalidating instruction is a store, and its in our candidate
// set, then we can do store-load forwarding: the load has the same value
// # as the stored value.
- if (isa<StoreInst>(I) && I->getOperand(1) == PointerSource) {
- Instrs.erase(I);
+ if (isa<StoreInst>(I) && I->getOperand(1) == LoadPtr)
RetVals.push_back(I->getOperand(0));
- }
LoadInvalidatedInBBBefore = true;
break;
@@ -367,10 +336,8 @@
for (BasicBlock::iterator I = LI->getNext(); I != LoadBB->end(); ++I) {
// If this instruction is a load, then this instruction returns the same
// value as LI.
- if (isa<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == PointerSource) {
+ if (isa<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == LoadPtr)
RetVals.push_back(I);
- Instrs.erase(I);
- }
if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
LoadInvalidatedInBBAfter = true;
@@ -378,6 +345,43 @@
}
}
+ // If the pointer is clobbered on entry and on exit to the function, there is
+ // no need to do any global analysis at all.
+ if (LoadInvalidatedInBBBefore && LoadInvalidatedInBBAfter)
+ return;
+
+ // Now that we know the set of equivalent source pointers for the load
+ // instruction, look to see if there are any load or store candidates that are
+ // identical.
+ //
+ std::map<BasicBlock*, std::vector<LoadInst*> > CandidateLoads;
+ std::map<BasicBlock*, std::vector<StoreInst*> > CandidateStores;
+
+ for (Value::use_iterator UI = LoadPtr->use_begin(), UE = LoadPtr->use_end();
+ UI != UE; ++UI)
+ if (LoadInst *Cand = dyn_cast<LoadInst>(*UI)) {// Is a load of source?
+ if (Cand->getParent()->getParent() == F && // In the same function?
+ // Not in LI's block?
+ Cand->getParent() != LoadBB && !Cand->isVolatile())
+ CandidateLoads[Cand->getParent()].push_back(Cand); // Got one...
+ } else if (StoreInst *Cand = dyn_cast<StoreInst>(*UI)) {
+ if (Cand->getParent()->getParent() == F && !Cand->isVolatile() &&
+ Cand->getParent() != LoadBB &&
+ Cand->getOperand(1) == LoadPtr) // It's a store THROUGH the ptr.
+ CandidateStores[Cand->getParent()].push_back(Cand);
+ }
+
+ // Get dominators.
+ DominatorSet &DomSetInfo = getAnalysis<DominatorSet>();
+
+ // Find all of the candidate loads and stores that are in the same block as
+ // the defining instruction.
+ std::set<Instruction*> Instrs;
+ Instrs.insert(CandidateLoads[LoadBB].begin(), CandidateLoads[LoadBB].end());
+ CandidateLoads.erase(LoadBB);
+ Instrs.insert(CandidateStores[LoadBB].begin(), CandidateStores[LoadBB].end());
+ CandidateStores.erase(LoadBB);
+
// If there is anything left in the Instrs set, it could not possibly equal
// LI.
Instrs.clear();
More information about the llvm-commits
mailing list