Index: include/llvm/Transforms/Utils/Cloning.h =================================================================== --- include/llvm/Transforms/Utils/Cloning.h +++ include/llvm/Transforms/Utils/Cloning.h @@ -227,18 +227,12 @@ /// *inlined* code to minimize the actual inserted code, it must not delete /// code in the caller as users of this routine may have pointers to /// instructions in the caller that need to remain stable. -/// -/// If ForwardVarArgsTo is passed, inlining a function with varargs is allowed -/// and all varargs at the callsite will be passed to any calls to -/// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs -/// are only used by ForwardVarArgsTo. bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, bool InsertLifetime = true, - Function *ForwardVarArgsTo = nullptr); + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); /// \brief Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. Index: lib/Transforms/IPO/PartialInlining.cpp =================================================================== --- lib/Transforms/IPO/PartialInlining.cpp +++ lib/Transforms/IPO/PartialInlining.cpp @@ -1406,14 +1406,36 @@ OR << ore::NV("Callee", Cloner.OrigFunc) << " partially inlined into " << ore::NV("Caller", CS.getCaller()); + SmallVector VarArgsToForward; + for (unsigned i = CS.getCalledFunction()->getFunctionType()->getNumParams(); + i < CS.getNumArgOperands(); i++) + VarArgsToForward.push_back(CS.getArgOperand(i)); + InlineFunctionInfo IFI(nullptr, GetAssumptionCache, PSI); // We can only forward varargs when we outlined a single region, else we // bail on vararg functions. - if (!InlineFunction(CS, IFI, nullptr, true, - (Cloner.ClonedOI ? Cloner.OutlinedFunctions.back().first - : nullptr))) + if (!InlineFunction(CS, IFI, nullptr, true)) continue; + if (Cloner.ClonedOI) { + for (auto CS : IFI.InlinedCallSites) { + CallInst *CI = dyn_cast(CS.getInstruction()); + if (!CI || + CS.getCalledFunction() != Cloner.OutlinedFunctions.back().first) + continue; + + if (!VarArgsToForward.empty()) { + SmallVector Params(CI->arg_operands()); + Params.append(VarArgsToForward.begin(), VarArgsToForward.end()); + CallInst *Call = + CallInst::Create(CI->getCalledFunction(), Params, "", CI); + Call->setDebugLoc(CI->getDebugLoc()); + CI->replaceAllUsesWith(Call); + CI->eraseFromParent(); + } + } + } + ORE.emit(OR); // Now update the entry count: Index: lib/Transforms/Utils/InlineFunction.cpp =================================================================== --- lib/Transforms/Utils/InlineFunction.cpp +++ lib/Transforms/Utils/InlineFunction.cpp @@ -1490,8 +1490,7 @@ /// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, bool InsertLifetime, - Function *ForwardVarArgsTo) { + AAResults *CalleeAAR, bool InsertLifetime) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getFunction() && "Instruction not in function!"); @@ -1822,11 +1821,6 @@ DIExpression::NoDeref); } - SmallVector VarArgsToForward; - for (unsigned i = CalledFunc->getFunctionType()->getNumParams(); - i < CS.getNumArgOperands(); i++) - VarArgsToForward.push_back(CS.getArgOperand(i)); - bool InlinedMustTailCalls = false, InlinedDeoptimizeCalls = false; if (InlinedFunctionInfo.ContainsCalls) { CallInst::TailCallKind CallSiteTailKind = CallInst::TCK_None; @@ -1868,16 +1862,6 @@ // 'nounwind'. if (MarkNoUnwind) CI->setDoesNotThrow(); - - if (ForwardVarArgsTo && !VarArgsToForward.empty() && - CI->getCalledFunction() == ForwardVarArgsTo) { - SmallVector Params(CI->arg_operands()); - Params.append(VarArgsToForward.begin(), VarArgsToForward.end()); - CallInst *Call = CallInst::Create(CI->getCalledFunction(), Params, "", CI); - Call->setDebugLoc(CI->getDebugLoc()); - CI->replaceAllUsesWith(Call); - CI->eraseFromParent(); - } } } }