diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Transforms/IPO/MergeFunctions.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/MergeFunctions.cpp | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 8b9abaddc84c..06d2a2f31941 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -115,12 +115,14 @@ #include "llvm/IR/Value.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/ValueMap.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/Transforms/Utils/FunctionComparator.h" #include <algorithm> #include <cassert> @@ -195,16 +197,12 @@ public: /// by considering all pointer types to be equivalent. Once identified, /// MergeFunctions will fold them by replacing a call to one to a call to a /// bitcast of the other. -class MergeFunctions : public ModulePass { +class MergeFunctions { public: - static char ID; - - MergeFunctions() - : ModulePass(ID), FnTree(FunctionNodeCmp(&GlobalNumbers)) { - initializeMergeFunctionsPass(*PassRegistry::getPassRegistry()); + MergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) { } - bool runOnModule(Module &M) override; + bool runOnModule(Module &M); private: // The function comparison operator is provided here so that FunctionNodes do @@ -297,14 +295,39 @@ private: DenseMap<AssertingVH<Function>, FnTreeType::iterator> FNodesInTree; }; -} // end anonymous namespace +class MergeFunctionsLegacyPass : public ModulePass { +public: + static char ID; + + MergeFunctionsLegacyPass(): ModulePass(ID) { + initializeMergeFunctionsLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + if (skipModule(M)) + return false; -char MergeFunctions::ID = 0; + MergeFunctions MF; + return MF.runOnModule(M); + } +}; -INITIALIZE_PASS(MergeFunctions, "mergefunc", "Merge Functions", false, false) +} // end anonymous namespace + +char MergeFunctionsLegacyPass::ID = 0; +INITIALIZE_PASS(MergeFunctionsLegacyPass, "mergefunc", + "Merge Functions", false, false) ModulePass *llvm::createMergeFunctionsPass() { - return new MergeFunctions(); + return new MergeFunctionsLegacyPass(); +} + +PreservedAnalyses MergeFunctionsPass::run(Module &M, + ModuleAnalysisManager &AM) { + MergeFunctions MF; + if (!MF.runOnModule(M)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); } #ifndef NDEBUG @@ -386,9 +409,6 @@ static bool isEligibleForMerging(Function &F) { } bool MergeFunctions::runOnModule(Module &M) { - if (skipModule(M)) - return false; - bool Changed = false; // All functions in the module, ordered by hash. Functions with a unique @@ -449,28 +469,10 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) { ++UI; CallSite CS(U->getUser()); if (CS && CS.isCallee(U)) { - // Transfer the called function's attributes to the call site. Due to the - // bitcast we will 'lose' ABI changing attributes because the 'called - // function' is no longer a Function* but the bitcast. Code that looks up - // the attributes from the called function will fail. - - // FIXME: This is not actually true, at least not anymore. The callsite - // will always have the same ABI affecting attributes as the callee, - // because otherwise the original input has UB. Note that Old and New - // always have matching ABI, so no attributes need to be changed. - // Transferring other attributes may help other optimizations, but that - // should be done uniformly and not in this ad-hoc way. - auto &Context = New->getContext(); - auto NewPAL = New->getAttributes(); - SmallVector<AttributeSet, 4> NewArgAttrs; - for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) - NewArgAttrs.push_back(NewPAL.getParamAttributes(argIdx)); - // Don't transfer attributes from the function to the callee. Function - // attributes typically aren't relevant to the calling convention or ABI. - CS.setAttributes(AttributeList::get(Context, /*FnAttrs=*/AttributeSet(), - NewPAL.getRetAttributes(), - NewArgAttrs)); - + // Do not copy attributes from the called function to the call-site. + // Function comparison ensures that the attributes are the same up to + // type congruences in byval(), in which case we need to keep the byval + // type of the call-site, not the callee function. remove(CS.getInstruction()->getFunction()); U->set(BitcastNew); } |