From 118d919a6a47867c553842a815f304f0477509be Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Thu, 31 Mar 2016 05:14:22 +0000 Subject: [PATCH] [SCEV] NFC code motion to simplify later change llvm-svn: 264993 --- llvm/lib/Analysis/ScalarEvolution.cpp | 154 +++++++++++++------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index bd26045ea424..7d383835fa45 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3798,6 +3798,83 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) { return Result; } +namespace { +/// Represents an abstract binary operation. This may exist as a +/// normal instruction or constant expression, or may have been +/// derived from an expression tree. +struct BinaryOp { + unsigned Opcode; + Value *LHS; + Value *RHS; + + /// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or + /// constant expression. + Operator *Op; + + explicit BinaryOp(Operator *Op) + : Opcode(Op->getOpcode()), LHS(Op->getOperand(0)), RHS(Op->getOperand(1)), + Op(Op) {} + + explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS) + : Opcode(Opcode), LHS(LHS), RHS(RHS), Op(nullptr) {} +}; +} + + +/// Try to map \p V into a BinaryOp, and return \c None on failure. +static Optional MatchBinaryOp(Value *V) { + auto *Op = dyn_cast(V); + if (!Op) + return None; + + // Implementation detail: all the cleverness here should happen without + // creating new SCEV expressions -- our caller knowns tricks to avoid creating + // SCEV expressions when possible, and we should not break that. + + switch (Op->getOpcode()) { + case Instruction::Add: + case Instruction::Sub: + case Instruction::Mul: + case Instruction::UDiv: + case Instruction::And: + case Instruction::Or: + case Instruction::AShr: + case Instruction::Shl: + return BinaryOp(Op); + + case Instruction::Xor: + if (auto *RHSC = dyn_cast(Op->getOperand(1))) + // If the RHS of the xor is a signbit, then this is just an add. + // Instcombine turns add of signbit into xor as a strength reduction step. + if (RHSC->getValue().isSignBit()) + return BinaryOp(Instruction::Add, Op->getOperand(0), Op->getOperand(1)); + return BinaryOp(Op); + + case Instruction::LShr: + // Turn logical shift right of a constant into a unsigned divide. + if (ConstantInt *SA = dyn_cast(Op->getOperand(1))) { + uint32_t BitWidth = cast(Op->getType())->getBitWidth(); + + // If the shift count is not less than the bitwidth, the result of + // the shift is undefined. Don't try to analyze it, because the + // resolution chosen here may differ from the resolution chosen in + // other parts of the compiler. + if (SA->getValue().ult(BitWidth)) { + Constant *X = + ConstantInt::get(SA->getContext(), + APInt::getOneBitSet(BitWidth, SA->getZExtValue())); + return BinaryOp(Instruction::UDiv, Op->getOperand(0), X); + } + } + return BinaryOp(Op); + + default: + break; + } + + return None; +} + const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) { const Loop *L = LI.getLoopFor(PN->getParent()); if (!L || L->getHeader() != PN->getParent()) @@ -4723,83 +4800,6 @@ SCEV::NoWrapFlags ScalarEvolution::getNoWrapFlagsFromUB(const Value *V) { return SCEV::FlagAnyWrap; } -namespace { -/// Represents an abstract binary operation. This may exist as a -/// normal instruction or constant expression, or may have been -/// derived from an expression tree. -struct BinaryOp { - unsigned Opcode; - Value *LHS; - Value *RHS; - - /// Op is set if this BinaryOp corresponds to a concrete LLVM instruction or - /// constant expression. - Operator *Op; - - explicit BinaryOp(Operator *Op) - : Opcode(Op->getOpcode()), LHS(Op->getOperand(0)), RHS(Op->getOperand(1)), - Op(Op) {} - - explicit BinaryOp(unsigned Opcode, Value *LHS, Value *RHS) - : Opcode(Opcode), LHS(LHS), RHS(RHS), Op(nullptr) {} -}; -} - - -/// Try to map \p V into a BinaryOp, and return \c None on failure. -static Optional MatchBinaryOp(Value *V) { - auto *Op = dyn_cast(V); - if (!Op) - return None; - - // Implementation detail: all the cleverness here should happen without - // creating new SCEV expressions -- our caller knowns tricks to avoid creating - // SCEV expressions when possible, and we should not break that. - - switch (Op->getOpcode()) { - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::UDiv: - case Instruction::And: - case Instruction::Or: - case Instruction::AShr: - case Instruction::Shl: - return BinaryOp(Op); - - case Instruction::Xor: - if (auto *RHSC = dyn_cast(Op->getOperand(1))) - // If the RHS of the xor is a signbit, then this is just an add. - // Instcombine turns add of signbit into xor as a strength reduction step. - if (RHSC->getValue().isSignBit()) - return BinaryOp(Instruction::Add, Op->getOperand(0), Op->getOperand(1)); - return BinaryOp(Op); - - case Instruction::LShr: - // Turn logical shift right of a constant into a unsigned divide. - if (ConstantInt *SA = dyn_cast(Op->getOperand(1))) { - uint32_t BitWidth = cast(Op->getType())->getBitWidth(); - - // If the shift count is not less than the bitwidth, the result of - // the shift is undefined. Don't try to analyze it, because the - // resolution chosen here may differ from the resolution chosen in - // other parts of the compiler. - if (SA->getValue().ult(BitWidth)) { - Constant *X = - ConstantInt::get(SA->getContext(), - APInt::getOneBitSet(BitWidth, SA->getZExtValue())); - return BinaryOp(Instruction::UDiv, Op->getOperand(0), X); - } - } - return BinaryOp(Op); - - default: - break; - } - - return None; -} - /// createSCEV - We know that there is no SCEV for the specified value. Analyze /// the expression. ///