[llvm-commits] [llvm] r44643 - /llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp

Evan Cheng evan.cheng at apple.com
Wed Dec 5 15:58:20 PST 2007


Author: evancheng
Date: Wed Dec  5 17:58:20 2007
New Revision: 44643

URL: http://llvm.org/viewvc/llvm-project?rev=44643&view=rev
Log:
If both result of the {s|z}xt and its source are live out, rewrite all uses of the source with result of extension.

Modified:
    llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp?rev=44643&r1=44642&r2=44643&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CodeGenPrepare.cpp Wed Dec  5 17:58:20 2007
@@ -28,11 +28,17 @@
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 using namespace llvm;
 
+namespace {
+  cl::opt<bool> OptExtUses("optimize-ext-uses",
+                           cl::init(false), cl::Hidden);
+}
+
 namespace {  
   class VISIBILITY_HIDDEN CodeGenPrepare : public FunctionPass {
     /// TLI - Keep a pointer of a TargetLowering to consult for determining
@@ -52,6 +58,7 @@
     bool OptimizeLoadStoreInst(Instruction *I, Value *Addr,
                                const Type *AccessTy,
                                DenseMap<Value*,Value*> &SunkAddrs);
+    bool OptimizeExtUses(Instruction *I);
   };
 }
 
@@ -913,6 +920,61 @@
   return true;
 }
 
+bool CodeGenPrepare::OptimizeExtUses(Instruction *I) {
+  BasicBlock *DefBB = I->getParent();
+
+  // If both result of the {s|z}xt and its source are live out, rewrite all
+  // other uses of the source with result of extension.
+  Value *Src = I->getOperand(0);
+  if (Src->hasOneUse())
+    return false;
+
+  bool DefIsLiveOut = false;
+  for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); 
+       UI != E; ++UI) {
+    Instruction *User = cast<Instruction>(*UI);
+
+    // Figure out which BB this ext is used in.
+    BasicBlock *UserBB = User->getParent();
+    if (UserBB == DefBB) continue;
+    DefIsLiveOut = true;
+    break;
+  }
+  if (!DefIsLiveOut)
+    return false;
+
+  // InsertedTruncs - Only insert one trunc in each block once.
+  DenseMap<BasicBlock*, Instruction*> InsertedTruncs;
+
+  bool MadeChange = false;
+  for (Value::use_iterator UI = Src->use_begin(), E = Src->use_end(); 
+       UI != E; ++UI) {
+    Use &TheUse = UI.getUse();
+    Instruction *User = cast<Instruction>(*UI);
+
+    // Figure out which BB this ext is used in.
+    BasicBlock *UserBB = User->getParent();
+    if (UserBB == DefBB) continue;
+
+    // Both src and def are live in this block. Rewrite the use.
+    Instruction *&InsertedTrunc = InsertedTruncs[UserBB];
+
+    if (!InsertedTrunc) {
+      BasicBlock::iterator InsertPt = UserBB->begin();
+      while (isa<PHINode>(InsertPt)) ++InsertPt;
+      
+      InsertedTrunc = new TruncInst(I, Src->getType(), "", InsertPt);
+    }
+
+    // Replace a use of the {s|z}ext source with a use of the result.
+    TheUse = InsertedTrunc;
+
+    MadeChange = true;
+  }
+
+  return MadeChange;
+}
+
 // In this pass we look for GEP and cast instructions that are used
 // across basic blocks and rewrite them to improve basic-block-at-a-time
 // selection.
@@ -948,8 +1010,14 @@
       if (isa<Constant>(CI->getOperand(0)))
         continue;
       
-      if (TLI)
-        MadeChange |= OptimizeNoopCopyExpression(CI, *TLI);
+      bool Change = false;
+      if (TLI) {
+        Change = OptimizeNoopCopyExpression(CI, *TLI);
+        MadeChange |= Change;
+      }
+
+      if (OptExtUses && !Change && (isa<ZExtInst>(I) || isa<SExtInst>(I)))
+        MadeChange |= OptimizeExtUses(I);
     } else if (CmpInst *CI = dyn_cast<CmpInst>(I)) {
       MadeChange |= OptimizeCmpExpression(CI);
     } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {





More information about the llvm-commits mailing list