mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 08:46:23 +00:00
While DAE can't modify the function signature of an externally visible function,
it can check whether the visible direct callers are passing in parameters to dead arguments and replace those with undef. This reinstates r94322 with bugs fixed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101213 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
32acbc1e50
commit
5894c0b60e
@ -30,6 +30,7 @@
|
||||
#include "llvm/Support/CallSite.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
@ -37,8 +38,9 @@
|
||||
#include <set>
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(NumArgumentsEliminated, "Number of unread args removed");
|
||||
STATISTIC(NumRetValsEliminated , "Number of unused return values removed");
|
||||
STATISTIC(NumArgumentsEliminated , "Number of unread args removed");
|
||||
STATISTIC(NumRetValsEliminated , "Number of unused return values removed");
|
||||
STATISTIC(NumParametersEliminated, "Number of parameters replaced with undef");
|
||||
|
||||
namespace {
|
||||
/// DAE - The dead argument elimination pass.
|
||||
@ -140,6 +142,7 @@ namespace {
|
||||
void MarkLive(const Function &F);
|
||||
void PropagateLiveness(const RetOrArg &RA);
|
||||
bool RemoveDeadStuffFromFunction(Function *F);
|
||||
bool RemoveDeadParamsFromCallersOf(Function *F);
|
||||
bool DeleteDeadVarargs(Function &Fn);
|
||||
};
|
||||
}
|
||||
@ -397,7 +400,9 @@ DAE::Liveness DAE::SurveyUses(const Value *V, UseVector &MaybeLiveUses) {
|
||||
// map.
|
||||
//
|
||||
// We consider arguments of non-internal functions to be intrinsically alive as
|
||||
// well as arguments to functions which have their "address taken".
|
||||
// well as arguments to functions which have their "address taken". Externally
|
||||
// visible functions are assumed to only have their return values intrinsically
|
||||
// alive, permitting removal of parameters to unused arguments in callers.
|
||||
//
|
||||
void DAE::SurveyFunction(const Function &F) {
|
||||
unsigned RetCount = NumRetVals(&F);
|
||||
@ -420,7 +425,14 @@ void DAE::SurveyFunction(const Function &F) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!F.hasLocalLinkage() && (!ShouldHackArguments() || F.isIntrinsic())) {
|
||||
if (F.hasExternalLinkage() && !F.isDeclaration()) {
|
||||
DEBUG(dbgs() << "DAE - Intrinsically live return from " << F.getName()
|
||||
<< "\n");
|
||||
// Mark the return values alive.
|
||||
for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
|
||||
MarkLive(CreateRet(&F, i));
|
||||
} else if (!F.hasLocalLinkage() &&
|
||||
(!ShouldHackArguments() || F.isIntrinsic())) {
|
||||
MarkLive(F);
|
||||
return;
|
||||
}
|
||||
@ -532,14 +544,14 @@ void DAE::MarkValue(const RetOrArg &RA, Liveness L,
|
||||
/// values (according to Uses) live as well.
|
||||
void DAE::MarkLive(const Function &F) {
|
||||
DEBUG(dbgs() << "DAE - Intrinsically live fn: " << F.getName() << "\n");
|
||||
// Mark the function as live.
|
||||
LiveFunctions.insert(&F);
|
||||
// Mark all arguments as live.
|
||||
for (unsigned i = 0, e = F.arg_size(); i != e; ++i)
|
||||
PropagateLiveness(CreateArg(&F, i));
|
||||
// Mark all return values as live.
|
||||
for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
|
||||
PropagateLiveness(CreateRet(&F, i));
|
||||
// Mark the function as live.
|
||||
LiveFunctions.insert(&F);
|
||||
// Mark all arguments as live.
|
||||
for (unsigned i = 0, e = F.arg_size(); i != e; ++i)
|
||||
PropagateLiveness(CreateArg(&F, i));
|
||||
// Mark all return values as live.
|
||||
for (unsigned i = 0, e = NumRetVals(&F); i != e; ++i)
|
||||
PropagateLiveness(CreateRet(&F, i));
|
||||
}
|
||||
|
||||
/// MarkLive - Mark the given return value or argument as live. Additionally,
|
||||
@ -853,7 +865,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
|
||||
Value *RetVal;
|
||||
|
||||
if (NFTy->getReturnType() == Type::getVoidTy(F->getContext())) {
|
||||
if (NFTy->getReturnType()->isVoidTy()) {
|
||||
RetVal = 0;
|
||||
} else {
|
||||
assert (RetTy->isStructTy());
|
||||
@ -894,6 +906,43 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DAE::RemoveDeadParamsFromCallersOf(Function *F) {
|
||||
// Don't modify fully live functions
|
||||
if (LiveFunctions.count(F))
|
||||
return false;
|
||||
|
||||
// Make a list of the dead arguments.
|
||||
SmallVector<int, 10> ArgDead;
|
||||
unsigned i = 0;
|
||||
for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
|
||||
I != E; ++I, ++i) {
|
||||
RetOrArg Arg = CreateArg(F, i);
|
||||
if (!LiveValues.count(Arg))
|
||||
ArgDead.push_back(i);
|
||||
}
|
||||
if (ArgDead.empty())
|
||||
return false;
|
||||
|
||||
bool MadeChange = false;
|
||||
for (Function::use_iterator I = F->use_begin(), E = F->use_end();
|
||||
I != E; ++I) {
|
||||
CallSite CS = CallSite::get(*I);
|
||||
if (CS.getInstruction() && CS.isCallee(I)) {
|
||||
for (unsigned i = 0, e = ArgDead.size(); i != e; ++i) {
|
||||
Value *A = CS.getArgument(ArgDead[i]);
|
||||
if (!isa<UndefValue>(A)) {
|
||||
++NumParametersEliminated;
|
||||
MadeChange = true;
|
||||
CS.setArgument(ArgDead[i], UndefValue::get(A->getType()));
|
||||
RecursivelyDeleteTriviallyDeadInstructions(A);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
bool DAE::runOnModule(Module &M) {
|
||||
bool Changed = false;
|
||||
|
||||
@ -922,7 +971,10 @@ bool DAE::runOnModule(Module &M) {
|
||||
// Increment now, because the function will probably get removed (ie.
|
||||
// replaced by a new one).
|
||||
Function *F = I++;
|
||||
Changed |= RemoveDeadStuffFromFunction(F);
|
||||
if (F->hasExternalLinkage() && !F->isDeclaration())
|
||||
Changed |= RemoveDeadParamsFromCallersOf(F);
|
||||
else
|
||||
Changed |= RemoveDeadStuffFromFunction(F);
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user