aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO/DeadArgumentElimination.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-11-27 13:23:08 +0000
committerDuncan Sands <baldrick@free.fr>2007-11-27 13:23:08 +0000
commitf5588dc4ec43da1e4423e5ff2394669c0f000350 (patch)
tree843dfcaeb8f6c99de930a32020148b563005c2fd /lib/Transforms/IPO/DeadArgumentElimination.cpp
parent4b97e6dc76fe49155a0da53e3df3eef153729d0f (diff)
downloadexternal_llvm-f5588dc4ec43da1e4423e5ff2394669c0f000350.zip
external_llvm-f5588dc4ec43da1e4423e5ff2394669c0f000350.tar.gz
external_llvm-f5588dc4ec43da1e4423e5ff2394669c0f000350.tar.bz2
Fix PR1146: parameter attributes are longer part of
the function type, instead they belong to functions and function calls. This is an updated and slightly corrected version of Reid Spencer's original patch. The only known problem is that auto-upgrading of bitcode files doesn't seem to work properly (see test/Bitcode/AutoUpgradeIntrinsics.ll). Hopefully a bitcode guru (who might that be? :) ) will fix it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/DeadArgumentElimination.cpp')
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
index 3d345ee..a76a43a 100644
--- a/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -26,6 +26,7 @@
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
@@ -157,6 +158,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, Fn.getLinkage());
NF->setCallingConv(Fn.getCallingConv());
+ NF->setParamAttrs(Fn.getParamAttrs());
Fn.getParent()->getFunctionList().insert(&Fn, NF);
NF->takeName(&Fn);
@@ -176,9 +178,11 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<InvokeInst>(New)->setParamAttrs(NF->getParamAttrs());
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<CallInst>(New)->setParamAttrs(NF->getParamAttrs());
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}
@@ -233,10 +237,10 @@ static inline bool CallPassesValueThoughVararg(Instruction *Call,
// (used in a computation), MaybeLive (only passed as an argument to a call), or
// Dead (not used).
DAE::Liveness DAE::getArgumentLiveness(const Argument &A) {
- const FunctionType *FTy = A.getParent()->getFunctionType();
+ const Function *F = A.getParent();
// If this is the return value of a struct function, it's not really dead.
- if (FTy->isStructReturn() && &*A.getParent()->arg_begin() == &A)
+ if (F->isStructReturn() && &*(F->arg_begin()) == &A)
return Live;
if (A.use_empty()) // First check, directly dead?
@@ -488,10 +492,32 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
const FunctionType *FTy = F->getFunctionType();
std::vector<const Type*> Params;
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
- if (!DeadArguments.count(I))
+ // Set up to build a new list of parameter attributes
+ ParamAttrsVector ParamAttrsVec;
+ const ParamAttrsList *PAL = F->getParamAttrs();
+
+ // Construct the new parameter list from non-dead arguments. Also construct
+ // a new set of parameter attributes to correspond.
+ unsigned index = 1;
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
+ ++I, ++index)
+ if (!DeadArguments.count(I)) {
Params.push_back(I->getType());
+ if (PAL) {
+ uint16_t Attrs = PAL->getParamAttrs(index);
+ if (Attrs != ParamAttr::None)
+ ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(),
+ Attrs));
+ }
+ }
+
+ // Reconstruct the ParamAttrsList based on the vector we constructed.
+ if (ParamAttrsVec.empty())
+ PAL = 0;
+ else
+ PAL = ParamAttrsList::get(ParamAttrsVec);
+ // Make the function return void if the return value is dead.
const Type *RetTy = FTy->getReturnType();
if (DeadRetVal.count(F)) {
RetTy = Type::VoidTy;
@@ -507,11 +533,13 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
Params.push_back(Type::Int32Ty);
}
+ // Create the new function type based on the recomputed parameters.
FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, F->getLinkage());
NF->setCallingConv(F->getCallingConv());
+ NF->setParamAttrs(PAL);
F->getParent()->getFunctionList().insert(F, NF);
NF->takeName(F);
@@ -542,9 +570,11 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<InvokeInst>(New)->setParamAttrs(PAL);
} else {
New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ cast<CallInst>(New)->setParamAttrs(PAL);
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
}