[PM] Replace an abuse of inheritance to override a single function with
authorChandler Carruth <chandlerc@gmail.com>
Wed, 21 Jan 2015 02:11:59 +0000 (02:11 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 21 Jan 2015 02:11:59 +0000 (02:11 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226640 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/SimplifyLibCalls.h
lib/Transforms/InstCombine/InstructionCombining.cpp
lib/Transforms/Utils/SimplifyLibCalls.cpp

index d2f096fd1efd4773274cf48904ab73d238004684..fb3beb2ab2d7a973b390321bd26de87990cb4953 100644 (file)
@@ -71,12 +71,21 @@ private:
   const DataLayout *DL;
   const TargetLibraryInfo *TLI;
   bool UnsafeFPShrink;
   const DataLayout *DL;
   const TargetLibraryInfo *TLI;
   bool UnsafeFPShrink;
+  function_ref<void(Instruction *, Value *)> 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:
 
 public:
-  LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI);
+  LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
+                    function_ref<void(Instruction *, Value *)> Replacer =
+                        &replaceAllUsesWithDefault);
 
   /// optimizeCall - Take the given call instruction and return a more
   /// optimal value to replace the instruction with or 0 if a more
 
   /// 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);
 
   /// 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);
 private:
   // String and Memory Library Call Optimizations
   Value *optimizeStrCat(CallInst *CI, IRBuilder<> &B);
index a012be0669a036a1c8ae2ceaf2e01eba995022d5..33f024b2729fb25882aba3be73de26b610acb1b3 100644 (file)
@@ -2919,25 +2919,6 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
   return MadeIRChange;
 }
 
   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
 // 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;
 
       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;
   Simplifier = &TheSimplifier;
 
   bool EverMadeChange = false;
index 76d5cc4917d1f8068b0b924897a7d49253d74dde..13c2365e1efb8563b75e422df0a5f114d9c053a3 100644 (file)
@@ -2084,15 +2084,19 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
   return nullptr;
 }
 
   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<void(Instruction *, Value *)> 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();
 }
   I->replaceAllUsesWith(With);
   I->eraseFromParent();
 }