diff --git a/include/llvm/Function.h b/include/llvm/Function.h index ccc006cfcfb..228ef9440e0 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -395,6 +395,10 @@ public: /// including any contained basic blocks. /// void dropAllReferences(); + + /// hasAddressTaken - returns true if there are any uses of this function + /// other than direct calls or invokes to it. + bool hasAddressTaken() const; }; inline ValueSymbolTable * diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 2bb6428060c..a6126340161 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -127,17 +127,8 @@ bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) { // Second check: make sure that all callers are direct callers. We can't // transform functions that have indirect callers. - for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); - UI != E; ++UI) { - CallSite CS = CallSite::get(*UI); - if (!CS.getInstruction()) // "Taking the address" of the function - return false; - - // Ensure that this call site is CALLING the function, not passing it as - // an argument. - if (!CS.isCallee(UI)) - return false; - } + if (F->hasAddressTaken()) + return false; // Check to see which arguments are promotable. If an argument is promotable, // add it to ArgsToPromote. diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index 666db7e8d74..e480dadca89 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -175,15 +175,8 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { if (Fn.isDeclaration() || !Fn.hasLocalLinkage()) return false; // Ensure that the function is only directly called. - for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end(); I != E; ++I) { - // If this use is anything other than a call site, give up. - CallSite CS = CallSite::get(*I); - Instruction *TheCall = CS.getInstruction(); - if (!TheCall) return false; // Not a direct call site? - - // The addr of this function is passed to the call. - if (!CS.isCallee(I)) return false; - } + if (Fn.hasAddressTaken()) + return false; // Okay, we know we can transform this function if safe. Scan its body // looking for calls to llvm.vastart. diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index f881e089c26..9a1b2941907 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1769,22 +1769,6 @@ bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV, return false; } -/// OnlyCalledDirectly - Return true if the specified function is only called -/// directly. In other words, its address is never taken. -static bool OnlyCalledDirectly(Function *F) { - for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); UI != E;++UI){ - Instruction *User = dyn_cast(*UI); - if (!User) return false; - if (!isa(User) && !isa(User)) return false; - - // See if the function address is passed as an argument. - for (User::op_iterator i = User->op_begin() + 1, e = User->op_end(); - i != e; ++i) - if (*i == F) return false; - } - return true; -} - /// ChangeCalleesToFastCall - Walk all of the direct calls of the specified /// function, changing them to FastCC. static void ChangeCalleesToFastCall(Function *F) { @@ -1830,7 +1814,7 @@ bool GlobalOpt::OptimizeFunctions(Module &M) { ++NumFnDeleted; } else if (F->hasLocalLinkage()) { if (F->getCallingConv() == CallingConv::C && !F->isVarArg() && - OnlyCalledDirectly(F)) { + !F->hasAddressTaken()) { // If this function has C calling conventions, is not a varargs // function, and is only called directly, promote it to use the Fast // calling convention. @@ -1841,7 +1825,7 @@ bool GlobalOpt::OptimizeFunctions(Module &M) { } if (F->getAttributes().hasAttrSomewhere(Attribute::Nest) && - OnlyCalledDirectly(F)) { + !F->hasAddressTaken()) { // The function is not used by a trampoline intrinsic, so it is safe // to remove the 'nest' attribute. RemoveNestAttribute(F); diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 3a991f62d84..54bd895fd40 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -364,4 +364,15 @@ Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, #include "llvm/Intrinsics.gen" #undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN + /// hasAddressTaken - returns true if there are any uses of this function + /// other than direct calls or invokes to it. +bool Function::hasAddressTaken() const { + for (Value::use_const_iterator I = use_begin(), E = use_end(); I != E; ++I) { + if (I.getOperandNo() != 0 || + (!isa(*I) && !isa(*I))) + return true; + } + return false; +} + // vim: sw=2 ai