Skip to content

Commit

Permalink
Unquadratize SetVector removal loops in DSE.
Browse files Browse the repository at this point in the history
Erasing from the beginning or middle of the vector is expensive, remove_if can
do it in linear time even though it's a bit ugly without lambdas.

No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165903 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
d0k committed Oct 14, 2012
1 parent e82a040 commit 0d05acf
Showing 1 changed file with 36 additions and 27 deletions.
63 changes: 36 additions & 27 deletions lib/Transforms/Scalar/DeadStoreElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,22 @@ bool DSE::HandleFree(CallInst *F) {
return MadeChange;
}

namespace {
struct CouldRef {
typedef Value *argument_type;
const CallSite CS;
AliasAnalysis *AA;

bool operator()(Value *I) {
// See if the call site touches the value.
AliasAnalysis::ModRefResult A =
AA->getModRefInfo(CS, I, getPointerSize(I, *AA));

return A == AliasAnalysis::ModRef || A == AliasAnalysis::Ref;
}
};
}

/// handleEndBlock - Remove dead stores to stack-allocated locations in the
/// function end block. Ex:
/// %A = alloca i32
Expand Down Expand Up @@ -802,26 +818,14 @@ bool DSE::handleEndBlock(BasicBlock &BB) {

// If the call might load from any of our allocas, then any store above
// the call is live.
SmallVector<Value*, 8> LiveAllocas;
for (SmallSetVector<Value*, 16>::iterator I = DeadStackObjects.begin(),
E = DeadStackObjects.end(); I != E; ++I) {
// See if the call site touches it.
AliasAnalysis::ModRefResult A =
AA->getModRefInfo(CS, *I, getPointerSize(*I, *AA));

if (A == AliasAnalysis::ModRef || A == AliasAnalysis::Ref)
LiveAllocas.push_back(*I);
}
CouldRef Pred = { CS, AA };
DeadStackObjects.remove_if(Pred);

// If all of the allocas were clobbered by the call then we're not going
// to find anything else to process.
if (DeadStackObjects.size() == LiveAllocas.size())
if (DeadStackObjects.empty())
break;

for (SmallVector<Value*, 8>::iterator I = LiveAllocas.begin(),
E = LiveAllocas.end(); I != E; ++I)
DeadStackObjects.remove(*I);

continue;
}

Expand Down Expand Up @@ -858,6 +862,20 @@ bool DSE::handleEndBlock(BasicBlock &BB) {
return MadeChange;
}

namespace {
struct CouldAlias {
typedef Value *argument_type;
const AliasAnalysis::Location &LoadedLoc;
AliasAnalysis *AA;

bool operator()(Value *I) {
// See if the loaded location could alias the stack location.
AliasAnalysis::Location StackLoc(I, getPointerSize(I, *AA));
return !AA->isNoAlias(StackLoc, LoadedLoc);
}
};
}

/// RemoveAccessedObjects - Check to see if the specified location may alias any
/// of the stack objects in the DeadStackObjects set. If so, they become live
/// because the location is being loaded.
Expand All @@ -876,16 +894,7 @@ void DSE::RemoveAccessedObjects(const AliasAnalysis::Location &LoadedLoc,
return;
}

SmallVector<Value*, 16> NowLive;
for (SmallSetVector<Value*, 16>::iterator I = DeadStackObjects.begin(),
E = DeadStackObjects.end(); I != E; ++I) {
// See if the loaded location could alias the stack location.
AliasAnalysis::Location StackLoc(*I, getPointerSize(*I, *AA));
if (!AA->isNoAlias(StackLoc, LoadedLoc))
NowLive.push_back(*I);
}

for (SmallVector<Value*, 16>::iterator I = NowLive.begin(), E = NowLive.end();
I != E; ++I)
DeadStackObjects.remove(*I);
// Remove objects that could alias LoadedLoc.
CouldAlias Pred = { LoadedLoc, AA };
DeadStackObjects.remove_if(Pred);
}

0 comments on commit 0d05acf

Please sign in to comment.