From 9280382ac6f023efd009c99c0b522a9edbeb6152 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 21 Jan 2015 02:11:59 +0000 Subject: [PATCH] [PM] Replace an abuse of inheritance to override a single function with a more direct approach: a type-erased glorified function pointer. Now we can pass a function pointer into this for the easy case and we can even pass a lambda into it in the interesting case in the instruction combiner. I'll be using this shortly to simplify the interfaces to InstCombiner, but this helps pave the way and seems like a better design for the libcall simplifier utility. llvm-svn: 226640 --- .../llvm/Transforms/Utils/SimplifyLibCalls.h | 20 ++++++++++-------- .../InstCombine/InstructionCombining.cpp | 24 ++++------------------ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 18 +++++++++------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h index d2f096f..fb3beb2 100644 --- a/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h @@ -71,12 +71,21 @@ private: const DataLayout *DL; const TargetLibraryInfo *TLI; bool UnsafeFPShrink; + function_ref Replacer; -protected: - ~LibCallSimplifier() {} + /// \brief Internal wrapper for RAUW that is the default implementation. + /// + /// Other users may provide an alternate function with this signature instead + /// of this one. + static void replaceAllUsesWithDefault(Instruction *I, Value *With); + + /// \brief Replace an instruction's uses with a value using our replacer. + void replaceAllUsesWith(Instruction *I, Value *With); public: - LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI); + LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI, + function_ref Replacer = + &replaceAllUsesWithDefault); /// optimizeCall - Take the given call instruction and return a more /// optimal value to replace the instruction with or 0 if a more @@ -87,11 +96,6 @@ public: /// The call must not be an indirect call. Value *optimizeCall(CallInst *CI); - /// replaceAllUsesWith - This method is used when the library call - /// simplifier needs to replace instructions other than the library - /// call being modified. - virtual void replaceAllUsesWith(Instruction *I, Value *With) const; - private: // String and Memory Library Call Optimizations Value *optimizeStrCat(CallInst *CI, IRBuilder<> &B); diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index a012be0..33f024b 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2919,25 +2919,6 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) { return MadeIRChange; } -namespace { -class InstCombinerLibCallSimplifier final : public LibCallSimplifier { - InstCombiner *IC; -public: - InstCombinerLibCallSimplifier(const DataLayout *DL, - const TargetLibraryInfo *TLI, - InstCombiner *IC) - : LibCallSimplifier(DL, TLI) { - this->IC = IC; - } - - /// replaceAllUsesWith - override so that instruction replacement - /// can be defined in terms of the instruction combiner framework. - void replaceAllUsesWith(Instruction *I, Value *With) const override { - IC->ReplaceInstUsesWith(*I, With); - } -}; -} - // FIXME: Passing all of the analyses here in the run method is ugly. We should // separate out the worklist from the combiner so that we can construct // a combiner once per function while re-using the storage of an external @@ -2962,7 +2943,10 @@ bool InstCombiner::run(Function &F, AssumptionCache *AC, const DataLayout *DL, F.getContext(), TargetFolder(DL), InstCombineIRInserter(Worklist, AC)); Builder = &TheBuilder; - InstCombinerLibCallSimplifier TheSimplifier(DL, TLI, this); + auto InstCombineRAUW = [this](Instruction *From, Value *With) { + ReplaceInstUsesWith(*From, With); + }; + LibCallSimplifier TheSimplifier(DL, TLI, InstCombineRAUW); Simplifier = &TheSimplifier; bool EverMadeChange = false; diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 76d5cc4..13c2365 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2084,15 +2084,19 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) { return nullptr; } -LibCallSimplifier::LibCallSimplifier(const DataLayout *DL, - const TargetLibraryInfo *TLI) : - FortifiedSimplifier(DL, TLI), - DL(DL), - TLI(TLI), - UnsafeFPShrink(false) { +LibCallSimplifier::LibCallSimplifier( + const DataLayout *DL, const TargetLibraryInfo *TLI, + function_ref Replacer) + : FortifiedSimplifier(DL, TLI), DL(DL), TLI(TLI), UnsafeFPShrink(false), + Replacer(Replacer) {} + +void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) { + // Indirect through the replacer used in this instance. + Replacer(I, With); } -void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const { +/*static*/ void LibCallSimplifier::replaceAllUsesWithDefault(Instruction *I, + Value *With) { I->replaceAllUsesWith(With); I->eraseFromParent(); } -- 2.7.4