38 #define DEBUG_TYPE "loop-unroll"
42 cl::desc(
"The baseline cost threshold for loop unrolling"));
46 cl::desc(
"The percentage of estimated dynamic cost which must be saved by "
47 "unrolling to allow unrolling up to the max threshold."));
51 cl::desc(
"This is the amount discounted from the total unroll cost when "
52 "the unrolled form has a high dynamic cost savings (triggered by "
53 "the '-unroll-perecent-dynamic-cost-saved-threshold' flag)."));
57 cl::desc(
"Don't allow loop unrolling to simulate more than this number of"
58 "iterations when checking full unroll profitability"));
62 cl::desc(
"Use this unroll count for all loops including those with "
63 "unroll_count pragma values, for testing purposes"));
67 cl::desc(
"Allows loops to be partially unrolled until "
68 "-unroll-threshold loop size is reached."));
72 cl::desc(
"Unroll loops with run-time trip counts"));
76 cl::desc(
"Unrolled size limit for loops with an unroll(full) or "
77 "unroll_count pragma."));
83 LoopUnroll(
int T = -1,
int C = -1,
int P = -1,
int R = -1) :
LoopPass(
ID) {
85 CurrentPercentDynamicCostSavedThreshold =
93 UserPercentDynamicCostSavedThreshold =
95 UserDynamicCostSavingsDiscount =
97 UserAllowPartial = (
P != -1) ||
99 UserRuntime = (R != -1) || (
UnrollRuntime.getNumOccurrences() > 0);
100 UserCount = (
C != -1) || (
UnrollCount.getNumOccurrences() > 0);
108 static const unsigned NoThreshold = UINT_MAX;
112 static const unsigned OptSizeUnrollThreshold = 50;
116 static const unsigned UnrollRuntimeCount = 8;
118 unsigned CurrentCount;
119 unsigned CurrentThreshold;
120 unsigned CurrentPercentDynamicCostSavedThreshold;
121 unsigned CurrentDynamicCostSavingsDiscount;
122 bool CurrentAllowPartial;
128 bool UserPercentDynamicCostSavedThreshold;
129 bool UserDynamicCostSavingsDiscount;
130 bool UserAllowPartial;
162 CurrentPercentDynamicCostSavedThreshold;
167 UP.
Count = CurrentCount;
169 UP.
Partial = CurrentAllowPartial;
180 selectUnrollCount(
const Loop *L,
unsigned TripCount,
bool PragmaFullUnroll,
181 unsigned PragmaCount,
183 bool &SetExplicitly);
189 void selectThresholds(
const Loop *L,
bool HasPragma,
191 unsigned &
Threshold,
unsigned &PartialThreshold,
192 unsigned &PercentDynamicCostSavedThreshold,
193 unsigned &DynamicCostSavingsDiscount) {
199 Threshold = UserThreshold ? CurrentThreshold : UP.
Threshold;
201 PercentDynamicCostSavedThreshold =
202 UserPercentDynamicCostSavedThreshold
203 ? CurrentPercentDynamicCostSavedThreshold
205 DynamicCostSavingsDiscount = UserDynamicCostSavingsDiscount
206 ? CurrentDynamicCostSavingsDiscount
209 if (!UserThreshold &&
210 L->
getHeader()->getParent()->hasFnAttribute(
220 if (Threshold != NoThreshold)
222 if (PartialThreshold != NoThreshold)
227 bool canUnrollCompletely(
Loop *L,
unsigned Threshold,
228 unsigned PercentDynamicCostSavedThreshold,
229 unsigned DynamicCostSavingsDiscount,
230 uint64_t UnrolledCost, uint64_t RolledDynamicCost);
246 return new LoopUnroll(Threshold, Count, AllowPartial, Runtime);
270 class UnrolledInstAnalyzer :
private InstVisitor<UnrolledInstAnalyzer, bool> {
273 struct SimplifiedAddress {
274 Value *Base =
nullptr;
279 UnrolledInstAnalyzer(
unsigned Iteration,
282 : Iteration(Iteration), SimplifiedValues(SimplifiedValues), L(L), SE(SE) {
307 const SCEV *IterationNumber;
335 if (
auto *
SC = dyn_cast<SCEVConstant>(S)) {
336 SimplifiedValues[
I] =
SC->getValue();
344 const SCEV *ValueAtIteration = AR->evaluateAtIteration(IterationNumber, SE);
346 if (
auto *
SC = dyn_cast<SCEVConstant>(ValueAtIteration)) {
347 SimplifiedValues[
I] =
SC->getValue();
360 Address.Base = Base->getValue();
361 Address.Offset = Offset->getValue();
368 return simplifyInstWithSCEV(&I);
380 if (!isa<Constant>(LHS))
383 if (!isa<Constant>(RHS))
387 Value *SimpleV =
nullptr;
389 if (
auto FI = dyn_cast<FPMathOperator>(&I))
395 if (
Constant *
C = dyn_cast_or_null<Constant>(SimpleV))
396 SimplifiedValues[&I] =
C;
400 return Base::visitBinaryOperator(I);
407 auto AddressIt = SimplifiedAddresses.find(AddrOp);
408 if (AddressIt == SimplifiedAddresses.end())
410 ConstantInt *SimplifiedAddrOp = AddressIt->second.Offset;
415 if (!GV || !GV->hasInitializer())
425 "Unexpectedly large index value.");
426 int64_t Index = SimplifiedAddrOp->
getSExtValue() / ElemSize;
434 assert(CV &&
"Constant expected.");
435 SimplifiedValues[&
I] = CV;
444 struct EstimatedUnrollCost {
446 unsigned UnrolledCost;
450 unsigned RolledDynamicCost;
470 unsigned MaxUnrolledLoopSize) {
475 "The unroll iterations max is too large!");
487 unsigned UnrolledCost = 0;
493 unsigned RolledDynamicCost = 0;
499 for (
unsigned Iteration = 0; Iteration < TripCount; ++Iteration) {
500 SimplifiedValues.
clear();
501 UnrolledInstAnalyzer Analyzer(Iteration, SimplifiedValues, L, SE);
506 for (
unsigned Idx = 0; Idx != BBWorklist.
size(); ++Idx) {
518 if (!Analyzer.visit(I))
519 UnrolledCost += InstCost;
523 RolledDynamicCost += InstCost;
526 if (UnrolledCost > MaxUnrolledLoopSize)
538 if (UnrolledCost == RolledDynamicCost)
541 return {{UnrolledCost, RolledDynamicCost}};
546 bool &NotDuplicatable,
559 unsigned LoopSize = Metrics.
NumInsts;
567 LoopSize = std::max(LoopSize, 3u);
602 "Unroll count hint metadata should have two operands.");
604 mdconst::extract<ConstantInt>(MD->
getOperand(1))->getZExtValue();
605 assert(Count >= 1 &&
"Unroll count must be positive.");
623 for (
unsigned i = 1, ie = LoopID->
getNumOperands(); i < ie; ++i) {
624 bool IsUnrollMetadata =
false;
630 if (!IsUnrollMetadata)
647 bool LoopUnroll::canUnrollCompletely(
Loop *L,
unsigned Threshold,
648 unsigned PercentDynamicCostSavedThreshold,
649 unsigned DynamicCostSavingsDiscount,
650 uint64_t UnrolledCost,
651 uint64_t RolledDynamicCost) {
653 if (Threshold == NoThreshold) {
654 DEBUG(
dbgs() <<
" Can fully unroll, because no threshold is set.\n");
658 if (UnrolledCost <= Threshold) {
659 DEBUG(
dbgs() <<
" Can fully unroll, because unrolled cost: "
660 << UnrolledCost <<
"<" << Threshold <<
"\n");
664 assert(UnrolledCost &&
"UnrolledCost can't be 0 at this point.");
665 assert(RolledDynamicCost >= UnrolledCost &&
666 "Cannot have a higher unrolled cost than a rolled cost!");
672 unsigned PercentDynamicCostSaved =
673 (uint64_t)(RolledDynamicCost - UnrolledCost) * 100ull / RolledDynamicCost;
675 if (PercentDynamicCostSaved >= PercentDynamicCostSavedThreshold &&
676 (int64_t)UnrolledCost - (int64_t)DynamicCostSavingsDiscount <=
677 (int64_t)Threshold) {
678 DEBUG(
dbgs() <<
" Can fully unroll, because unrolling will reduce the "
679 "expected dynamic cost by " << PercentDynamicCostSaved
680 <<
"% (threshold: " << PercentDynamicCostSavedThreshold
682 <<
" and the unrolled cost (" << UnrolledCost
683 <<
") is less than the max threshold ("
684 << DynamicCostSavingsDiscount <<
").\n");
688 DEBUG(
dbgs() <<
" Too large to fully unroll:\n");
689 DEBUG(
dbgs() <<
" Threshold: " << Threshold <<
"\n");
690 DEBUG(
dbgs() <<
" Max threshold: " << DynamicCostSavingsDiscount <<
"\n");
691 DEBUG(
dbgs() <<
" Percent cost saved threshold: "
692 << PercentDynamicCostSavedThreshold <<
"%\n");
693 DEBUG(
dbgs() <<
" Unrolled cost: " << UnrolledCost <<
"\n");
694 DEBUG(
dbgs() <<
" Rolled dynamic cost: " << RolledDynamicCost <<
"\n");
695 DEBUG(
dbgs() <<
" Percent cost saved: " << PercentDynamicCostSaved
700 unsigned LoopUnroll::selectUnrollCount(
701 const Loop *L,
unsigned TripCount,
bool PragmaFullUnroll,
703 bool &SetExplicitly) {
704 SetExplicitly =
true;
708 unsigned Count = UserCount ? CurrentCount : 0;
715 }
else if (PragmaFullUnroll) {
724 SetExplicitly =
false;
727 Count = UnrollRuntimeCount;
735 if (TripCount && Count > TripCount)
741 if (skipOptnoneFunction(L))
746 LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
749 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
750 auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
754 <<
"] Loop %" << Header->
getName() <<
"\n");
761 bool HasPragma = PragmaFullUnroll || PragmaCount > 0;
764 getUnrollingPreferences(L, TTI, UP);
767 unsigned TripCount = 0;
768 unsigned TripMultiple = 1;
782 bool CountSetExplicitly;
783 unsigned Count = selectUnrollCount(L, TripCount, PragmaFullUnroll,
784 PragmaCount, UP, CountSetExplicitly);
786 unsigned NumInlineCandidates;
787 bool notDuplicatable;
790 DEBUG(
dbgs() <<
" Loop Size = " << LoopSize <<
"\n");
795 uint64_t UnrolledSize = (uint64_t)(LoopSize-2) * Count + 2;
796 if (notDuplicatable) {
797 DEBUG(
dbgs() <<
" Not unrolling loop which contains non-duplicatable"
798 <<
" instructions.\n");
801 if (NumInlineCandidates != 0) {
802 DEBUG(
dbgs() <<
" Not unrolling loop with inlinable calls.\n");
807 unsigned PercentDynamicCostSavedThreshold;
808 unsigned DynamicCostSavingsDiscount;
809 selectThresholds(L, HasPragma, UP, Threshold, PartialThreshold,
810 PercentDynamicCostSavedThreshold,
811 DynamicCostSavingsDiscount);
815 enum {
Full = 0, Partial = 1, Runtime = 2 };
817 if (TripCount && Count == TripCount) {
820 if (canUnrollCompletely(L, Threshold, 100, DynamicCostSavingsDiscount,
821 UnrolledSize, UnrolledSize)) {
828 L, TripCount, *SE, TTI, Threshold + DynamicCostSavingsDiscount))
829 if (canUnrollCompletely(L, Threshold, PercentDynamicCostSavedThreshold,
830 DynamicCostSavingsDiscount, Cost->UnrolledCost,
831 Cost->RolledDynamicCost)) {
835 }
else if (TripCount && Count < TripCount) {
842 unsigned OriginalCount = Count;
844 (PragmaCount > 0) || (UserRuntime ? CurrentRuntime : UP.
Runtime);
847 AllowRuntime =
false;
849 if (Unrolling == Partial) {
850 bool AllowPartial = UserAllowPartial ? CurrentAllowPartial : UP.
Partial;
851 if (!AllowPartial && !CountSetExplicitly) {
852 DEBUG(
dbgs() <<
" will not try to unroll partially because "
853 <<
"-unroll-allow-partial not given\n");
856 if (PartialThreshold != NoThreshold && UnrolledSize > PartialThreshold) {
858 Count = (std::max(PartialThreshold, 3u)-2) / (LoopSize-2);
859 while (Count != 0 && TripCount % Count != 0)
862 }
else if (Unrolling == Runtime) {
863 if (!AllowRuntime && !CountSetExplicitly) {
864 DEBUG(
dbgs() <<
" will not try to unroll loop with runtime trip count "
865 <<
"-unroll-runtime not given\n");
870 while (Count != 0 && UnrolledSize > PartialThreshold) {
872 UnrolledSize = (LoopSize-2) * Count + 2;
876 DEBUG(
dbgs() <<
" partially unrolling with count: " << Count <<
"\n");
880 if (PragmaCount != 0)
890 if (PragmaFullUnroll && PragmaCount == 0) {
891 if (TripCount && Count != TripCount) {
894 "Unable to fully unroll loop as directed by unroll(full) pragma "
895 "because unrolled size is too large.");
896 }
else if (!TripCount) {
899 "Unable to fully unroll loop as directed by unroll(full) pragma "
900 "because loop has a runtime trip count.");
902 }
else if (PragmaCount > 0 && Count != OriginalCount) {
905 "Unable to unroll loop the number of times directed by "
906 "unroll_count pragma because unrolled size is too large.");
910 if (Unrolling !=
Full && Count < 2) {
918 TripMultiple, LI,
this, &LPM, &AC))
Pass interface - Implemented by all 'passes'.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Base class for instruction visitors.
const SCEV * getConstant(ConstantInt *V)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
static MDString * get(LLVMContext &Context, StringRef Str)
unsigned getNumOperands() const
Return number of MDNode operands.
const SCEV * getPointerBase(const SCEV *V)
getPointerBase - Transitively follow the chain of pointer-type operands until reaching a SCEV that do...
ScalarEvolution - This class is the main scalar evolution driver.
Constant * getElementAsConstant(unsigned i) const
getElementAsConstant - Return a Constant for a specified index's element.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
bool isLoopExiting(const BlockT *BB) const
isLoopExiting - True if terminator in the block can branch to another block that is outside of the cu...
const Function * getParent() const
Return the enclosing method, or null if none.
unsigned NumInlineCandidates
The number of calls to internal functions with a single caller.
static cl::opt< unsigned > UnrollCount("unroll-count", cl::init(0), cl::Hidden, cl::desc("Use this unroll count for all loops including those with ""unroll_count pragma values, for testing purposes"))
LoadInst - an instruction for reading from memory.
bool notDuplicatable
True if this function cannot be duplicated.
size_type size() const
Determine the number of elements in the SetVector.
BlockT * getHeader() const
StringRef getName() const
Return a constant reference to the value's name.
BlockT * getLoopLatch() const
getLoopLatch - If there is a single latch block for this loop, return it.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static cl::opt< unsigned > UnrollMaxIterationsCountToAnalyze("unroll-max-iteration-count-to-analyze", cl::init(0), cl::Hidden, cl::desc("Don't allow loop unrolling to simulate more than this number of""iterations when checking full unroll profitability"))
const APInt & getValue() const
Return the constant as an APInt value reference.
static bool HasUnrollFullPragma(const Loop *L)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static MDNode * GetUnrollMetadataForLoop(const Loop *L, StringRef Name)
void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, const Function &Fn, const DebugLoc &DLoc, const Twine &Msg)
Emit an optimization-missed message.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SCEVAddRecExpr - This node represents a polynomial recurrence on the trip count of the specified loop...
ConstantDataSequential - A vector or array constant whose element type is a simple 1/2/4/8-byte integ...
unsigned getActiveBits() const
Compute the number of active bits in the value.
AnalysisUsage & addPreservedID(const void *ID)
static cl::opt< unsigned > UnrollThreshold("unroll-threshold", cl::init(150), cl::Hidden, cl::desc("The baseline cost threshold for loop unrolling"))
Pass * createLoopUnrollPass(int Threshold=-1, int Count=-1, int AllowPartial=-1, int Runtime=-1)
void initializeLoopUnrollPass(PassRegistry &)
void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI, SmallPtrSetImpl< const Value * > &EphValues)
Add information about a block to the current state.
SCEVUnknown - This means that we are dealing with an entirely unknown SCEV value, and only represent ...
initializer< Ty > init(const Ty &Val)
bool isSCEVable(Type *Ty) const
isSCEVable - Test if values of the given type are analyzable within the SCEV framework.
static cl::opt< bool > UnrollAllowPartial("unroll-allow-partial", cl::init(false), cl::Hidden, cl::desc("Allows loops to be partially unrolled until ""-unroll-threshold loop size is reached."))
LLVM Basic Block Representation.
This is an important class for using LLVM in a threaded context.
This is an important base class in LLVM.
MDNode * getLoopID() const
Return the llvm.loop loop id metadata node for this loop if it is present.
Represent the analysis usage information of a pass.
bool contains(const LoopT *L) const
contains - Return true if the specified loop is contained within in this loop.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
static cl::opt< bool > UnrollRuntime("unroll-runtime", cl::ZeroOrMore, cl::init(false), cl::Hidden, cl::desc("Unroll loops with run-time trip counts"))
BlockT * getExitingBlock() const
getExitingBlock - If getExitingBlocks would return exactly one block, return that block...
Value * getOperand(unsigned i) const
Value * getPointerOperand()
Value * SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, const FastMathFlags &FMF, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyFPBinOp - Given operands for a BinaryOperator, see if we can fold the result.
unsigned getSmallConstantTripCount(Loop *L)
Returns the maximum trip count of the loop if it is a single-exit loop and we can compute a small max...
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
Optional< EstimatedUnrollCost > analyzeLoopUnrollCost(const Loop *L, unsigned TripCount, ScalarEvolution &SE, const TargetTransformInfo &TTI, unsigned MaxUnrolledLoopSize)
Figure out if the loop is worth full unrolling.
BinaryOps getOpcode() const
StringRef getString() const
const MDOperand & getOperand(unsigned I) const
A SetVector that performs no allocations if smaller than a certain size.
machine trace Machine Trace Metrics
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
AnalysisUsage & addRequiredID(const void *ID)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
unsigned getSmallConstantTripMultiple(Loop *L)
Returns the largest constant divisor of the trip count of the loop if it is a single-exit loop and we...
Utility to calculate the size and a few similar metrics for a set of basic blocks.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static unsigned UnrollCountPragmaValue(const Loop *L)
CHAIN = SC CHAIN, Imm128 - System call.
static cl::opt< unsigned > PragmaUnrollThreshold("pragma-unroll-threshold", cl::init(16 *1024), cl::Hidden, cl::desc("Unrolled size limit for loops with an unroll(full) or ""unroll_count pragma."))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void SetLoopAlreadyUnrolled(Loop *L)
static cl::opt< unsigned > UnrollPercentDynamicCostSavedThreshold("unroll-percent-dynamic-cost-saved-threshold", cl::init(20), cl::Hidden, cl::desc("The percentage of estimated dynamic cost which must be saved by ""unrolling to allow unrolling up to the max threshold."))
void clear()
Completely clear the SetVector.
static bool HasUnrollDisablePragma(const Loop *L)
Class for arbitrary precision integers.
Value * SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
SimplifyBinOp - Given operands for a BinaryOperator, see if we can fold the result.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
std::vector< BlockT * >::const_iterator block_iterator
MDNode * GetUnrollMetadata(MDNode *LoopID, StringRef Name)
Given an llvm.loop loop id metadata node, returns the loop hint metadata node with the given name (fo...
block_iterator block_end() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
SCEV - This class represents an analyzed expression in the program.
unsigned getNumElements() const
getNumElements - Return the number of elements in the array or vector.
Type * getElementType() const
getElementType - Return the element type of the array/vector.
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
static bool HasRuntimeUnrollDisablePragma(const Loop *L)
static unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls, bool &NotDuplicatable, const TargetTransformInfo &TTI, AssumptionCache *AC)
ApproximateLoopSize - Approximate the size of the loop.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
Pass * createSimpleLoopUnrollPass()
succ_range successors(BasicBlock *BB)
const SCEV * getSCEV(Value *V)
getSCEV - Return a SCEV expression for the full generality of the specified expression.
block_iterator block_begin() const
The legacy pass manager's analysis pass to compute loop information.
StringRef - Represent a constant reference to a string, i.e.
Legacy analysis pass which computes a DominatorTree.
static void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop)...
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
unsigned NumInsts
Number of instructions in the analyzed blocks.
bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool AllowRuntime, bool AllowExpensiveTripCount, unsigned TripMultiple, LoopInfo *LI, Pass *PP, LPPassManager *LPM, AssumptionCache *AC)
Unroll the given loop by Count.
static cl::opt< unsigned > UnrollDynamicCostSavingsDiscount("unroll-dynamic-cost-savings-discount", cl::init(2000), cl::Hidden, cl::desc("This is the amount discounted from the total unroll cost when ""the unrolled form has a high dynamic cost savings (triggered by ""the '-unroll-perecent-dynamic-cost-saved-threshold' flag)."))
SCEVConstant - This class represents a constant integer value.