10b57cec5SDimitry Andric //===- DeadArgumentElimination.cpp - Eliminate dead arguments -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass deletes dead arguments from internal functions. Dead argument
100b57cec5SDimitry Andric // elimination removes arguments which are directly dead, as well as arguments
110b57cec5SDimitry Andric // only passed into function calls as dead arguments of other functions. This
120b57cec5SDimitry Andric // pass also deletes dead return values in a similar way.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric // This pass is often useful as a cleanup pass to run after aggressive
150b57cec5SDimitry Andric // interprocedural passes, which add possibly-dead arguments or return values.
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric
1906c3fb27SDimitry Andric #include "llvm/Transforms/IPO/DeadArgumentElimination.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
220b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
2306c3fb27SDimitry Andric #include "llvm/IR/AttributeMask.h"
240b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
250b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
260b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
2781ad6265SDimitry Andric #include "llvm/IR/DIBuilder.h"
280b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
290b57cec5SDimitry Andric #include "llvm/IR/Function.h"
305ffd83dbSDimitry Andric #include "llvm/IR/IRBuilder.h"
310b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
320b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
330b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
340b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
350b57cec5SDimitry Andric #include "llvm/IR/Module.h"
365ffd83dbSDimitry Andric #include "llvm/IR/NoFolder.h"
370b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
380b57cec5SDimitry Andric #include "llvm/IR/Type.h"
390b57cec5SDimitry Andric #include "llvm/IR/Use.h"
400b57cec5SDimitry Andric #include "llvm/IR/User.h"
410b57cec5SDimitry Andric #include "llvm/IR/Value.h"
42480093f4SDimitry Andric #include "llvm/InitializePasses.h"
430b57cec5SDimitry Andric #include "llvm/Pass.h"
440b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
450b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
460b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
470b57cec5SDimitry Andric #include "llvm/Transforms/IPO.h"
480b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h"
490b57cec5SDimitry Andric #include <cassert>
500b57cec5SDimitry Andric #include <utility>
510b57cec5SDimitry Andric #include <vector>
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric using namespace llvm;
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric #define DEBUG_TYPE "deadargelim"
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric STATISTIC(NumArgumentsEliminated, "Number of unread args removed");
580b57cec5SDimitry Andric STATISTIC(NumRetValsEliminated, "Number of unused return values removed");
5981ad6265SDimitry Andric STATISTIC(NumArgumentsReplacedWithPoison,
6081ad6265SDimitry Andric "Number of unread args replaced with poison");
610b57cec5SDimitry Andric
620b57cec5SDimitry Andric namespace {
630b57cec5SDimitry Andric
6481ad6265SDimitry Andric /// The dead argument elimination pass.
650b57cec5SDimitry Andric class DAE : public ModulePass {
660b57cec5SDimitry Andric protected:
670b57cec5SDimitry Andric // DAH uses this to specify a different ID.
DAE(char & ID)680b57cec5SDimitry Andric explicit DAE(char &ID) : ModulePass(ID) {}
690b57cec5SDimitry Andric
700b57cec5SDimitry Andric public:
710b57cec5SDimitry Andric static char ID; // Pass identification, replacement for typeid
720b57cec5SDimitry Andric
DAE()730b57cec5SDimitry Andric DAE() : ModulePass(ID) {
740b57cec5SDimitry Andric initializeDAEPass(*PassRegistry::getPassRegistry());
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
runOnModule(Module & M)770b57cec5SDimitry Andric bool runOnModule(Module &M) override {
780b57cec5SDimitry Andric if (skipModule(M))
790b57cec5SDimitry Andric return false;
8081ad6265SDimitry Andric DeadArgumentEliminationPass DAEP(shouldHackArguments());
810b57cec5SDimitry Andric ModuleAnalysisManager DummyMAM;
820b57cec5SDimitry Andric PreservedAnalyses PA = DAEP.run(M, DummyMAM);
830b57cec5SDimitry Andric return !PA.areAllPreserved();
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric
shouldHackArguments() const8681ad6265SDimitry Andric virtual bool shouldHackArguments() const { return false; }
870b57cec5SDimitry Andric };
880b57cec5SDimitry Andric
isMustTailCalleeAnalyzable(const CallBase & CB)8906c3fb27SDimitry Andric bool isMustTailCalleeAnalyzable(const CallBase &CB) {
9006c3fb27SDimitry Andric assert(CB.isMustTailCall());
9106c3fb27SDimitry Andric return CB.getCalledFunction() && !CB.getCalledFunction()->isDeclaration();
9206c3fb27SDimitry Andric }
9306c3fb27SDimitry Andric
940b57cec5SDimitry Andric } // end anonymous namespace
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric char DAE::ID = 0;
970b57cec5SDimitry Andric
980b57cec5SDimitry Andric INITIALIZE_PASS(DAE, "deadargelim", "Dead Argument Elimination", false, false)
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric namespace {
1010b57cec5SDimitry Andric
10281ad6265SDimitry Andric /// The DeadArgumentHacking pass, same as dead argument elimination, but deletes
10381ad6265SDimitry Andric /// arguments to functions which are external. This is only for use by bugpoint.
1040b57cec5SDimitry Andric struct DAH : public DAE {
1050b57cec5SDimitry Andric static char ID;
1060b57cec5SDimitry Andric
DAH__anon22dba76f0211::DAH1070b57cec5SDimitry Andric DAH() : DAE(ID) {}
1080b57cec5SDimitry Andric
shouldHackArguments__anon22dba76f0211::DAH10981ad6265SDimitry Andric bool shouldHackArguments() const override { return true; }
1100b57cec5SDimitry Andric };
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric } // end anonymous namespace
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric char DAH::ID = 0;
1150b57cec5SDimitry Andric
1160b57cec5SDimitry Andric INITIALIZE_PASS(DAH, "deadarghaX0r",
11781ad6265SDimitry Andric "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)", false,
11881ad6265SDimitry Andric false)
1190b57cec5SDimitry Andric
12081ad6265SDimitry Andric /// This pass removes arguments from functions which are not used by the body of
12181ad6265SDimitry Andric /// the function.
createDeadArgEliminationPass()1220b57cec5SDimitry Andric ModulePass *llvm::createDeadArgEliminationPass() { return new DAE(); }
1230b57cec5SDimitry Andric
createDeadArgHackingPass()1240b57cec5SDimitry Andric ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); }
1250b57cec5SDimitry Andric
12681ad6265SDimitry Andric /// If this is an function that takes a ... list, and if llvm.vastart is never
12781ad6265SDimitry Andric /// called, the varargs list is dead for the function.
deleteDeadVarargs(Function & F)12881ad6265SDimitry Andric bool DeadArgumentEliminationPass::deleteDeadVarargs(Function &F) {
12981ad6265SDimitry Andric assert(F.getFunctionType()->isVarArg() && "Function isn't varargs!");
13081ad6265SDimitry Andric if (F.isDeclaration() || !F.hasLocalLinkage())
13181ad6265SDimitry Andric return false;
1320b57cec5SDimitry Andric
1330b57cec5SDimitry Andric // Ensure that the function is only directly called.
13481ad6265SDimitry Andric if (F.hasAddressTaken())
1350b57cec5SDimitry Andric return false;
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric // Don't touch naked functions. The assembly might be using an argument, or
1380b57cec5SDimitry Andric // otherwise rely on the frame layout in a way that this analysis will not
1390b57cec5SDimitry Andric // see.
14081ad6265SDimitry Andric if (F.hasFnAttribute(Attribute::Naked)) {
1410b57cec5SDimitry Andric return false;
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andric // Okay, we know we can transform this function if safe. Scan its body
1450b57cec5SDimitry Andric // looking for calls marked musttail or calls to llvm.vastart.
14681ad6265SDimitry Andric for (BasicBlock &BB : F) {
1470b57cec5SDimitry Andric for (Instruction &I : BB) {
1480b57cec5SDimitry Andric CallInst *CI = dyn_cast<CallInst>(&I);
1490b57cec5SDimitry Andric if (!CI)
1500b57cec5SDimitry Andric continue;
1510b57cec5SDimitry Andric if (CI->isMustTailCall())
1520b57cec5SDimitry Andric return false;
1530b57cec5SDimitry Andric if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
1540b57cec5SDimitry Andric if (II->getIntrinsicID() == Intrinsic::vastart)
1550b57cec5SDimitry Andric return false;
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric // If we get here, there are no calls to llvm.vastart in the function body,
1610b57cec5SDimitry Andric // remove the "..." and adjust all the calls.
1620b57cec5SDimitry Andric
1630b57cec5SDimitry Andric // Start by computing a new prototype for the function, which is the same as
1640b57cec5SDimitry Andric // the old function, but doesn't have isVarArg set.
16581ad6265SDimitry Andric FunctionType *FTy = F.getFunctionType();
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric std::vector<Type *> Params(FTy->param_begin(), FTy->param_end());
16881ad6265SDimitry Andric FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);
1690b57cec5SDimitry Andric unsigned NumArgs = Params.size();
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andric // Create the new function body and insert it into the module...
17281ad6265SDimitry Andric Function *NF = Function::Create(NFTy, F.getLinkage(), F.getAddressSpace());
17381ad6265SDimitry Andric NF->copyAttributesFrom(&F);
17481ad6265SDimitry Andric NF->setComdat(F.getComdat());
17581ad6265SDimitry Andric F.getParent()->getFunctionList().insert(F.getIterator(), NF);
17681ad6265SDimitry Andric NF->takeName(&F);
1775f757f3fSDimitry Andric NF->IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
1780b57cec5SDimitry Andric
17981ad6265SDimitry Andric // Loop over all the callers of the function, transforming the call sites
1800b57cec5SDimitry Andric // to pass in a smaller number of arguments into the new function.
1810b57cec5SDimitry Andric //
1820b57cec5SDimitry Andric std::vector<Value *> Args;
18381ad6265SDimitry Andric for (User *U : llvm::make_early_inc_range(F.users())) {
184349cc55cSDimitry Andric CallBase *CB = dyn_cast<CallBase>(U);
1855ffd83dbSDimitry Andric if (!CB)
1860b57cec5SDimitry Andric continue;
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric // Pass all the same arguments.
1895ffd83dbSDimitry Andric Args.assign(CB->arg_begin(), CB->arg_begin() + NumArgs);
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andric // Drop any attributes that were on the vararg arguments.
1925ffd83dbSDimitry Andric AttributeList PAL = CB->getAttributes();
1930b57cec5SDimitry Andric if (!PAL.isEmpty()) {
1940b57cec5SDimitry Andric SmallVector<AttributeSet, 8> ArgAttrs;
1950b57cec5SDimitry Andric for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo)
196349cc55cSDimitry Andric ArgAttrs.push_back(PAL.getParamAttrs(ArgNo));
19781ad6265SDimitry Andric PAL = AttributeList::get(F.getContext(), PAL.getFnAttrs(),
198349cc55cSDimitry Andric PAL.getRetAttrs(), ArgAttrs);
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andric SmallVector<OperandBundleDef, 1> OpBundles;
2025ffd83dbSDimitry Andric CB->getOperandBundlesAsDefs(OpBundles);
2030b57cec5SDimitry Andric
2045ffd83dbSDimitry Andric CallBase *NewCB = nullptr;
2055ffd83dbSDimitry Andric if (InvokeInst *II = dyn_cast<InvokeInst>(CB)) {
2065ffd83dbSDimitry Andric NewCB = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
207*0fca6ea1SDimitry Andric Args, OpBundles, "", CB->getIterator());
2080b57cec5SDimitry Andric } else {
209*0fca6ea1SDimitry Andric NewCB = CallInst::Create(NF, Args, OpBundles, "", CB->getIterator());
2105ffd83dbSDimitry Andric cast<CallInst>(NewCB)->setTailCallKind(
2115ffd83dbSDimitry Andric cast<CallInst>(CB)->getTailCallKind());
2120b57cec5SDimitry Andric }
2135ffd83dbSDimitry Andric NewCB->setCallingConv(CB->getCallingConv());
2145ffd83dbSDimitry Andric NewCB->setAttributes(PAL);
2155ffd83dbSDimitry Andric NewCB->copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
2160b57cec5SDimitry Andric
2170b57cec5SDimitry Andric Args.clear();
2180b57cec5SDimitry Andric
2195ffd83dbSDimitry Andric if (!CB->use_empty())
2205ffd83dbSDimitry Andric CB->replaceAllUsesWith(NewCB);
2210b57cec5SDimitry Andric
2225ffd83dbSDimitry Andric NewCB->takeName(CB);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric // Finally, remove the old call from the program, reducing the use-count of
2250b57cec5SDimitry Andric // F.
2265ffd83dbSDimitry Andric CB->eraseFromParent();
2270b57cec5SDimitry Andric }
2280b57cec5SDimitry Andric
2290b57cec5SDimitry Andric // Since we have now created the new function, splice the body of the old
2300b57cec5SDimitry Andric // function right into the new function, leaving the old rotting hulk of the
2310b57cec5SDimitry Andric // function empty.
232bdd1243dSDimitry Andric NF->splice(NF->begin(), &F);
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric // Loop over the argument list, transferring uses of the old arguments over to
23581ad6265SDimitry Andric // the new arguments, also transferring over the names as well. While we're
23681ad6265SDimitry Andric // at it, remove the dead arguments from the DeadArguments list.
23781ad6265SDimitry Andric for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(),
23881ad6265SDimitry Andric I2 = NF->arg_begin();
23981ad6265SDimitry Andric I != E; ++I, ++I2) {
2400b57cec5SDimitry Andric // Move the name and users over to the new version.
2410b57cec5SDimitry Andric I->replaceAllUsesWith(&*I2);
2420b57cec5SDimitry Andric I2->takeName(&*I);
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric
24581ad6265SDimitry Andric // Clone metadata from the old function, including debug info descriptor.
2460b57cec5SDimitry Andric SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
24781ad6265SDimitry Andric F.getAllMetadata(MDs);
248bdd1243dSDimitry Andric for (auto [KindID, Node] : MDs)
249bdd1243dSDimitry Andric NF->addMetadata(KindID, *Node);
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric // Fix up any BlockAddresses that refer to the function.
2525f757f3fSDimitry Andric F.replaceAllUsesWith(NF);
2530b57cec5SDimitry Andric // Delete the bitcast that we just created, so that NF does not
2540b57cec5SDimitry Andric // appear to be address-taken.
2550b57cec5SDimitry Andric NF->removeDeadConstantUsers();
2560b57cec5SDimitry Andric // Finally, nuke the old function.
25781ad6265SDimitry Andric F.eraseFromParent();
2580b57cec5SDimitry Andric return true;
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric
26181ad6265SDimitry Andric /// Checks if the given function has any arguments that are unused, and changes
26281ad6265SDimitry Andric /// the caller parameters to be poison instead.
removeDeadArgumentsFromCallers(Function & F)26381ad6265SDimitry Andric bool DeadArgumentEliminationPass::removeDeadArgumentsFromCallers(Function &F) {
2640b57cec5SDimitry Andric // We cannot change the arguments if this TU does not define the function or
2650b57cec5SDimitry Andric // if the linker may choose a function body from another TU, even if the
2660b57cec5SDimitry Andric // nominal linkage indicates that other copies of the function have the same
2670b57cec5SDimitry Andric // semantics. In the below example, the dead load from %p may not have been
26881ad6265SDimitry Andric // eliminated from the linker-chosen copy of f, so replacing %p with poison
2690b57cec5SDimitry Andric // in callers may introduce undefined behavior.
2700b57cec5SDimitry Andric //
2710b57cec5SDimitry Andric // define linkonce_odr void @f(i32* %p) {
2720b57cec5SDimitry Andric // %v = load i32 %p
2730b57cec5SDimitry Andric // ret void
2740b57cec5SDimitry Andric // }
27581ad6265SDimitry Andric if (!F.hasExactDefinition())
2760b57cec5SDimitry Andric return false;
2770b57cec5SDimitry Andric
27881ad6265SDimitry Andric // Functions with local linkage should already have been handled, except if
27981ad6265SDimitry Andric // they are fully alive (e.g., called indirectly) and except for the fragile
28081ad6265SDimitry Andric // (variadic) ones. In these cases, we may still be able to improve their
28181ad6265SDimitry Andric // statically known call sites.
28281ad6265SDimitry Andric if ((F.hasLocalLinkage() && !LiveFunctions.count(&F)) &&
28381ad6265SDimitry Andric !F.getFunctionType()->isVarArg())
2840b57cec5SDimitry Andric return false;
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric // Don't touch naked functions. The assembly might be using an argument, or
2870b57cec5SDimitry Andric // otherwise rely on the frame layout in a way that this analysis will not
2880b57cec5SDimitry Andric // see.
28981ad6265SDimitry Andric if (F.hasFnAttribute(Attribute::Naked))
2900b57cec5SDimitry Andric return false;
2910b57cec5SDimitry Andric
29281ad6265SDimitry Andric if (F.use_empty())
2930b57cec5SDimitry Andric return false;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric SmallVector<unsigned, 8> UnusedArgs;
2960b57cec5SDimitry Andric bool Changed = false;
2970b57cec5SDimitry Andric
29804eeddc0SDimitry Andric AttributeMask UBImplyingAttributes =
29904eeddc0SDimitry Andric AttributeFuncs::getUBImplyingAttributes();
30081ad6265SDimitry Andric for (Argument &Arg : F.args()) {
3015ffd83dbSDimitry Andric if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
302e8d8bef9SDimitry Andric !Arg.hasPassPointeeByValueCopyAttr()) {
3030b57cec5SDimitry Andric if (Arg.isUsedByMetadata()) {
30481ad6265SDimitry Andric Arg.replaceAllUsesWith(PoisonValue::get(Arg.getType()));
3050b57cec5SDimitry Andric Changed = true;
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric UnusedArgs.push_back(Arg.getArgNo());
30881ad6265SDimitry Andric F.removeParamAttrs(Arg.getArgNo(), UBImplyingAttributes);
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric if (UnusedArgs.empty())
3130b57cec5SDimitry Andric return false;
3140b57cec5SDimitry Andric
31581ad6265SDimitry Andric for (Use &U : F.uses()) {
3165ffd83dbSDimitry Andric CallBase *CB = dyn_cast<CallBase>(U.getUser());
31781ad6265SDimitry Andric if (!CB || !CB->isCallee(&U) ||
31881ad6265SDimitry Andric CB->getFunctionType() != F.getFunctionType())
3190b57cec5SDimitry Andric continue;
3200b57cec5SDimitry Andric
32181ad6265SDimitry Andric // Now go through all unused args and replace them with poison.
322*0fca6ea1SDimitry Andric for (unsigned ArgNo : UnusedArgs) {
3235ffd83dbSDimitry Andric Value *Arg = CB->getArgOperand(ArgNo);
32481ad6265SDimitry Andric CB->setArgOperand(ArgNo, PoisonValue::get(Arg->getType()));
325fe6060f1SDimitry Andric CB->removeParamAttrs(ArgNo, UBImplyingAttributes);
326fe6060f1SDimitry Andric
32781ad6265SDimitry Andric ++NumArgumentsReplacedWithPoison;
3280b57cec5SDimitry Andric Changed = true;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric }
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric return Changed;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric /// Convenience function that returns the number of return values. It returns 0
3360b57cec5SDimitry Andric /// for void functions and 1 for functions not returning a struct. It returns
3370b57cec5SDimitry Andric /// the number of struct elements for functions returning a struct.
numRetVals(const Function * F)33881ad6265SDimitry Andric static unsigned numRetVals(const Function *F) {
3390b57cec5SDimitry Andric Type *RetTy = F->getReturnType();
3400b57cec5SDimitry Andric if (RetTy->isVoidTy())
3410b57cec5SDimitry Andric return 0;
34281ad6265SDimitry Andric if (StructType *STy = dyn_cast<StructType>(RetTy))
3430b57cec5SDimitry Andric return STy->getNumElements();
34481ad6265SDimitry Andric if (ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
3450b57cec5SDimitry Andric return ATy->getNumElements();
3460b57cec5SDimitry Andric return 1;
3470b57cec5SDimitry Andric }
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andric /// Returns the sub-type a function will return at a given Idx. Should
3500b57cec5SDimitry Andric /// correspond to the result type of an ExtractValue instruction executed with
3510b57cec5SDimitry Andric /// just that one Idx (i.e. only top-level structure is considered).
getRetComponentType(const Function * F,unsigned Idx)3520b57cec5SDimitry Andric static Type *getRetComponentType(const Function *F, unsigned Idx) {
3530b57cec5SDimitry Andric Type *RetTy = F->getReturnType();
3540b57cec5SDimitry Andric assert(!RetTy->isVoidTy() && "void type has no subtype");
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric if (StructType *STy = dyn_cast<StructType>(RetTy))
3570b57cec5SDimitry Andric return STy->getElementType(Idx);
35881ad6265SDimitry Andric if (ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
3590b57cec5SDimitry Andric return ATy->getElementType();
3600b57cec5SDimitry Andric return RetTy;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric
36381ad6265SDimitry Andric /// Checks Use for liveness in LiveValues. If Use is not live, it adds Use to
36481ad6265SDimitry Andric /// the MaybeLiveUses argument. Returns the determined liveness of Use.
3650b57cec5SDimitry Andric DeadArgumentEliminationPass::Liveness
markIfNotLive(RetOrArg Use,UseVector & MaybeLiveUses)36681ad6265SDimitry Andric DeadArgumentEliminationPass::markIfNotLive(RetOrArg Use,
3670b57cec5SDimitry Andric UseVector &MaybeLiveUses) {
3680b57cec5SDimitry Andric // We're live if our use or its Function is already marked as live.
36981ad6265SDimitry Andric if (isLive(Use))
3700b57cec5SDimitry Andric return Live;
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric // We're maybe live otherwise, but remember that we must become live if
3730b57cec5SDimitry Andric // Use becomes live.
3740b57cec5SDimitry Andric MaybeLiveUses.push_back(Use);
3750b57cec5SDimitry Andric return MaybeLive;
3760b57cec5SDimitry Andric }
3770b57cec5SDimitry Andric
37881ad6265SDimitry Andric /// Looks at a single use of an argument or return value and determines if it
37981ad6265SDimitry Andric /// should be alive or not. Adds this use to MaybeLiveUses if it causes the
38081ad6265SDimitry Andric /// used value to become MaybeLive.
3810b57cec5SDimitry Andric ///
3820b57cec5SDimitry Andric /// RetValNum is the return value number to use when this use is used in a
3830b57cec5SDimitry Andric /// return instruction. This is used in the recursion, you should always leave
3840b57cec5SDimitry Andric /// it at 0.
3850b57cec5SDimitry Andric DeadArgumentEliminationPass::Liveness
surveyUse(const Use * U,UseVector & MaybeLiveUses,unsigned RetValNum)38681ad6265SDimitry Andric DeadArgumentEliminationPass::surveyUse(const Use *U, UseVector &MaybeLiveUses,
3870b57cec5SDimitry Andric unsigned RetValNum) {
3880b57cec5SDimitry Andric const User *V = U->getUser();
3890b57cec5SDimitry Andric if (const ReturnInst *RI = dyn_cast<ReturnInst>(V)) {
3900b57cec5SDimitry Andric // The value is returned from a function. It's only live when the
3910b57cec5SDimitry Andric // function's return value is live. We use RetValNum here, for the case
3920b57cec5SDimitry Andric // that U is really a use of an insertvalue instruction that uses the
3930b57cec5SDimitry Andric // original Use.
3940b57cec5SDimitry Andric const Function *F = RI->getParent()->getParent();
3950b57cec5SDimitry Andric if (RetValNum != -1U) {
39681ad6265SDimitry Andric RetOrArg Use = createRet(F, RetValNum);
3970b57cec5SDimitry Andric // We might be live, depending on the liveness of Use.
39881ad6265SDimitry Andric return markIfNotLive(Use, MaybeLiveUses);
39981ad6265SDimitry Andric }
40081ad6265SDimitry Andric
4010b57cec5SDimitry Andric DeadArgumentEliminationPass::Liveness Result = MaybeLive;
40281ad6265SDimitry Andric for (unsigned Ri = 0; Ri < numRetVals(F); ++Ri) {
40381ad6265SDimitry Andric RetOrArg Use = createRet(F, Ri);
4040b57cec5SDimitry Andric // We might be live, depending on the liveness of Use. If any
4050b57cec5SDimitry Andric // sub-value is live, then the entire value is considered live. This
4060b57cec5SDimitry Andric // is a conservative choice, and better tracking is possible.
4070b57cec5SDimitry Andric DeadArgumentEliminationPass::Liveness SubResult =
40881ad6265SDimitry Andric markIfNotLive(Use, MaybeLiveUses);
4090b57cec5SDimitry Andric if (Result != Live)
4100b57cec5SDimitry Andric Result = SubResult;
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric return Result;
4130b57cec5SDimitry Andric }
41481ad6265SDimitry Andric
4150b57cec5SDimitry Andric if (const InsertValueInst *IV = dyn_cast<InsertValueInst>(V)) {
41681ad6265SDimitry Andric if (U->getOperandNo() != InsertValueInst::getAggregateOperandIndex() &&
41781ad6265SDimitry Andric IV->hasIndices())
4180b57cec5SDimitry Andric // The use we are examining is inserted into an aggregate. Our liveness
4190b57cec5SDimitry Andric // depends on all uses of that aggregate, but if it is used as a return
4200b57cec5SDimitry Andric // value, only index at which we were inserted counts.
4210b57cec5SDimitry Andric RetValNum = *IV->idx_begin();
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric // Note that if we are used as the aggregate operand to the insertvalue,
4240b57cec5SDimitry Andric // we don't change RetValNum, but do survey all our uses.
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric Liveness Result = MaybeLive;
4270b57cec5SDimitry Andric for (const Use &UU : IV->uses()) {
42881ad6265SDimitry Andric Result = surveyUse(&UU, MaybeLiveUses, RetValNum);
4290b57cec5SDimitry Andric if (Result == Live)
4300b57cec5SDimitry Andric break;
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric return Result;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric
4355ffd83dbSDimitry Andric if (const auto *CB = dyn_cast<CallBase>(V)) {
4365ffd83dbSDimitry Andric const Function *F = CB->getCalledFunction();
4370b57cec5SDimitry Andric if (F) {
4380b57cec5SDimitry Andric // Used in a direct call.
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric // The function argument is live if it is used as a bundle operand.
4415ffd83dbSDimitry Andric if (CB->isBundleOperand(U))
4420b57cec5SDimitry Andric return Live;
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andric // Find the argument number. We know for sure that this use is an
4450b57cec5SDimitry Andric // argument, since if it was the function argument this would be an
44681ad6265SDimitry Andric // indirect call and that we know can't be looking at a value of the
4470b57cec5SDimitry Andric // label type (for the invoke instruction).
4485ffd83dbSDimitry Andric unsigned ArgNo = CB->getArgOperandNo(U);
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric if (ArgNo >= F->getFunctionType()->getNumParams())
4510b57cec5SDimitry Andric // The value is passed in through a vararg! Must be live.
4520b57cec5SDimitry Andric return Live;
4530b57cec5SDimitry Andric
4545ffd83dbSDimitry Andric assert(CB->getArgOperand(ArgNo) == CB->getOperand(U->getOperandNo()) &&
4555ffd83dbSDimitry Andric "Argument is not where we expected it");
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andric // Value passed to a normal call. It's only live when the corresponding
4580b57cec5SDimitry Andric // argument to the called function turns out live.
45981ad6265SDimitry Andric RetOrArg Use = createArg(F, ArgNo);
46081ad6265SDimitry Andric return markIfNotLive(Use, MaybeLiveUses);
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric // Used in any other way? Value must be live.
4640b57cec5SDimitry Andric return Live;
4650b57cec5SDimitry Andric }
4660b57cec5SDimitry Andric
46781ad6265SDimitry Andric /// Looks at all the uses of the given value
4680b57cec5SDimitry Andric /// Returns the Liveness deduced from the uses of this value.
4690b57cec5SDimitry Andric ///
4700b57cec5SDimitry Andric /// Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses. If
4710b57cec5SDimitry Andric /// the result is Live, MaybeLiveUses might be modified but its content should
4720b57cec5SDimitry Andric /// be ignored (since it might not be complete).
4730b57cec5SDimitry Andric DeadArgumentEliminationPass::Liveness
surveyUses(const Value * V,UseVector & MaybeLiveUses)47481ad6265SDimitry Andric DeadArgumentEliminationPass::surveyUses(const Value *V,
4750b57cec5SDimitry Andric UseVector &MaybeLiveUses) {
4760b57cec5SDimitry Andric // Assume it's dead (which will only hold if there are no uses at all..).
4770b57cec5SDimitry Andric Liveness Result = MaybeLive;
4780b57cec5SDimitry Andric // Check each use.
4790b57cec5SDimitry Andric for (const Use &U : V->uses()) {
48081ad6265SDimitry Andric Result = surveyUse(&U, MaybeLiveUses);
4810b57cec5SDimitry Andric if (Result == Live)
4820b57cec5SDimitry Andric break;
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric return Result;
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric
48781ad6265SDimitry Andric /// Performs the initial survey of the specified function, checking out whether
48881ad6265SDimitry Andric /// it uses any of its incoming arguments or whether any callers use the return
48981ad6265SDimitry Andric /// value. This fills in the LiveValues set and Uses map.
49081ad6265SDimitry Andric ///
49181ad6265SDimitry Andric /// We consider arguments of non-internal functions to be intrinsically alive as
49281ad6265SDimitry Andric /// well as arguments to functions which have their "address taken".
surveyFunction(const Function & F)49381ad6265SDimitry Andric void DeadArgumentEliminationPass::surveyFunction(const Function &F) {
4945ffd83dbSDimitry Andric // Functions with inalloca/preallocated parameters are expecting args in a
4955ffd83dbSDimitry Andric // particular register and memory layout.
4965ffd83dbSDimitry Andric if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||
4975ffd83dbSDimitry Andric F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
49881ad6265SDimitry Andric markLive(F);
4990b57cec5SDimitry Andric return;
5000b57cec5SDimitry Andric }
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric // Don't touch naked functions. The assembly might be using an argument, or
5030b57cec5SDimitry Andric // otherwise rely on the frame layout in a way that this analysis will not
5040b57cec5SDimitry Andric // see.
5050b57cec5SDimitry Andric if (F.hasFnAttribute(Attribute::Naked)) {
50681ad6265SDimitry Andric markLive(F);
5070b57cec5SDimitry Andric return;
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric
51081ad6265SDimitry Andric unsigned RetCount = numRetVals(&F);
5110b57cec5SDimitry Andric
5120b57cec5SDimitry Andric // Assume all return values are dead
5130b57cec5SDimitry Andric using RetVals = SmallVector<Liveness, 5>;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric RetVals RetValLiveness(RetCount, MaybeLive);
5160b57cec5SDimitry Andric
5170b57cec5SDimitry Andric using RetUses = SmallVector<UseVector, 5>;
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andric // These vectors map each return value to the uses that make it MaybeLive, so
5200b57cec5SDimitry Andric // we can add those to the Uses map if the return value really turns out to be
5210b57cec5SDimitry Andric // MaybeLive. Initialized to a list of RetCount empty lists.
5220b57cec5SDimitry Andric RetUses MaybeLiveRetUses(RetCount);
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric bool HasMustTailCalls = false;
52581ad6265SDimitry Andric for (const BasicBlock &BB : F) {
5260b57cec5SDimitry Andric // If we have any returns of `musttail` results - the signature can't
5270b57cec5SDimitry Andric // change
52806c3fb27SDimitry Andric if (const auto *TC = BB.getTerminatingMustTailCall()) {
5290b57cec5SDimitry Andric HasMustTailCalls = true;
53006c3fb27SDimitry Andric // In addition, if the called function is not locally defined (or unknown,
53106c3fb27SDimitry Andric // if this is an indirect call), we can't change the callsite and thus
53206c3fb27SDimitry Andric // can't change this function's signature either.
53306c3fb27SDimitry Andric if (!isMustTailCalleeAnalyzable(*TC)) {
53406c3fb27SDimitry Andric markLive(F);
53506c3fb27SDimitry Andric return;
53606c3fb27SDimitry Andric }
53706c3fb27SDimitry Andric }
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric
5400b57cec5SDimitry Andric if (HasMustTailCalls) {
5410b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - " << F.getName()
5420b57cec5SDimitry Andric << " has musttail calls\n");
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric if (!F.hasLocalLinkage() && (!ShouldHackArguments || F.isIntrinsic())) {
54681ad6265SDimitry Andric markLive(F);
5470b57cec5SDimitry Andric return;
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric LLVM_DEBUG(
5510b57cec5SDimitry Andric dbgs() << "DeadArgumentEliminationPass - Inspecting callers for fn: "
5520b57cec5SDimitry Andric << F.getName() << "\n");
5530b57cec5SDimitry Andric // Keep track of the number of live retvals, so we can skip checks once all
5540b57cec5SDimitry Andric // of them turn out to be live.
5550b57cec5SDimitry Andric unsigned NumLiveRetVals = 0;
5560b57cec5SDimitry Andric
5570b57cec5SDimitry Andric bool HasMustTailCallers = false;
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric // Loop all uses of the function.
5600b57cec5SDimitry Andric for (const Use &U : F.uses()) {
5610b57cec5SDimitry Andric // If the function is PASSED IN as an argument, its address has been
5620b57cec5SDimitry Andric // taken.
5635ffd83dbSDimitry Andric const auto *CB = dyn_cast<CallBase>(U.getUser());
56481ad6265SDimitry Andric if (!CB || !CB->isCallee(&U) ||
56581ad6265SDimitry Andric CB->getFunctionType() != F.getFunctionType()) {
56681ad6265SDimitry Andric markLive(F);
5670b57cec5SDimitry Andric return;
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andric // The number of arguments for `musttail` call must match the number of
5710b57cec5SDimitry Andric // arguments of the caller
5725ffd83dbSDimitry Andric if (CB->isMustTailCall())
5730b57cec5SDimitry Andric HasMustTailCallers = true;
5740b57cec5SDimitry Andric
5750b57cec5SDimitry Andric // If we end up here, we are looking at a direct call to our function.
5760b57cec5SDimitry Andric
5770b57cec5SDimitry Andric // Now, check how our return value(s) is/are used in this caller. Don't
5780b57cec5SDimitry Andric // bother checking return values if all of them are live already.
5790b57cec5SDimitry Andric if (NumLiveRetVals == RetCount)
5800b57cec5SDimitry Andric continue;
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric // Check all uses of the return value.
58381ad6265SDimitry Andric for (const Use &UU : CB->uses()) {
58481ad6265SDimitry Andric if (ExtractValueInst *Ext = dyn_cast<ExtractValueInst>(UU.getUser())) {
5850b57cec5SDimitry Andric // This use uses a part of our return value, survey the uses of
5860b57cec5SDimitry Andric // that part and store the results for this index only.
5870b57cec5SDimitry Andric unsigned Idx = *Ext->idx_begin();
5880b57cec5SDimitry Andric if (RetValLiveness[Idx] != Live) {
58981ad6265SDimitry Andric RetValLiveness[Idx] = surveyUses(Ext, MaybeLiveRetUses[Idx]);
5900b57cec5SDimitry Andric if (RetValLiveness[Idx] == Live)
5910b57cec5SDimitry Andric NumLiveRetVals++;
5920b57cec5SDimitry Andric }
5930b57cec5SDimitry Andric } else {
5940b57cec5SDimitry Andric // Used by something else than extractvalue. Survey, but assume that the
5950b57cec5SDimitry Andric // result applies to all sub-values.
5960b57cec5SDimitry Andric UseVector MaybeLiveAggregateUses;
59781ad6265SDimitry Andric if (surveyUse(&UU, MaybeLiveAggregateUses) == Live) {
5980b57cec5SDimitry Andric NumLiveRetVals = RetCount;
5990b57cec5SDimitry Andric RetValLiveness.assign(RetCount, Live);
6000b57cec5SDimitry Andric break;
60181ad6265SDimitry Andric }
60281ad6265SDimitry Andric
6035ffd83dbSDimitry Andric for (unsigned Ri = 0; Ri != RetCount; ++Ri) {
6045ffd83dbSDimitry Andric if (RetValLiveness[Ri] != Live)
6055ffd83dbSDimitry Andric MaybeLiveRetUses[Ri].append(MaybeLiveAggregateUses.begin(),
6060b57cec5SDimitry Andric MaybeLiveAggregateUses.end());
6070b57cec5SDimitry Andric }
6080b57cec5SDimitry Andric }
6090b57cec5SDimitry Andric }
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andric if (HasMustTailCallers) {
6130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - " << F.getName()
6140b57cec5SDimitry Andric << " has musttail callers\n");
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric
6170b57cec5SDimitry Andric // Now we've inspected all callers, record the liveness of our return values.
6185ffd83dbSDimitry Andric for (unsigned Ri = 0; Ri != RetCount; ++Ri)
61981ad6265SDimitry Andric markValue(createRet(&F, Ri), RetValLiveness[Ri], MaybeLiveRetUses[Ri]);
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Inspecting args for fn: "
6220b57cec5SDimitry Andric << F.getName() << "\n");
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric // Now, check all of our arguments.
6255ffd83dbSDimitry Andric unsigned ArgI = 0;
6260b57cec5SDimitry Andric UseVector MaybeLiveArgUses;
6275ffd83dbSDimitry Andric for (Function::const_arg_iterator AI = F.arg_begin(), E = F.arg_end();
6285ffd83dbSDimitry Andric AI != E; ++AI, ++ArgI) {
6290b57cec5SDimitry Andric Liveness Result;
6300b57cec5SDimitry Andric if (F.getFunctionType()->isVarArg() || HasMustTailCallers ||
6310b57cec5SDimitry Andric HasMustTailCalls) {
6320b57cec5SDimitry Andric // Variadic functions will already have a va_arg function expanded inside
6330b57cec5SDimitry Andric // them, making them potentially very sensitive to ABI changes resulting
6340b57cec5SDimitry Andric // from removing arguments entirely, so don't. For example AArch64 handles
6350b57cec5SDimitry Andric // register and stack HFAs very differently, and this is reflected in the
6360b57cec5SDimitry Andric // IR which has already been generated.
6370b57cec5SDimitry Andric //
6380b57cec5SDimitry Andric // `musttail` calls to this function restrict argument removal attempts.
6390b57cec5SDimitry Andric // The signature of the caller must match the signature of the function.
6400b57cec5SDimitry Andric //
6410b57cec5SDimitry Andric // `musttail` calls in this function prevents us from changing its
6420b57cec5SDimitry Andric // signature
6430b57cec5SDimitry Andric Result = Live;
6440b57cec5SDimitry Andric } else {
6450b57cec5SDimitry Andric // See what the effect of this use is (recording any uses that cause
6460b57cec5SDimitry Andric // MaybeLive in MaybeLiveArgUses).
64781ad6265SDimitry Andric Result = surveyUses(&*AI, MaybeLiveArgUses);
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric
6500b57cec5SDimitry Andric // Mark the result.
65181ad6265SDimitry Andric markValue(createArg(&F, ArgI), Result, MaybeLiveArgUses);
6520b57cec5SDimitry Andric // Clear the vector again for the next iteration.
6530b57cec5SDimitry Andric MaybeLiveArgUses.clear();
6540b57cec5SDimitry Andric }
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric
65781ad6265SDimitry Andric /// Marks the liveness of RA depending on L. If L is MaybeLive, it also takes
65881ad6265SDimitry Andric /// all uses in MaybeLiveUses and records them in Uses, such that RA will be
65981ad6265SDimitry Andric /// marked live if any use in MaybeLiveUses gets marked live later on.
markValue(const RetOrArg & RA,Liveness L,const UseVector & MaybeLiveUses)66081ad6265SDimitry Andric void DeadArgumentEliminationPass::markValue(const RetOrArg &RA, Liveness L,
6610b57cec5SDimitry Andric const UseVector &MaybeLiveUses) {
6620b57cec5SDimitry Andric switch (L) {
6630b57cec5SDimitry Andric case Live:
66481ad6265SDimitry Andric markLive(RA);
6650b57cec5SDimitry Andric break;
6660b57cec5SDimitry Andric case MaybeLive:
66781ad6265SDimitry Andric assert(!isLive(RA) && "Use is already live!");
668eaeb601bSDimitry Andric for (const auto &MaybeLiveUse : MaybeLiveUses) {
66981ad6265SDimitry Andric if (isLive(MaybeLiveUse)) {
670eaeb601bSDimitry Andric // A use is live, so this value is live.
67181ad6265SDimitry Andric markLive(RA);
672eaeb601bSDimitry Andric break;
67381ad6265SDimitry Andric }
674eaeb601bSDimitry Andric // Note any uses of this value, so this value can be
6750b57cec5SDimitry Andric // marked live whenever one of the uses becomes live.
67681ad6265SDimitry Andric Uses.emplace(MaybeLiveUse, RA);
677eaeb601bSDimitry Andric }
6780b57cec5SDimitry Andric break;
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric }
6810b57cec5SDimitry Andric
68281ad6265SDimitry Andric /// Mark the given Function as alive, meaning that it cannot be changed in any
68381ad6265SDimitry Andric /// way. Additionally, mark any values that are used as this function's
68481ad6265SDimitry Andric /// parameters or by its return values (according to Uses) live as well.
markLive(const Function & F)68581ad6265SDimitry Andric void DeadArgumentEliminationPass::markLive(const Function &F) {
6860b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Intrinsically live fn: "
6870b57cec5SDimitry Andric << F.getName() << "\n");
6880b57cec5SDimitry Andric // Mark the function as live.
6890b57cec5SDimitry Andric LiveFunctions.insert(&F);
6900b57cec5SDimitry Andric // Mark all arguments as live.
6915ffd83dbSDimitry Andric for (unsigned ArgI = 0, E = F.arg_size(); ArgI != E; ++ArgI)
69281ad6265SDimitry Andric propagateLiveness(createArg(&F, ArgI));
6930b57cec5SDimitry Andric // Mark all return values as live.
69481ad6265SDimitry Andric for (unsigned Ri = 0, E = numRetVals(&F); Ri != E; ++Ri)
69581ad6265SDimitry Andric propagateLiveness(createRet(&F, Ri));
6960b57cec5SDimitry Andric }
6970b57cec5SDimitry Andric
69881ad6265SDimitry Andric /// Mark the given return value or argument as live. Additionally, mark any
69981ad6265SDimitry Andric /// values that are used by this value (according to Uses) live as well.
markLive(const RetOrArg & RA)70081ad6265SDimitry Andric void DeadArgumentEliminationPass::markLive(const RetOrArg &RA) {
70181ad6265SDimitry Andric if (isLive(RA))
702eaeb601bSDimitry Andric return; // Already marked Live.
7030b57cec5SDimitry Andric
704eaeb601bSDimitry Andric LiveValues.insert(RA);
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Marking "
7070b57cec5SDimitry Andric << RA.getDescription() << " live\n");
70881ad6265SDimitry Andric propagateLiveness(RA);
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric
isLive(const RetOrArg & RA)71181ad6265SDimitry Andric bool DeadArgumentEliminationPass::isLive(const RetOrArg &RA) {
712eaeb601bSDimitry Andric return LiveFunctions.count(RA.F) || LiveValues.count(RA);
713eaeb601bSDimitry Andric }
714eaeb601bSDimitry Andric
71581ad6265SDimitry Andric /// Given that RA is a live value, propagate it's liveness to any other values
71681ad6265SDimitry Andric /// it uses (according to Uses).
propagateLiveness(const RetOrArg & RA)71781ad6265SDimitry Andric void DeadArgumentEliminationPass::propagateLiveness(const RetOrArg &RA) {
7180b57cec5SDimitry Andric // We don't use upper_bound (or equal_range) here, because our recursive call
7190b57cec5SDimitry Andric // to ourselves is likely to cause the upper_bound (which is the first value
7200b57cec5SDimitry Andric // not belonging to RA) to become erased and the iterator invalidated.
7210b57cec5SDimitry Andric UseMap::iterator Begin = Uses.lower_bound(RA);
7220b57cec5SDimitry Andric UseMap::iterator E = Uses.end();
7230b57cec5SDimitry Andric UseMap::iterator I;
7240b57cec5SDimitry Andric for (I = Begin; I != E && I->first == RA; ++I)
72581ad6265SDimitry Andric markLive(I->second);
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric // Erase RA from the Uses map (from the lower bound to wherever we ended up
7280b57cec5SDimitry Andric // after the loop).
7290b57cec5SDimitry Andric Uses.erase(Begin, I);
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric
73281ad6265SDimitry Andric /// Remove any arguments and return values from F that are not in LiveValues.
73381ad6265SDimitry Andric /// Transform the function and all the callees of the function to not have these
73481ad6265SDimitry Andric /// arguments and return values.
removeDeadStuffFromFunction(Function * F)73581ad6265SDimitry Andric bool DeadArgumentEliminationPass::removeDeadStuffFromFunction(Function *F) {
7360b57cec5SDimitry Andric // Don't modify fully live functions
7370b57cec5SDimitry Andric if (LiveFunctions.count(F))
7380b57cec5SDimitry Andric return false;
7390b57cec5SDimitry Andric
7400b57cec5SDimitry Andric // Start by computing a new prototype for the function, which is the same as
7410b57cec5SDimitry Andric // the old function, but has fewer arguments and a different return type.
7420b57cec5SDimitry Andric FunctionType *FTy = F->getFunctionType();
7430b57cec5SDimitry Andric std::vector<Type *> Params;
7440b57cec5SDimitry Andric
7450b57cec5SDimitry Andric // Keep track of if we have a live 'returned' argument
7460b57cec5SDimitry Andric bool HasLiveReturnedArg = false;
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andric // Set up to build a new list of parameter attributes.
7490b57cec5SDimitry Andric SmallVector<AttributeSet, 8> ArgAttrVec;
7500b57cec5SDimitry Andric const AttributeList &PAL = F->getAttributes();
7510b57cec5SDimitry Andric
7520b57cec5SDimitry Andric // Remember which arguments are still alive.
7530b57cec5SDimitry Andric SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
7540b57cec5SDimitry Andric // Construct the new parameter list from non-dead arguments. Also construct
7550b57cec5SDimitry Andric // a new set of parameter attributes to correspond. Skip the first parameter
7560b57cec5SDimitry Andric // attribute, since that belongs to the return value.
7575ffd83dbSDimitry Andric unsigned ArgI = 0;
7585ffd83dbSDimitry Andric for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
7595ffd83dbSDimitry Andric ++I, ++ArgI) {
76081ad6265SDimitry Andric RetOrArg Arg = createArg(F, ArgI);
7610b57cec5SDimitry Andric if (LiveValues.erase(Arg)) {
7620b57cec5SDimitry Andric Params.push_back(I->getType());
7635ffd83dbSDimitry Andric ArgAlive[ArgI] = true;
764349cc55cSDimitry Andric ArgAttrVec.push_back(PAL.getParamAttrs(ArgI));
765349cc55cSDimitry Andric HasLiveReturnedArg |= PAL.hasParamAttr(ArgI, Attribute::Returned);
7660b57cec5SDimitry Andric } else {
7670b57cec5SDimitry Andric ++NumArgumentsEliminated;
7680b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Removing argument "
7695ffd83dbSDimitry Andric << ArgI << " (" << I->getName() << ") from "
7700b57cec5SDimitry Andric << F->getName() << "\n");
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric
7740b57cec5SDimitry Andric // Find out the new return value.
7750b57cec5SDimitry Andric Type *RetTy = FTy->getReturnType();
7760b57cec5SDimitry Andric Type *NRetTy = nullptr;
77781ad6265SDimitry Andric unsigned RetCount = numRetVals(F);
7780b57cec5SDimitry Andric
7790b57cec5SDimitry Andric // -1 means unused, other numbers are the new index
7800b57cec5SDimitry Andric SmallVector<int, 5> NewRetIdxs(RetCount, -1);
7810b57cec5SDimitry Andric std::vector<Type *> RetTypes;
7820b57cec5SDimitry Andric
7830b57cec5SDimitry Andric // If there is a function with a live 'returned' argument but a dead return
7840b57cec5SDimitry Andric // value, then there are two possible actions:
7850b57cec5SDimitry Andric // 1) Eliminate the return value and take off the 'returned' attribute on the
7860b57cec5SDimitry Andric // argument.
7870b57cec5SDimitry Andric // 2) Retain the 'returned' attribute and treat the return value (but not the
7880b57cec5SDimitry Andric // entire function) as live so that it is not eliminated.
7890b57cec5SDimitry Andric //
7900b57cec5SDimitry Andric // It's not clear in the general case which option is more profitable because,
7910b57cec5SDimitry Andric // even in the absence of explicit uses of the return value, code generation
7920b57cec5SDimitry Andric // is free to use the 'returned' attribute to do things like eliding
79381ad6265SDimitry Andric // save/restores of registers across calls. Whether this happens is target and
79481ad6265SDimitry Andric // ABI-specific as well as depending on the amount of register pressure, so
79581ad6265SDimitry Andric // there's no good way for an IR-level pass to figure this out.
7960b57cec5SDimitry Andric //
7970b57cec5SDimitry Andric // Fortunately, the only places where 'returned' is currently generated by
7980b57cec5SDimitry Andric // the FE are places where 'returned' is basically free and almost always a
7990b57cec5SDimitry Andric // performance win, so the second option can just be used always for now.
8000b57cec5SDimitry Andric //
8010b57cec5SDimitry Andric // This should be revisited if 'returned' is ever applied more liberally.
8020b57cec5SDimitry Andric if (RetTy->isVoidTy() || HasLiveReturnedArg) {
8030b57cec5SDimitry Andric NRetTy = RetTy;
8040b57cec5SDimitry Andric } else {
8050b57cec5SDimitry Andric // Look at each of the original return values individually.
8065ffd83dbSDimitry Andric for (unsigned Ri = 0; Ri != RetCount; ++Ri) {
80781ad6265SDimitry Andric RetOrArg Ret = createRet(F, Ri);
8080b57cec5SDimitry Andric if (LiveValues.erase(Ret)) {
8095ffd83dbSDimitry Andric RetTypes.push_back(getRetComponentType(F, Ri));
8105ffd83dbSDimitry Andric NewRetIdxs[Ri] = RetTypes.size() - 1;
8110b57cec5SDimitry Andric } else {
8120b57cec5SDimitry Andric ++NumRetValsEliminated;
8130b57cec5SDimitry Andric LLVM_DEBUG(
8140b57cec5SDimitry Andric dbgs() << "DeadArgumentEliminationPass - Removing return value "
8155ffd83dbSDimitry Andric << Ri << " from " << F->getName() << "\n");
8160b57cec5SDimitry Andric }
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric if (RetTypes.size() > 1) {
8190b57cec5SDimitry Andric // More than one return type? Reduce it down to size.
8200b57cec5SDimitry Andric if (StructType *STy = dyn_cast<StructType>(RetTy)) {
8210b57cec5SDimitry Andric // Make the new struct packed if we used to return a packed struct
8220b57cec5SDimitry Andric // already.
8230b57cec5SDimitry Andric NRetTy = StructType::get(STy->getContext(), RetTypes, STy->isPacked());
8240b57cec5SDimitry Andric } else {
8250b57cec5SDimitry Andric assert(isa<ArrayType>(RetTy) && "unexpected multi-value return");
8260b57cec5SDimitry Andric NRetTy = ArrayType::get(RetTypes[0], RetTypes.size());
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric } else if (RetTypes.size() == 1)
8290b57cec5SDimitry Andric // One return type? Just a simple value then, but only if we didn't use to
8300b57cec5SDimitry Andric // return a struct with that simple value before.
8310b57cec5SDimitry Andric NRetTy = RetTypes.front();
8320b57cec5SDimitry Andric else if (RetTypes.empty())
8330b57cec5SDimitry Andric // No return types? Make it void, but only if we didn't use to return {}.
8340b57cec5SDimitry Andric NRetTy = Type::getVoidTy(F->getContext());
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric
8370b57cec5SDimitry Andric assert(NRetTy && "No new return type found?");
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric // The existing function return attributes.
84004eeddc0SDimitry Andric AttrBuilder RAttrs(F->getContext(), PAL.getRetAttrs());
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric // Remove any incompatible attributes, but only if we removed all return
8430b57cec5SDimitry Andric // values. Otherwise, ensure that we don't have any conflicting attributes
8440b57cec5SDimitry Andric // here. Currently, this should not be possible, but special handling might be
8450b57cec5SDimitry Andric // required when new return value attributes are added.
8460b57cec5SDimitry Andric if (NRetTy->isVoidTy())
8470b57cec5SDimitry Andric RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
8480b57cec5SDimitry Andric else
8490b57cec5SDimitry Andric assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
8500b57cec5SDimitry Andric "Return attributes no longer compatible?");
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andric AttributeSet RetAttrs = AttributeSet::get(F->getContext(), RAttrs);
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andric // Strip allocsize attributes. They might refer to the deleted arguments.
855349cc55cSDimitry Andric AttributeSet FnAttrs =
856349cc55cSDimitry Andric PAL.getFnAttrs().removeAttribute(F->getContext(), Attribute::AllocSize);
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andric // Reconstruct the AttributesList based on the vector we constructed.
8590b57cec5SDimitry Andric assert(ArgAttrVec.size() == Params.size());
8600b57cec5SDimitry Andric AttributeList NewPAL =
8610b57cec5SDimitry Andric AttributeList::get(F->getContext(), FnAttrs, RetAttrs, ArgAttrVec);
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andric // Create the new function type based on the recomputed parameters.
8640b57cec5SDimitry Andric FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg());
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andric // No change?
8670b57cec5SDimitry Andric if (NFTy == FTy)
8680b57cec5SDimitry Andric return false;
8690b57cec5SDimitry Andric
8700b57cec5SDimitry Andric // Create the new function body and insert it into the module...
8710b57cec5SDimitry Andric Function *NF = Function::Create(NFTy, F->getLinkage(), F->getAddressSpace());
8720b57cec5SDimitry Andric NF->copyAttributesFrom(F);
8730b57cec5SDimitry Andric NF->setComdat(F->getComdat());
8740b57cec5SDimitry Andric NF->setAttributes(NewPAL);
8750b57cec5SDimitry Andric // Insert the new function before the old function, so we won't be processing
8760b57cec5SDimitry Andric // it again.
8770b57cec5SDimitry Andric F->getParent()->getFunctionList().insert(F->getIterator(), NF);
8780b57cec5SDimitry Andric NF->takeName(F);
8795f757f3fSDimitry Andric NF->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;
8800b57cec5SDimitry Andric
88181ad6265SDimitry Andric // Loop over all the callers of the function, transforming the call sites to
88281ad6265SDimitry Andric // pass in a smaller number of arguments into the new function.
8830b57cec5SDimitry Andric std::vector<Value *> Args;
8840b57cec5SDimitry Andric while (!F->use_empty()) {
8855ffd83dbSDimitry Andric CallBase &CB = cast<CallBase>(*F->user_back());
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric ArgAttrVec.clear();
8885ffd83dbSDimitry Andric const AttributeList &CallPAL = CB.getAttributes();
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andric // Adjust the call return attributes in case the function was changed to
8910b57cec5SDimitry Andric // return void.
89204eeddc0SDimitry Andric AttrBuilder RAttrs(F->getContext(), CallPAL.getRetAttrs());
8930b57cec5SDimitry Andric RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
8940b57cec5SDimitry Andric AttributeSet RetAttrs = AttributeSet::get(F->getContext(), RAttrs);
8950b57cec5SDimitry Andric
8960b57cec5SDimitry Andric // Declare these outside of the loops, so we can reuse them for the second
8970b57cec5SDimitry Andric // loop, which loops the varargs.
89881ad6265SDimitry Andric auto *I = CB.arg_begin();
8995ffd83dbSDimitry Andric unsigned Pi = 0;
9000b57cec5SDimitry Andric // Loop over those operands, corresponding to the normal arguments to the
9010b57cec5SDimitry Andric // original function, and add those that are still alive.
9025ffd83dbSDimitry Andric for (unsigned E = FTy->getNumParams(); Pi != E; ++I, ++Pi)
9035ffd83dbSDimitry Andric if (ArgAlive[Pi]) {
9040b57cec5SDimitry Andric Args.push_back(*I);
9050b57cec5SDimitry Andric // Get original parameter attributes, but skip return attributes.
906349cc55cSDimitry Andric AttributeSet Attrs = CallPAL.getParamAttrs(Pi);
9070b57cec5SDimitry Andric if (NRetTy != RetTy && Attrs.hasAttribute(Attribute::Returned)) {
9080b57cec5SDimitry Andric // If the return type has changed, then get rid of 'returned' on the
9090b57cec5SDimitry Andric // call site. The alternative is to make all 'returned' attributes on
9100b57cec5SDimitry Andric // call sites keep the return value alive just like 'returned'
91181ad6265SDimitry Andric // attributes on function declaration, but it's less clearly a win and
9120b57cec5SDimitry Andric // this is not an expected case anyway
9130b57cec5SDimitry Andric ArgAttrVec.push_back(AttributeSet::get(
91481ad6265SDimitry Andric F->getContext(), AttrBuilder(F->getContext(), Attrs)
91581ad6265SDimitry Andric .removeAttribute(Attribute::Returned)));
9160b57cec5SDimitry Andric } else {
9170b57cec5SDimitry Andric // Otherwise, use the original attributes.
9180b57cec5SDimitry Andric ArgAttrVec.push_back(Attrs);
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric }
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andric // Push any varargs arguments on the list. Don't forget their attributes.
92381ad6265SDimitry Andric for (auto *E = CB.arg_end(); I != E; ++I, ++Pi) {
9240b57cec5SDimitry Andric Args.push_back(*I);
925349cc55cSDimitry Andric ArgAttrVec.push_back(CallPAL.getParamAttrs(Pi));
9260b57cec5SDimitry Andric }
9270b57cec5SDimitry Andric
9280b57cec5SDimitry Andric // Reconstruct the AttributesList based on the vector we constructed.
9290b57cec5SDimitry Andric assert(ArgAttrVec.size() == Args.size());
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andric // Again, be sure to remove any allocsize attributes, since their indices
9320b57cec5SDimitry Andric // may now be incorrect.
933349cc55cSDimitry Andric AttributeSet FnAttrs = CallPAL.getFnAttrs().removeAttribute(
9340b57cec5SDimitry Andric F->getContext(), Attribute::AllocSize);
9350b57cec5SDimitry Andric
93681ad6265SDimitry Andric AttributeList NewCallPAL =
93781ad6265SDimitry Andric AttributeList::get(F->getContext(), FnAttrs, RetAttrs, ArgAttrVec);
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andric SmallVector<OperandBundleDef, 1> OpBundles;
9405ffd83dbSDimitry Andric CB.getOperandBundlesAsDefs(OpBundles);
9410b57cec5SDimitry Andric
9425ffd83dbSDimitry Andric CallBase *NewCB = nullptr;
9435ffd83dbSDimitry Andric if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
9445ffd83dbSDimitry Andric NewCB = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
9455ffd83dbSDimitry Andric Args, OpBundles, "", CB.getParent());
9460b57cec5SDimitry Andric } else {
947*0fca6ea1SDimitry Andric NewCB = CallInst::Create(NFTy, NF, Args, OpBundles, "", CB.getIterator());
9485ffd83dbSDimitry Andric cast<CallInst>(NewCB)->setTailCallKind(
9495ffd83dbSDimitry Andric cast<CallInst>(&CB)->getTailCallKind());
9500b57cec5SDimitry Andric }
9515ffd83dbSDimitry Andric NewCB->setCallingConv(CB.getCallingConv());
9525ffd83dbSDimitry Andric NewCB->setAttributes(NewCallPAL);
9535ffd83dbSDimitry Andric NewCB->copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
9540b57cec5SDimitry Andric Args.clear();
9550b57cec5SDimitry Andric ArgAttrVec.clear();
9560b57cec5SDimitry Andric
9575ffd83dbSDimitry Andric if (!CB.use_empty() || CB.isUsedByMetadata()) {
9585ffd83dbSDimitry Andric if (NewCB->getType() == CB.getType()) {
9590b57cec5SDimitry Andric // Return type not changed? Just replace users then.
9605ffd83dbSDimitry Andric CB.replaceAllUsesWith(NewCB);
9615ffd83dbSDimitry Andric NewCB->takeName(&CB);
9625ffd83dbSDimitry Andric } else if (NewCB->getType()->isVoidTy()) {
96381ad6265SDimitry Andric // If the return value is dead, replace any uses of it with poison
9640b57cec5SDimitry Andric // (any non-debug value uses will get removed later on).
9655ffd83dbSDimitry Andric if (!CB.getType()->isX86_MMXTy())
96681ad6265SDimitry Andric CB.replaceAllUsesWith(PoisonValue::get(CB.getType()));
9670b57cec5SDimitry Andric } else {
9680b57cec5SDimitry Andric assert((RetTy->isStructTy() || RetTy->isArrayTy()) &&
9690b57cec5SDimitry Andric "Return type changed, but not into a void. The old return type"
9700b57cec5SDimitry Andric " must have been a struct or an array!");
9715ffd83dbSDimitry Andric Instruction *InsertPt = &CB;
9725ffd83dbSDimitry Andric if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
9735ffd83dbSDimitry Andric BasicBlock *NewEdge =
9745ffd83dbSDimitry Andric SplitEdge(NewCB->getParent(), II->getNormalDest());
9750b57cec5SDimitry Andric InsertPt = &*NewEdge->getFirstInsertionPt();
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andric // We used to return a struct or array. Instead of doing smart stuff
9790b57cec5SDimitry Andric // with all the uses, we will just rebuild it using extract/insertvalue
9800b57cec5SDimitry Andric // chaining and let instcombine clean that up.
9810b57cec5SDimitry Andric //
98281ad6265SDimitry Andric // Start out building up our return value from poison
98381ad6265SDimitry Andric Value *RetVal = PoisonValue::get(RetTy);
9845ffd83dbSDimitry Andric for (unsigned Ri = 0; Ri != RetCount; ++Ri)
9855ffd83dbSDimitry Andric if (NewRetIdxs[Ri] != -1) {
9860b57cec5SDimitry Andric Value *V;
9875ffd83dbSDimitry Andric IRBuilder<NoFolder> IRB(InsertPt);
9880b57cec5SDimitry Andric if (RetTypes.size() > 1)
9890b57cec5SDimitry Andric // We are still returning a struct, so extract the value from our
9900b57cec5SDimitry Andric // return value
9915ffd83dbSDimitry Andric V = IRB.CreateExtractValue(NewCB, NewRetIdxs[Ri], "newret");
9920b57cec5SDimitry Andric else
9930b57cec5SDimitry Andric // We are now returning a single element, so just insert that
9945ffd83dbSDimitry Andric V = NewCB;
9950b57cec5SDimitry Andric // Insert the value at the old position
9965ffd83dbSDimitry Andric RetVal = IRB.CreateInsertValue(RetVal, V, Ri, "oldret");
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric // Now, replace all uses of the old call instruction with the return
9990b57cec5SDimitry Andric // struct we built
10005ffd83dbSDimitry Andric CB.replaceAllUsesWith(RetVal);
10015ffd83dbSDimitry Andric NewCB->takeName(&CB);
10020b57cec5SDimitry Andric }
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric
10050b57cec5SDimitry Andric // Finally, remove the old call from the program, reducing the use-count of
10060b57cec5SDimitry Andric // F.
10075ffd83dbSDimitry Andric CB.eraseFromParent();
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric
10100b57cec5SDimitry Andric // Since we have now created the new function, splice the body of the old
10110b57cec5SDimitry Andric // function right into the new function, leaving the old rotting hulk of the
10120b57cec5SDimitry Andric // function empty.
1013bdd1243dSDimitry Andric NF->splice(NF->begin(), F);
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric // Loop over the argument list, transferring uses of the old arguments over to
10160b57cec5SDimitry Andric // the new arguments, also transferring over the names as well.
10175ffd83dbSDimitry Andric ArgI = 0;
10180b57cec5SDimitry Andric for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
10195ffd83dbSDimitry Andric I2 = NF->arg_begin();
10205ffd83dbSDimitry Andric I != E; ++I, ++ArgI)
10215ffd83dbSDimitry Andric if (ArgAlive[ArgI]) {
10220b57cec5SDimitry Andric // If this is a live argument, move the name and users over to the new
10230b57cec5SDimitry Andric // version.
10240b57cec5SDimitry Andric I->replaceAllUsesWith(&*I2);
10250b57cec5SDimitry Andric I2->takeName(&*I);
10260b57cec5SDimitry Andric ++I2;
10270b57cec5SDimitry Andric } else {
102881ad6265SDimitry Andric // If this argument is dead, replace any uses of it with poison
10290b57cec5SDimitry Andric // (any non-debug value uses will get removed later on).
10300b57cec5SDimitry Andric if (!I->getType()->isX86_MMXTy())
103181ad6265SDimitry Andric I->replaceAllUsesWith(PoisonValue::get(I->getType()));
10320b57cec5SDimitry Andric }
10330b57cec5SDimitry Andric
10340b57cec5SDimitry Andric // If we change the return value of the function we must rewrite any return
10350b57cec5SDimitry Andric // instructions. Check this now.
10360b57cec5SDimitry Andric if (F->getReturnType() != NF->getReturnType())
10370b57cec5SDimitry Andric for (BasicBlock &BB : *NF)
10380b57cec5SDimitry Andric if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
10395ffd83dbSDimitry Andric IRBuilder<NoFolder> IRB(RI);
10405ffd83dbSDimitry Andric Value *RetVal = nullptr;
10410b57cec5SDimitry Andric
10425ffd83dbSDimitry Andric if (!NFTy->getReturnType()->isVoidTy()) {
10430b57cec5SDimitry Andric assert(RetTy->isStructTy() || RetTy->isArrayTy());
10440b57cec5SDimitry Andric // The original return value was a struct or array, insert
10450b57cec5SDimitry Andric // extractvalue/insertvalue chains to extract only the values we need
10460b57cec5SDimitry Andric // to return and insert them into our new result.
10470b57cec5SDimitry Andric // This does generate messy code, but we'll let it to instcombine to
10480b57cec5SDimitry Andric // clean that up.
10490b57cec5SDimitry Andric Value *OldRet = RI->getOperand(0);
105081ad6265SDimitry Andric // Start out building up our return value from poison
105181ad6265SDimitry Andric RetVal = PoisonValue::get(NRetTy);
10525ffd83dbSDimitry Andric for (unsigned RetI = 0; RetI != RetCount; ++RetI)
10535ffd83dbSDimitry Andric if (NewRetIdxs[RetI] != -1) {
10545ffd83dbSDimitry Andric Value *EV = IRB.CreateExtractValue(OldRet, RetI, "oldret");
10555ffd83dbSDimitry Andric
10560b57cec5SDimitry Andric if (RetTypes.size() > 1) {
10570b57cec5SDimitry Andric // We're still returning a struct, so reinsert the value into
10580b57cec5SDimitry Andric // our new return value at the new index
10590b57cec5SDimitry Andric
10605ffd83dbSDimitry Andric RetVal = IRB.CreateInsertValue(RetVal, EV, NewRetIdxs[RetI],
10615ffd83dbSDimitry Andric "newret");
10620b57cec5SDimitry Andric } else {
10630b57cec5SDimitry Andric // We are now only returning a simple value, so just return the
10640b57cec5SDimitry Andric // extracted value.
10650b57cec5SDimitry Andric RetVal = EV;
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric }
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric // Replace the return instruction with one returning the new return
10700b57cec5SDimitry Andric // value (possibly 0 if we became void).
1071*0fca6ea1SDimitry Andric auto *NewRet =
1072*0fca6ea1SDimitry Andric ReturnInst::Create(F->getContext(), RetVal, RI->getIterator());
10735ffd83dbSDimitry Andric NewRet->setDebugLoc(RI->getDebugLoc());
1074bdd1243dSDimitry Andric RI->eraseFromParent();
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric
107781ad6265SDimitry Andric // Clone metadata from the old function, including debug info descriptor.
10780b57cec5SDimitry Andric SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
10790b57cec5SDimitry Andric F->getAllMetadata(MDs);
1080bdd1243dSDimitry Andric for (auto [KindID, Node] : MDs)
1081bdd1243dSDimitry Andric NF->addMetadata(KindID, *Node);
10820b57cec5SDimitry Andric
108381ad6265SDimitry Andric // If either the return value(s) or argument(s) are removed, then probably the
108481ad6265SDimitry Andric // function does not follow standard calling conventions anymore. Hence, add
108581ad6265SDimitry Andric // DW_CC_nocall to DISubroutineType to inform debugger that it may not be safe
108681ad6265SDimitry Andric // to call this function or try to interpret the return value.
108781ad6265SDimitry Andric if (NFTy != FTy && NF->getSubprogram()) {
108881ad6265SDimitry Andric DISubprogram *SP = NF->getSubprogram();
108981ad6265SDimitry Andric auto Temp = SP->getType()->cloneWithCC(llvm::dwarf::DW_CC_nocall);
109081ad6265SDimitry Andric SP->replaceType(MDNode::replaceWithPermanent(std::move(Temp)));
109181ad6265SDimitry Andric }
109281ad6265SDimitry Andric
10930b57cec5SDimitry Andric // Now that the old function is dead, delete it.
10940b57cec5SDimitry Andric F->eraseFromParent();
10950b57cec5SDimitry Andric
10960b57cec5SDimitry Andric return true;
10970b57cec5SDimitry Andric }
10980b57cec5SDimitry Andric
propagateVirtMustcallLiveness(const Module & M)109906c3fb27SDimitry Andric void DeadArgumentEliminationPass::propagateVirtMustcallLiveness(
110006c3fb27SDimitry Andric const Module &M) {
110106c3fb27SDimitry Andric // If a function was marked "live", and it has musttail callers, they in turn
110206c3fb27SDimitry Andric // can't change either.
110306c3fb27SDimitry Andric LiveFuncSet NewLiveFuncs(LiveFunctions);
110406c3fb27SDimitry Andric while (!NewLiveFuncs.empty()) {
110506c3fb27SDimitry Andric LiveFuncSet Temp;
110606c3fb27SDimitry Andric for (const auto *F : NewLiveFuncs)
110706c3fb27SDimitry Andric for (const auto *U : F->users())
110806c3fb27SDimitry Andric if (const auto *CB = dyn_cast<CallBase>(U))
110906c3fb27SDimitry Andric if (CB->isMustTailCall())
111006c3fb27SDimitry Andric if (!LiveFunctions.count(CB->getParent()->getParent()))
111106c3fb27SDimitry Andric Temp.insert(CB->getParent()->getParent());
111206c3fb27SDimitry Andric NewLiveFuncs.clear();
111306c3fb27SDimitry Andric NewLiveFuncs.insert(Temp.begin(), Temp.end());
111406c3fb27SDimitry Andric for (const auto *F : Temp)
111506c3fb27SDimitry Andric markLive(*F);
111606c3fb27SDimitry Andric }
111706c3fb27SDimitry Andric }
111806c3fb27SDimitry Andric
run(Module & M,ModuleAnalysisManager &)11190b57cec5SDimitry Andric PreservedAnalyses DeadArgumentEliminationPass::run(Module &M,
11200b57cec5SDimitry Andric ModuleAnalysisManager &) {
11210b57cec5SDimitry Andric bool Changed = false;
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric // First pass: Do a simple check to see if any functions can have their "..."
11240b57cec5SDimitry Andric // removed. We can do this if they never call va_start. This loop cannot be
11250b57cec5SDimitry Andric // fused with the next loop, because deleting a function invalidates
11260b57cec5SDimitry Andric // information computed while surveying other functions.
11270b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Deleting dead varargs\n");
1128349cc55cSDimitry Andric for (Function &F : llvm::make_early_inc_range(M))
11290b57cec5SDimitry Andric if (F.getFunctionType()->isVarArg())
113081ad6265SDimitry Andric Changed |= deleteDeadVarargs(F);
11310b57cec5SDimitry Andric
113281ad6265SDimitry Andric // Second phase: Loop through the module, determining which arguments are
113381ad6265SDimitry Andric // live. We assume all arguments are dead unless proven otherwise (allowing us
113481ad6265SDimitry Andric // to determine that dead arguments passed into recursive functions are dead).
11350b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "DeadArgumentEliminationPass - Determining liveness\n");
11360b57cec5SDimitry Andric for (auto &F : M)
113781ad6265SDimitry Andric surveyFunction(F);
11380b57cec5SDimitry Andric
113906c3fb27SDimitry Andric propagateVirtMustcallLiveness(M);
114006c3fb27SDimitry Andric
11410b57cec5SDimitry Andric // Now, remove all dead arguments and return values from each function in
1142349cc55cSDimitry Andric // turn. We use make_early_inc_range here because functions will probably get
1143349cc55cSDimitry Andric // removed (i.e. replaced by new ones).
1144349cc55cSDimitry Andric for (Function &F : llvm::make_early_inc_range(M))
114581ad6265SDimitry Andric Changed |= removeDeadStuffFromFunction(&F);
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andric // Finally, look for any unused parameters in functions with non-local
114881ad6265SDimitry Andric // linkage and replace the passed in parameters with poison.
11490b57cec5SDimitry Andric for (auto &F : M)
115081ad6265SDimitry Andric Changed |= removeDeadArgumentsFromCallers(F);
11510b57cec5SDimitry Andric
11520b57cec5SDimitry Andric if (!Changed)
11530b57cec5SDimitry Andric return PreservedAnalyses::all();
11540b57cec5SDimitry Andric return PreservedAnalyses::none();
11550b57cec5SDimitry Andric }
1156