Add method for replacing instructions to LibCallSimplifier
authorMeador Inge <meadori@codesourcery.com>
Sun, 11 Nov 2012 03:51:43 +0000 (03:51 +0000)
committerMeador Inge <meadori@codesourcery.com>
Sun, 11 Nov 2012 03:51:43 +0000 (03:51 +0000)
In some cases the library call simplifier may need to replace instructions
other than the library call being simplified.  In those cases it may be
necessary for clients of the simplifier to override how the replacements
are actually done.  As such, a new overrideable method for replacing
instructions was added to LibCallSimplifier.

A new subclass of LibCallSimplifier is also defined which overrides
the instruction replacement method.  This is because the instruction
combiner defines its own replacement method which updates the worklist
when instructions are replaced.

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

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

index 5db2d00181407c24efa60001e5d9d7a4cad26380..fde452bca23589ced2c58bf9463754a2c65adf87 100644 (file)
@@ -19,6 +19,7 @@ namespace llvm {
   class Value;
   class CallInst;
   class DataLayout;
+  class Instruction;
   class TargetLibraryInfo;
   class LibCallSimplifierImpl;
 
@@ -35,8 +36,16 @@ namespace llvm {
 
     /// optimizeCall - Take the given call instruction and return a more
     /// optimal value to replace the instruction with or 0 if a more
-    /// optimal form can't be found.
+    /// optimal form can't be found.  Note that the returned value may
+    /// be equal to the instruction being optimized.  In this case all
+    /// other instructions that use the given instruction were modified
+    /// and the given instruction is dead.
     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;
   };
 } // End llvm namespace
 
index ccf75bca2b9185b697194e8474ba9017cb81c435..9a46f25e66ff812cd63447e260e8b24f3ed7db72 100644 (file)
@@ -2367,6 +2367,24 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) {
   return MadeIRChange;
 }
 
+namespace {
+class InstCombinerLibCallSimplifier : public LibCallSimplifier {
+  InstCombiner *IC;
+public:
+  InstCombinerLibCallSimplifier(const DataLayout *TD,
+                                const TargetLibraryInfo *TLI,
+                                InstCombiner *IC)
+    : LibCallSimplifier(TD, TLI) {
+    this->IC = IC;
+  }
+
+  /// replaceAllUsesWith - override so that instruction replacement
+  /// can be defined in terms of the instruction combiner framework.
+  virtual void replaceAllUsesWith(Instruction *I, Value *With) const {
+    IC->ReplaceInstUsesWith(*I, With);
+  }
+};
+}
 
 bool InstCombiner::runOnFunction(Function &F) {
   TD = getAnalysisIfAvailable<DataLayout>();
@@ -2379,7 +2397,7 @@ bool InstCombiner::runOnFunction(Function &F) {
                InstCombineIRInserter(Worklist));
   Builder = &TheBuilder;
 
-  LibCallSimplifier TheSimplifier(TD, TLI);
+  InstCombinerLibCallSimplifier TheSimplifier(TD, TLI, this);
   Simplifier = &TheSimplifier;
 
   bool EverMadeChange = false;
index 74d4e22fa44600bcb0d2a988d53f8092f0104890..e3e9266e5237419d8cb48d76e861997f482e05e9 100644 (file)
@@ -34,6 +34,7 @@ protected:
   Function *Caller;
   const DataLayout *TD;
   const TargetLibraryInfo *TLI;
+  const LibCallSimplifier *LCS;
   LLVMContext* Context;
 public:
   LibCallOptimization() { }
@@ -48,10 +49,12 @@ public:
     =0;
 
   Value *optimizeCall(CallInst *CI, const DataLayout *TD,
-                      const TargetLibraryInfo *TLI, IRBuilder<> &B) {
+                      const TargetLibraryInfo *TLI,
+                      const LibCallSimplifier *LCS, IRBuilder<> &B) {
     Caller = CI->getParent()->getParent();
     this->TD = TD;
     this->TLI = TLI;
+    this->LCS = LCS;
     if (CI->getCalledFunction())
       Context = &CI->getCalledFunction()->getContext();
 
@@ -840,6 +843,7 @@ namespace llvm {
 class LibCallSimplifierImpl {
   const DataLayout *TD;
   const TargetLibraryInfo *TLI;
+  const LibCallSimplifier *LCS;
   StringMap<LibCallOptimization*> Optimizations;
 
   // Fortified library call optimizations.
@@ -869,9 +873,11 @@ class LibCallSimplifierImpl {
   void initOptimizations();
   void addOpt(LibFunc::Func F, LibCallOptimization* Opt);
 public:
-  LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI) {
+  LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI,
+                        const LibCallSimplifier *LCS) {
     this->TD = TD;
     this->TLI = TLI;
+    this->LCS = LCS;
   }
 
   Value *optimizeCall(CallInst *CI);
@@ -918,7 +924,7 @@ Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
   LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
   if (LCO) {
     IRBuilder<> Builder(CI);
-    return LCO->optimizeCall(CI, TD, TLI, Builder);
+    return LCO->optimizeCall(CI, TD, TLI, LCS, Builder);
   }
   return 0;
 }
@@ -930,7 +936,7 @@ void LibCallSimplifierImpl::addOpt(LibFunc::Func F, LibCallOptimization* Opt) {
 
 LibCallSimplifier::LibCallSimplifier(const DataLayout *TD,
                                      const TargetLibraryInfo *TLI) {
-  Impl = new LibCallSimplifierImpl(TD, TLI);
+  Impl = new LibCallSimplifierImpl(TD, TLI, this);
 }
 
 LibCallSimplifier::~LibCallSimplifier() {
@@ -941,4 +947,9 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
   return Impl->optimizeCall(CI);
 }
 
+void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const {
+  I->replaceAllUsesWith(With);
+  I->eraseFromParent();
+}
+
 }