diff options
author | Chris Lattner <sabre@nondot.org> | 2003-07-24 17:52:58 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-07-24 17:52:58 +0000 |
commit | 08fd7abb42cadf2d14a3ca8103b73a358468391f (patch) | |
tree | 81e7a213f056681ae5f53dec878c3ea1081b9f96 /lib/Transforms | |
parent | 3d8d9f7e72d5a75b5d538b8af09f8151d1adc22a (diff) | |
download | external_llvm-08fd7abb42cadf2d14a3ca8103b73a358468391f.zip external_llvm-08fd7abb42cadf2d14a3ca8103b73a358468391f.tar.gz external_llvm-08fd7abb42cadf2d14a3ca8103b73a358468391f.tar.bz2 |
Reorganization of code, no functional changes.
Now it shoudl be a bit more efficient
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7292 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 95 |
1 files changed, 48 insertions, 47 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 0db6dcf..ed86fde 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -876,51 +876,10 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { Op0 == Constant::getNullValue(Op0->getType())) return ReplaceInstUsesWith(I, Op0); - // If this is a shift of a shift, see if we can fold the two together... - if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0)) { - if (isa<Constant>(Op1) && isa<Constant>(Op0SI->getOperand(1))) { - ConstantUInt *ShiftAmt1C = cast<ConstantUInt>(Op0SI->getOperand(1)); - unsigned ShiftAmt1 = ShiftAmt1C->getValue(); - unsigned ShiftAmt2 = cast<ConstantUInt>(Op1)->getValue(); - - // Check for (A << c1) << c2 and (A >> c1) >> c2 - if (I.getOpcode() == Op0SI->getOpcode()) { - unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift... - return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), - ConstantUInt::get(Type::UByteTy, Amt)); - } - - if (I.getType()->isUnsigned()) { // Check for (A << c1) >> c2 or visaversa - // Calculate bitmask for what gets shifted off the edge... - Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); - if (I.getOpcode() == Instruction::Shr) - C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C); - else - C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C); - - Instruction *Mask = - BinaryOperator::create(Instruction::And, Op0SI->getOperand(0), - C, Op0SI->getOperand(0)->getName()+".mask",&I); - WorkList.push_back(Mask); - - // Figure out what flavor of shift we should use... - if (ShiftAmt1 == ShiftAmt2) - return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 - else if (ShiftAmt1 < ShiftAmt2) { - return new ShiftInst(I.getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); - } else { - return new ShiftInst(Op0SI->getOpcode(), Mask, - ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); - } - } - } - } - - // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr of - // a signed value. - // if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) { + // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr + // of a signed value. + // unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8; if (CUI->getValue() >= TypeBits && (!Op0->getType()->isSigned() || I.getOpcode() == Instruction::Shl)) @@ -932,12 +891,54 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) { // Convert 'shl int %X, 1' to 'add int %X, %X' return BinaryOperator::create(Instruction::Add, Op0, Op0, I.getName()); + // If this is a shift of a shift, see if we can fold the two together... + if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0)) { + if (isa<ConstantUInt>(Op1) && isa<Constant>(Op0SI->getOperand(1))) { + ConstantUInt *ShiftAmt1C = cast<ConstantUInt>(Op0SI->getOperand(1)); + unsigned ShiftAmt1 = ShiftAmt1C->getValue(); + unsigned ShiftAmt2 = CUI->getValue(); + + // Check for (A << c1) << c2 and (A >> c1) >> c2 + if (I.getOpcode() == Op0SI->getOpcode()) { + unsigned Amt = ShiftAmt1+ShiftAmt2; // Fold into one big shift... + return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0), + ConstantUInt::get(Type::UByteTy, Amt)); + } + + // Check for (A << c1) >> c2 or visaversa + if (I.getType()->isUnsigned()) { + // Calculate bitmask for what gets shifted off the edge... + Constant *C = ConstantIntegral::getAllOnesValue(I.getType()); + if (I.getOpcode() == Instruction::Shr) + C = ConstantExpr::getShift(Instruction::Shr, C, ShiftAmt1C); + else + C = ConstantExpr::getShift(Instruction::Shl, C, ShiftAmt1C); + + Instruction *Mask = + BinaryOperator::create(Instruction::And, Op0SI->getOperand(0), + C, Op0SI->getOperand(0)->getName()+".mask"); + InsertNewInstBefore(Mask, I); + + // Figure out what flavor of shift we should use... + if (ShiftAmt1 == ShiftAmt2) + return ReplaceInstUsesWith(I, Mask); // (A << c) >> c === A & c2 + else if (ShiftAmt1 < ShiftAmt2) { + return new ShiftInst(I.getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1)); + } else { + return new ShiftInst(Op0SI->getOpcode(), Mask, + ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2)); + } + } + } + } } // shr int -1, X = -1 (for any arithmetic shift rights of ~0) - if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0)) - if (I.getOpcode() == Instruction::Shr && CSI->isAllOnesValue()) - return ReplaceInstUsesWith(I, CSI); + if (I.getOpcode() == Instruction::Shr) + if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0)) + if (CSI->isAllOnesValue()) + return ReplaceInstUsesWith(I, CSI); return 0; } |