Added SCEV::NoWrapFlags to manage unsigned, signed, and self wrap

properties.
Added the self-wrap flag for SCEV::AddRecExpr.
A slew of temporary FIXMEs indicate the intention of the no-self-wrap flag
without changing behavior in this revision.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127590 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick
2011-03-14 16:50:06 +00:00
parent d99b39e43b
commit 3228cc259b
7 changed files with 307 additions and 182 deletions

View File

@@ -160,13 +160,8 @@ namespace llvm {
const Type *getType() const { return getOperand(0)->getType(); }
bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); }
void setHasNoUnsignedWrap(bool B) {
SubclassData = (SubclassData & ~(1 << 0)) | (B << 0);
}
bool hasNoSignedWrap() const { return SubclassData & (1 << 1); }
void setHasNoSignedWrap(bool B) {
SubclassData = (SubclassData & ~(1 << 1)) | (B << 1);
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const {
return (NoWrapFlags)(SubclassData & Mask);
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -199,6 +194,11 @@ namespace llvm {
S->getSCEVType() == scSMaxExpr ||
S->getSCEVType() == scUMaxExpr;
}
/// Set flags for a non-recurrence without clearing previously set flags.
void setNoWrapFlags(NoWrapFlags Flags) {
SubclassData |= Flags;
}
};
@@ -305,11 +305,12 @@ namespace llvm {
/// getStepRecurrence - This method constructs and returns the recurrence
/// indicating how much this expression steps by. If this is a polynomial
/// of degree N, it returns a chrec of degree N-1.
/// We cannot determine whether the step recurrence has self-wraparound.
const SCEV *getStepRecurrence(ScalarEvolution &SE) const {
if (isAffine()) return getOperand(1);
return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1,
op_end()),
getLoop());
getLoop(), FlagAnyWrap);
}
/// isAffine - Return true if this is an affine AddRec (i.e., it represents
@@ -327,6 +328,15 @@ namespace llvm {
return getNumOperands() == 3;
}
/// Set flags for a recurrence without clearing any previously set flags.
/// For AddRec, either NUW or NSW implies NW. Keep track of this fact here
/// to make it easier to propagate flags.
void setNoWrapFlags(NoWrapFlags Flags) {
if (Flags & (FlagNUW | FlagNSW))
Flags = ScalarEvolution::setFlags(Flags, FlagNW);
SubclassData |= Flags;
}
/// evaluateAtIteration - Return the value of this chain of recurrences at
/// the specified iteration number.
const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const;
@@ -364,8 +374,7 @@ namespace llvm {
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scSMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public:
@@ -387,8 +396,7 @@ namespace llvm {
const SCEV *const *O, size_t N)
: SCEVCommutativeExpr(ID, scUMaxExpr, O, N) {
// Max never overflows.
setHasNoUnsignedWrap(true);
setHasNoSignedWrap(true);
setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW));
}
public: