From 0975ed5f4ef7264b45995241717055f8a116bb27 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 7 May 2005 04:24:13 +0000 Subject: [PATCH] Convert shifts to muls to assist reassociation. This implements 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 | 29 +++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index d91b24f6957..d00423edf5a 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -22,11 +22,11 @@ #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(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(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.