Convert shifts to muls to assist reassociation. This implements
authorChris Lattner <sabre@nondot.org>
Sat, 7 May 2005 04:24:13 +0000 (04:24 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 7 May 2005 04:24:13 +0000 (04:24 +0000)
Reassociate/shifttest.ll

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

lib/Transforms/Scalar/Reassociate.cpp

index d91b24f6957547ea2649c10cb2e250740e250ae6..d00423edf5affd14d22c3af61780be5c14699cf5 100644 (file)
 
 #define DEBUG_TYPE "reassociate"
 #include "llvm/Transforms/Scalar.h"
+#include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
-#include "llvm/Type.h"
 #include "llvm/Pass.h"
-#include "llvm/Constant.h"
+#include "llvm/Type.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/ADT/PostOrderIterator.h"
@@ -243,6 +243,25 @@ static Instruction *BreakUpSubtract(Instruction *Sub) {
   return New;
 }
 
+/// ConvertShiftToMul - If this is a shift of a reassociable multiply or is used
+/// by one, change this into a multiply by a constant to assist with further
+/// reassociation.
+static Instruction *ConvertShiftToMul(Instruction *Shl) {
+  if (!isReassociableOp(Shl->getOperand(0), Instruction::Mul) &&
+      !(Shl->hasOneUse() && isReassociableOp(Shl->use_back(),Instruction::Mul)))
+    return 0;
+
+  Constant *MulCst = ConstantInt::get(Shl->getType(), 1);
+  MulCst = ConstantExpr::getShl(MulCst, cast<Constant>(Shl->getOperand(1)));
+
+  std::string Name = Shl->getName();  Shl->setName("");
+  Instruction *Mul = BinaryOperator::createMul(Shl->getOperand(0), MulCst,
+                                               Name, Shl);
+  Shl->replaceAllUsesWith(Mul);
+  Shl->eraseFromParent();
+  return Mul;
+}
+
 
 /// ReassociateBB - Inspect all of the instructions in this basic block,
 /// reassociating them as we go.
@@ -256,6 +275,12 @@ bool Reassociate::ReassociateBB(BasicBlock *BB) {
         Changed = true;
         BI = NI;
       }
+    if (BI->getOpcode() == Instruction::Shl &&
+        isa<ConstantInt>(BI->getOperand(1)))
+      if (Instruction *NI = ConvertShiftToMul(BI)) {
+        Changed = true;
+        BI = NI;
+      }
 
     // If this instruction is a commutative binary operator, and the ranks of
     // the two operands are sorted incorrectly, fix it now.