forked from OSchip/llvm-project
[SCEV] NFC code motion to simplify later change
llvm-svn: 264993
This commit is contained in:
parent
d2aa03a60a
commit
118d919a6a
|
@ -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<BinaryOp> MatchBinaryOp(Value *V) {
|
||||
auto *Op = dyn_cast<Operator>(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<ConstantInt>(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<ConstantInt>(Op->getOperand(1))) {
|
||||
uint32_t BitWidth = cast<IntegerType>(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<BinaryOp> MatchBinaryOp(Value *V) {
|
||||
auto *Op = dyn_cast<Operator>(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<ConstantInt>(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<ConstantInt>(Op->getOperand(1))) {
|
||||
uint32_t BitWidth = cast<IntegerType>(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.
|
||||
///
|
||||
|
|
Loading…
Reference in New Issue