Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
InductiveRangeCheckElimination.cpp
Go to the documentation of this file.
1//===- InductiveRangeCheckElimination.cpp - -------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The InductiveRangeCheckElimination pass splits a loop's iteration space into
10// three disjoint ranges. It does that in a way such that the loop running in
11// the middle loop provably does not need range checks. As an example, it will
12// convert
13//
14// len = < known positive >
15// for (i = 0; i < n; i++) {
16// if (0 <= i && i < len) {
17// do_something();
18// } else {
19// throw_out_of_bounds();
20// }
21// }
22//
23// to
24//
25// len = < known positive >
26// limit = smin(n, len)
27// // no first segment
28// for (i = 0; i < limit; i++) {
29// if (0 <= i && i < len) { // this check is fully redundant
30// do_something();
31// } else {
32// throw_out_of_bounds();
33// }
34// }
35// for (i = limit; i < n; i++) {
36// if (0 <= i && i < len) {
37// do_something();
38// } else {
39// throw_out_of_bounds();
40// }
41// }
42//
43//===----------------------------------------------------------------------===//
44
45#include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h"
46#include "llvm/ADT/APInt.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/ADT/PriorityWorklist.h"
49#include "llvm/ADT/SmallPtrSet.h"
50#include "llvm/ADT/SmallVector.h"
51#include "llvm/ADT/StringRef.h"
52#include "llvm/ADT/Twine.h"
53#include "llvm/Analysis/BlockFrequencyInfo.h"
54#include "llvm/Analysis/BranchProbabilityInfo.h"
55#include "llvm/Analysis/LoopAnalysisManager.h"
56#include "llvm/Analysis/LoopInfo.h"
57#include "llvm/Analysis/ScalarEvolution.h"
58#include "llvm/Analysis/ScalarEvolutionExpressions.h"
59#include "llvm/IR/BasicBlock.h"
60#include "llvm/IR/CFG.h"
61#include "llvm/IR/Constants.h"
62#include "llvm/IR/DerivedTypes.h"
63#include "llvm/IR/Dominators.h"
64#include "llvm/IR/Function.h"
65#include "llvm/IR/IRBuilder.h"
66#include "llvm/IR/InstrTypes.h"
67#include "llvm/IR/Instructions.h"
68#include "llvm/IR/Metadata.h"
69#include "llvm/IR/Module.h"
70#include "llvm/IR/PatternMatch.h"
71#include "llvm/IR/Type.h"
72#include "llvm/IR/Use.h"
73#include "llvm/IR/User.h"
74#include "llvm/IR/Value.h"
75#include "llvm/Support/BranchProbability.h"
76#include "llvm/Support/Casting.h"
77#include "llvm/Support/CommandLine.h"
78#include "llvm/Support/Compiler.h"
79#include "llvm/Support/Debug.h"
80#include "llvm/Support/ErrorHandling.h"
81#include "llvm/Support/raw_ostream.h"
82#include "llvm/Transforms/Utils/BasicBlockUtils.h"
83#include "llvm/Transforms/Utils/Cloning.h"
84#include "llvm/Transforms/Utils/LoopConstrainer.h"
85#include "llvm/Transforms/Utils/LoopSimplify.h"
86#include "llvm/Transforms/Utils/LoopUtils.h"
87#include "llvm/Transforms/Utils/ValueMapper.h"
88#include <algorithm>
89#include <cassert>
90#include <optional>
91#include <utility>
92
93using namespacellvm;
94using namespacellvm::PatternMatch;
95
96staticcl::opt<unsigned>LoopSizeCutoff("irce-loop-size-cutoff",cl::Hidden,
97cl::init(64));
98
99staticcl::opt<bool>PrintChangedLoops("irce-print-changed-loops",cl::Hidden,
100cl::init(false));
101
102staticcl::opt<bool>PrintRangeChecks("irce-print-range-checks",cl::Hidden,
103cl::init(false));
104
105staticcl::opt<bool>SkipProfitabilityChecks("irce-skip-profitability-checks",
106cl::Hidden,cl::init(false));
107
108staticcl::opt<unsigned>MinEliminatedChecks("irce-min-eliminated-checks",
109cl::Hidden,cl::init(10));
110
111staticcl::opt<bool>AllowUnsignedLatchCondition("irce-allow-unsigned-latch",
112cl::Hidden,cl::init(true));
113
114staticcl::opt<bool>AllowNarrowLatchCondition(
115"irce-allow-narrow-latch",cl::Hidden,cl::init(true),
116cl::desc("If set to true, IRCE may eliminate wide range checks in loops "
117"with narrow latch condition."));
118
119staticcl::opt<unsigned>MaxTypeSizeForOverflowCheck(
120"irce-max-type-size-for-overflow-check",cl::Hidden,cl::init(32),
121cl::desc(
122"Maximum size of range check type for which can be produced runtime "
123"overflow check of its limit's computation"));
124
125staticcl::opt<bool>
126PrintScaledBoundaryRangeChecks("irce-print-scaled-boundary-range-checks",
127cl::Hidden,cl::init(false));
128
129#define DEBUG_TYPE "irce"
130
131namespace{
132
133/// An inductive range check is conditional branch in a loop with a condition
134/// that is provably true for some contiguous range of values taken by the
135/// containing loop's induction variable.
136///
137classInductiveRangeCheck {
138
139constSCEV *Begin =nullptr;
140constSCEV *Step =nullptr;
141constSCEV *End =nullptr;
142Use *CheckUse =nullptr;
143
144staticbool parseRangeCheckICmp(Loop *L,ICmpInst *ICI,ScalarEvolution &SE,
145constSCEVAddRecExpr *&Index,
146constSCEV *&End);
147
148staticvoid
149 extractRangeChecksFromCond(Loop *L,ScalarEvolution &SE,Use &ConditionUse,
150SmallVectorImpl<InductiveRangeCheck> &Checks,
151SmallPtrSetImpl<Value *> &Visited);
152
153staticbool parseIvAgaisntLimit(Loop *L,Value *LHS,Value *RHS,
154ICmpInst::Predicate Pred,ScalarEvolution &SE,
155constSCEVAddRecExpr *&Index,
156constSCEV *&End);
157
158staticbool reassociateSubLHS(Loop *L,Value *VariantLHS,Value *InvariantRHS,
159ICmpInst::Predicate Pred,ScalarEvolution &SE,
160constSCEVAddRecExpr *&Index,constSCEV *&End);
161
162public:
163constSCEV *getBegin() const{return Begin; }
164constSCEV *getStep() const{return Step; }
165constSCEV *getEnd() const{returnEnd; }
166
167voidprint(raw_ostream &OS) const{
168OS <<"InductiveRangeCheck:\n";
169OS <<" Begin: ";
170 Begin->print(OS);
171OS <<" Step: ";
172 Step->print(OS);
173OS <<" End: ";
174End->print(OS);
175OS <<"\n CheckUse: ";
176 getCheckUse()->getUser()->print(OS);
177OS <<" Operand: " << getCheckUse()->getOperandNo() <<"\n";
178 }
179
180LLVM_DUMP_METHOD
181voiddump() {
182print(dbgs());
183 }
184
185Use *getCheckUse() const{return CheckUse; }
186
187 /// Represents an signed integer range [Range.getBegin(), Range.getEnd()). If
188 /// R.getEnd() le R.getBegin(), then R denotes the empty range.
189
190classRange {
191constSCEV *Begin;
192constSCEV *End;
193
194public:
195Range(constSCEV *Begin,constSCEV *End) : Begin(Begin),End(End) {
196assert(Begin->getType() ==End->getType() &&"ill-typed range!");
197 }
198
199Type *getType() const{return Begin->getType(); }
200constSCEV *getBegin() const{return Begin; }
201constSCEV *getEnd() const{returnEnd; }
202bool isEmpty(ScalarEvolution &SE,bool IsSigned) const{
203if (Begin ==End)
204returntrue;
205if (IsSigned)
206return SE.isKnownPredicate(ICmpInst::ICMP_SGE, Begin,End);
207else
208return SE.isKnownPredicate(ICmpInst::ICMP_UGE, Begin,End);
209 }
210 };
211
212 /// This is the value the condition of the branch needs to evaluate to for the
213 /// branch to take the hot successor (see (1) above).
214bool getPassingDirection() {returntrue; }
215
216 /// Computes a range for the induction variable (IndVar) in which the range
217 /// check is redundant and can be constant-folded away. The induction
218 /// variable is not required to be the canonical {0,+,1} induction variable.
219 std::optional<Range> computeSafeIterationSpace(ScalarEvolution &SE,
220constSCEVAddRecExpr *IndVar,
221bool IsLatchSigned)const;
222
223 /// Parse out a set of inductive range checks from \p BI and append them to \p
224 /// Checks.
225 ///
226 /// NB! There may be conditions feeding into \p BI that aren't inductive range
227 /// checks, and hence don't end up in \p Checks.
228staticvoid extractRangeChecksFromBranch(
229BranchInst *BI,Loop *L,ScalarEvolution &SE,BranchProbabilityInfo *BPI,
230 std::optional<uint64_t> EstimatedTripCount,
231SmallVectorImpl<InductiveRangeCheck> &Checks,bool &Changed);
232};
233
234classInductiveRangeCheckElimination {
235ScalarEvolution &SE;
236BranchProbabilityInfo *BPI;
237DominatorTree &DT;
238LoopInfo &LI;
239
240usingGetBFIFunc =
241 std::optional<llvm::function_ref<llvm::BlockFrequencyInfo &()>>;
242 GetBFIFunc GetBFI;
243
244// Returns the estimated number of iterations based on block frequency info if
245// available, or on branch probability info. Nullopt is returned if the number
246// of iterations cannot be estimated.
247 std::optional<uint64_t> estimatedTripCount(constLoop &L);
248
249public:
250 InductiveRangeCheckElimination(ScalarEvolution &SE,
251BranchProbabilityInfo *BPI,DominatorTree &DT,
252LoopInfo &LI, GetBFIFunc GetBFI = std::nullopt)
253 : SE(SE), BPI(BPI), DT(DT), LI(LI), GetBFI(GetBFI) {}
254
255bool run(Loop *L,function_ref<void(Loop *,bool)> LPMAddNewLoop);
256};
257
258}// end anonymous namespace
259
260/// Parse a single ICmp instruction, `ICI`, into a range check. If `ICI` cannot
261/// be interpreted as a range check, return false. Otherwise set `Index` to the
262/// SCEV being range checked, and set `End` to the upper or lower limit `Index`
263/// is being range checked.
264bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L,ICmpInst *ICI,
265ScalarEvolution &SE,
266constSCEVAddRecExpr *&Index,
267constSCEV *&End) {
268auto IsLoopInvariant = [&SE,L](Value *V) {
269return SE.isLoopInvariant(SE.getSCEV(V),L);
270 };
271
272ICmpInst::Predicate Pred = ICI->getPredicate();
273Value *LHS = ICI->getOperand(0);
274Value *RHS = ICI->getOperand(1);
275
276if (!LHS->getType()->isIntegerTy())
277returnfalse;
278
279// Canonicalize to the `Index Pred Invariant` comparison
280if (IsLoopInvariant(LHS)) {
281std::swap(LHS, RHS);
282 Pred =CmpInst::getSwappedPredicate(Pred);
283 }elseif (!IsLoopInvariant(RHS))
284// Both LHS and RHS are loop variant
285returnfalse;
286
287if (parseIvAgaisntLimit(L, LHS, RHS, Pred, SE, Index,End))
288returntrue;
289
290if (reassociateSubLHS(L, LHS, RHS, Pred, SE, Index,End))
291returntrue;
292
293// TODO: support ReassociateAddLHS
294returnfalse;
295}
296
297// Try to parse range check in the form of "IV vs Limit"
298bool InductiveRangeCheck::parseIvAgaisntLimit(Loop *L,Value *LHS,Value *RHS,
299ICmpInst::Predicate Pred,
300ScalarEvolution &SE,
301constSCEVAddRecExpr *&Index,
302constSCEV *&End) {
303
304auto SIntMaxSCEV = [&](Type *T) {
305unsignedBitWidth = cast<IntegerType>(T)->getBitWidth();
306return SE.getConstant(APInt::getSignedMaxValue(BitWidth));
307 };
308
309constauto *AddRec = dyn_cast<SCEVAddRecExpr>(SE.getSCEV(LHS));
310if (!AddRec)
311returnfalse;
312
313// We strengthen "0 <= I" to "0 <= I < INT_SMAX" and "I < L" to "0 <= I < L".
314// We can potentially do much better here.
315// If we want to adjust upper bound for the unsigned range check as we do it
316// for signed one, we will need to pick Unsigned max
317switch (Pred) {
318default:
319returnfalse;
320
321case ICmpInst::ICMP_SGE:
322if (match(RHS, m_ConstantInt<0>())) {
323Index = AddRec;
324End = SIntMaxSCEV(Index->getType());
325returntrue;
326 }
327returnfalse;
328
329case ICmpInst::ICMP_SGT:
330if (match(RHS, m_ConstantInt<-1>())) {
331Index = AddRec;
332End = SIntMaxSCEV(Index->getType());
333returntrue;
334 }
335returnfalse;
336
337case ICmpInst::ICMP_SLT:
338case ICmpInst::ICMP_ULT:
339Index = AddRec;
340End = SE.getSCEV(RHS);
341returntrue;
342
343case ICmpInst::ICMP_SLE:
344case ICmpInst::ICMP_ULE:
345constSCEV *One = SE.getOne(RHS->getType());
346constSCEV *RHSS = SE.getSCEV(RHS);
347boolSigned = Pred == ICmpInst::ICMP_SLE;
348if (SE.willNotOverflow(Instruction::BinaryOps::Add,Signed, RHSS, One)) {
349Index = AddRec;
350End = SE.getAddExpr(RHSS, One);
351returntrue;
352 }
353returnfalse;
354 }
355
356llvm_unreachable("default clause returns!");
357}
358
359// Try to parse range check in the form of "IV - Offset vs Limit" or "Offset -
360// IV vs Limit"
361bool InductiveRangeCheck::reassociateSubLHS(
362Loop *L,Value *VariantLHS,Value *InvariantRHS,ICmpInst::Predicate Pred,
363ScalarEvolution &SE,constSCEVAddRecExpr *&Index,constSCEV *&End) {
364Value *LHS, *RHS;
365if (!match(VariantLHS,m_Sub(m_Value(LHS),m_Value(RHS))))
366returnfalse;
367
368constSCEV *IV = SE.getSCEV(LHS);
369constSCEV *Offset = SE.getSCEV(RHS);
370constSCEV *Limit = SE.getSCEV(InvariantRHS);
371
372bool OffsetSubtracted =false;
373if (SE.isLoopInvariant(IV, L))
374// "Offset - IV vs Limit"
375std::swap(IV,Offset);
376elseif (SE.isLoopInvariant(Offset, L))
377// "IV - Offset vs Limit"
378 OffsetSubtracted =true;
379else
380returnfalse;
381
382constauto *AddRec = dyn_cast<SCEVAddRecExpr>(IV);
383if (!AddRec)
384returnfalse;
385
386// In order to turn "IV - Offset < Limit" into "IV < Limit + Offset", we need
387// to be able to freely move values from left side of inequality to right side
388// (just as in normal linear arithmetics). Overflows make things much more
389// complicated, so we want to avoid this.
390//
391// Let's prove that the initial subtraction doesn't overflow with all IV's
392// values from the safe range constructed for that check.
393//
394// [Case 1] IV - Offset < Limit
395// It doesn't overflow if:
396// SINT_MIN <= IV - Offset <= SINT_MAX
397// In terms of scaled SINT we need to prove:
398// SINT_MIN + Offset <= IV <= SINT_MAX + Offset
399// Safe range will be constructed:
400// 0 <= IV < Limit + Offset
401// It means that 'IV - Offset' doesn't underflow, because:
402// SINT_MIN + Offset < 0 <= IV
403// and doesn't overflow:
404// IV < Limit + Offset <= SINT_MAX + Offset
405//
406// [Case 2] Offset - IV > Limit
407// It doesn't overflow if:
408// SINT_MIN <= Offset - IV <= SINT_MAX
409// In terms of scaled SINT we need to prove:
410// -SINT_MIN >= IV - Offset >= -SINT_MAX
411// Offset - SINT_MIN >= IV >= Offset - SINT_MAX
412// Safe range will be constructed:
413// 0 <= IV < Offset - Limit
414// It means that 'Offset - IV' doesn't underflow, because
415// Offset - SINT_MAX < 0 <= IV
416// and doesn't overflow:
417// IV < Offset - Limit <= Offset - SINT_MIN
418//
419// For the computed upper boundary of the IV's range (Offset +/- Limit) we
420// don't know exactly whether it overflows or not. So if we can't prove this
421// fact at compile time, we scale boundary computations to a wider type with
422// the intention to add runtime overflow check.
423
424auto getExprScaledIfOverflow = [&](Instruction::BinaryOps BinOp,
425constSCEV *LHS,
426constSCEV *RHS) ->constSCEV * {
427constSCEV *(ScalarEvolution::*Operation)(constSCEV *,constSCEV *,
428SCEV::NoWrapFlags,unsigned);
429switch (BinOp) {
430default:
431llvm_unreachable("Unsupported binary op");
432case Instruction::Add:
433Operation = &ScalarEvolution::getAddExpr;
434break;
435case Instruction::Sub:
436Operation = &ScalarEvolution::getMinusSCEV;
437break;
438 }
439
440if (SE.willNotOverflow(BinOp, ICmpInst::isSigned(Pred), LHS, RHS,
441 cast<Instruction>(VariantLHS)))
442return (SE.*Operation)(LHS,RHS,SCEV::FlagAnyWrap, 0);
443
444// We couldn't prove that the expression does not overflow.
445// Than scale it to a wider type to check overflow at runtime.
446auto *Ty = cast<IntegerType>(LHS->getType());
447if (Ty->getBitWidth() >MaxTypeSizeForOverflowCheck)
448returnnullptr;
449
450auto WideTy =IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2);
451return (SE.*Operation)(SE.getSignExtendExpr(LHS, WideTy),
452 SE.getSignExtendExpr(RHS, WideTy),SCEV::FlagAnyWrap,
453 0);
454 };
455
456if (OffsetSubtracted)
457// "IV - Offset < Limit" -> "IV" < Offset + Limit
458 Limit = getExprScaledIfOverflow(Instruction::BinaryOps::Add,Offset, Limit);
459else {
460// "Offset - IV > Limit" -> "IV" < Offset - Limit
461 Limit = getExprScaledIfOverflow(Instruction::BinaryOps::Sub,Offset, Limit);
462 Pred = ICmpInst::getSwappedPredicate(Pred);
463 }
464
465if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SLE) {
466// "Expr <= Limit" -> "Expr < Limit + 1"
467if (Pred == ICmpInst::ICMP_SLE && Limit)
468 Limit = getExprScaledIfOverflow(Instruction::BinaryOps::Add, Limit,
469 SE.getOne(Limit->getType()));
470if (Limit) {
471Index = AddRec;
472End = Limit;
473returntrue;
474 }
475 }
476returnfalse;
477}
478
479void InductiveRangeCheck::extractRangeChecksFromCond(
480Loop *L,ScalarEvolution &SE,Use &ConditionUse,
481SmallVectorImpl<InductiveRangeCheck> &Checks,
482SmallPtrSetImpl<Value *> &Visited) {
483Value *Condition = ConditionUse.get();
484if (!Visited.insert(Condition).second)
485return;
486
487// TODO: Do the same for OR, XOR, NOT etc?
488if (match(Condition,m_LogicalAnd(m_Value(),m_Value()))) {
489 extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(0),
490 Checks, Visited);
491 extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(1),
492 Checks, Visited);
493return;
494 }
495
496ICmpInst *ICI = dyn_cast<ICmpInst>(Condition);
497if (!ICI)
498return;
499
500constSCEV *End =nullptr;
501constSCEVAddRecExpr *IndexAddRec =nullptr;
502if (!parseRangeCheckICmp(L, ICI, SE, IndexAddRec,End))
503return;
504
505assert(IndexAddRec &&"IndexAddRec was not computed");
506assert(End &&"End was not computed");
507
508if ((IndexAddRec->getLoop() != L) || !IndexAddRec->isAffine())
509return;
510
511 InductiveRangeCheck IRC;
512 IRC.End =End;
513 IRC.Begin = IndexAddRec->getStart();
514 IRC.Step = IndexAddRec->getStepRecurrence(SE);
515 IRC.CheckUse = &ConditionUse;
516 Checks.push_back(IRC);
517}
518
519void InductiveRangeCheck::extractRangeChecksFromBranch(
520BranchInst *BI,Loop *L,ScalarEvolution &SE,BranchProbabilityInfo *BPI,
521 std::optional<uint64_t> EstimatedTripCount,
522SmallVectorImpl<InductiveRangeCheck> &Checks,bool &Changed) {
523if (BI->isUnconditional() || BI->getParent() ==L->getLoopLatch())
524return;
525
526unsigned IndexLoopSucc =L->contains(BI->getSuccessor(0)) ? 0 : 1;
527assert(L->contains(BI->getSuccessor(IndexLoopSucc)) &&
528"No edges coming to loop?");
529
530if (!SkipProfitabilityChecks && BPI) {
531auto SuccessProbability =
532 BPI->getEdgeProbability(BI->getParent(), IndexLoopSucc);
533if (EstimatedTripCount) {
534auto EstimatedEliminatedChecks =
535 SuccessProbability.scale(*EstimatedTripCount);
536if (EstimatedEliminatedChecks <MinEliminatedChecks) {
537LLVM_DEBUG(dbgs() <<"irce: could not prove profitability for branch "
538 << *BI <<": "
539 <<"estimated eliminated checks too low "
540 << EstimatedEliminatedChecks <<"\n";);
541return;
542 }
543 }else {
544BranchProbability LikelyTaken(15, 16);
545if (SuccessProbability < LikelyTaken) {
546LLVM_DEBUG(dbgs() <<"irce: could not prove profitability for branch "
547 << *BI <<": "
548 <<"could not estimate trip count "
549 <<"and branch success probability too low "
550 << SuccessProbability <<"\n";);
551return;
552 }
553 }
554 }
555
556// IRCE expects branch's true edge comes to loop. Invert branch for opposite
557// case.
558if (IndexLoopSucc != 0) {
559IRBuilder<> Builder(BI);
560InvertBranch(BI, Builder);
561if (BPI)
562 BPI->swapSuccEdgesProbabilities(BI->getParent());
563 Changed =true;
564 }
565
566SmallPtrSet<Value *, 8> Visited;
567 InductiveRangeCheck::extractRangeChecksFromCond(L, SE, BI->getOperandUse(0),
568 Checks, Visited);
569}
570
571/// If the type of \p S matches with \p Ty, return \p S. Otherwise, return
572/// signed or unsigned extension of \p S to type \p Ty.
573staticconstSCEV *NoopOrExtend(constSCEV *S,Type *Ty,ScalarEvolution &SE,
574boolSigned) {
575returnSigned ? SE.getNoopOrSignExtend(S, Ty) : SE.getNoopOrZeroExtend(S, Ty);
576}
577
578// Compute a safe set of limits for the main loop to run in -- effectively the
579// intersection of `Range' and the iteration space of the original loop.
580// Return std::nullopt if unable to compute the set of subranges.
581static std::optional<LoopConstrainer::SubRanges>
582calculateSubRanges(ScalarEvolution &SE,constLoop &L,
583 InductiveRangeCheck::Range &Range,
584constLoopStructure &MainLoopStructure) {
585auto *RTy = cast<IntegerType>(Range.getType());
586// We only support wide range checks and narrow latches.
587if (!AllowNarrowLatchCondition && RTy != MainLoopStructure.ExitCountTy)
588return std::nullopt;
589if (RTy->getBitWidth() < MainLoopStructure.ExitCountTy->getBitWidth())
590return std::nullopt;
591
592LoopConstrainer::SubRanges Result;
593
594bool IsSignedPredicate = MainLoopStructure.IsSignedPredicate;
595// I think we can be more aggressive here and make this nuw / nsw if the
596// addition that feeds into the icmp for the latch's terminating branch is nuw
597// / nsw. In any case, a wrapping 2's complement addition is safe.
598constSCEV *Start =NoopOrExtend(SE.getSCEV(MainLoopStructure.IndVarStart),
599 RTy, SE, IsSignedPredicate);
600constSCEV *End =NoopOrExtend(SE.getSCEV(MainLoopStructure.LoopExitAt), RTy,
601 SE, IsSignedPredicate);
602
603bool Increasing = MainLoopStructure.IndVarIncreasing;
604
605// We compute `Smallest` and `Greatest` such that [Smallest, Greatest), or
606// [Smallest, GreatestSeen] is the range of values the induction variable
607// takes.
608
609constSCEV *Smallest =nullptr, *Greatest =nullptr, *GreatestSeen =nullptr;
610
611constSCEV *One = SE.getOne(RTy);
612if (Increasing) {
613 Smallest = Start;
614 Greatest =End;
615// No overflow, because the range [Smallest, GreatestSeen] is not empty.
616 GreatestSeen = SE.getMinusSCEV(End, One);
617 }else {
618// These two computations may sign-overflow. Here is why that is okay:
619//
620// We know that the induction variable does not sign-overflow on any
621// iteration except the last one, and it starts at `Start` and ends at
622// `End`, decrementing by one every time.
623//
624// * if `Smallest` sign-overflows we know `End` is `INT_SMAX`. Since the
625// induction variable is decreasing we know that the smallest value
626// the loop body is actually executed with is `INT_SMIN` == `Smallest`.
627//
628// * if `Greatest` sign-overflows, we know it can only be `INT_SMIN`. In
629// that case, `Clamp` will always return `Smallest` and
630// [`Result.LowLimit`, `Result.HighLimit`) = [`Smallest`, `Smallest`)
631// will be an empty range. Returning an empty range is always safe.
632
633 Smallest = SE.getAddExpr(End, One);
634 Greatest = SE.getAddExpr(Start, One);
635 GreatestSeen = Start;
636 }
637
638auto Clamp = [&SE, Smallest, Greatest, IsSignedPredicate](constSCEV *S) {
639return IsSignedPredicate
640 ? SE.getSMaxExpr(Smallest, SE.getSMinExpr(Greatest, S))
641 : SE.getUMaxExpr(Smallest, SE.getUMinExpr(Greatest, S));
642 };
643
644// In some cases we can prove that we don't need a pre or post loop.
645ICmpInst::Predicate PredLE =
646 IsSignedPredicate ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
647ICmpInst::Predicate PredLT =
648 IsSignedPredicate ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
649
650bool ProvablyNoPreloop =
651 SE.isKnownPredicate(PredLE,Range.getBegin(), Smallest);
652if (!ProvablyNoPreloop)
653 Result.LowLimit = Clamp(Range.getBegin());
654
655bool ProvablyNoPostLoop =
656 SE.isKnownPredicate(PredLT, GreatestSeen,Range.getEnd());
657if (!ProvablyNoPostLoop)
658 Result.HighLimit = Clamp(Range.getEnd());
659
660return Result;
661}
662
663/// Computes and returns a range of values for the induction variable (IndVar)
664/// in which the range check can be safely elided. If it cannot compute such a
665/// range, returns std::nullopt.
666std::optional<InductiveRangeCheck::Range>
667InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE,
668constSCEVAddRecExpr *IndVar,
669bool IsLatchSigned) const{
670// We can deal when types of latch check and range checks don't match in case
671// if latch check is more narrow.
672auto *IVType = dyn_cast<IntegerType>(IndVar->getType());
673auto *RCType = dyn_cast<IntegerType>(getBegin()->getType());
674auto *EndType = dyn_cast<IntegerType>(getEnd()->getType());
675// Do not work with pointer types.
676if (!IVType || !RCType)
677return std::nullopt;
678if (IVType->getBitWidth() > RCType->getBitWidth())
679return std::nullopt;
680
681// IndVar is of the form "A + B * I" (where "I" is the canonical induction
682// variable, that may or may not exist as a real llvm::Value in the loop) and
683// this inductive range check is a range check on the "C + D * I" ("C" is
684// getBegin() and "D" is getStep()). We rewrite the value being range
685// checked to "M + N * IndVar" where "N" = "D * B^(-1)" and "M" = "C - NA".
686//
687// The actual inequalities we solve are of the form
688//
689// 0 <= M + 1 * IndVar < L given L >= 0 (i.e. N == 1)
690//
691// Here L stands for upper limit of the safe iteration space.
692// The inequality is satisfied by (0 - M) <= IndVar < (L - M). To avoid
693// overflows when calculating (0 - M) and (L - M) we, depending on type of
694// IV's iteration space, limit the calculations by borders of the iteration
695// space. For example, if IndVar is unsigned, (0 - M) overflows for any M > 0.
696// If we figured out that "anything greater than (-M) is safe", we strengthen
697// this to "everything greater than 0 is safe", assuming that values between
698// -M and 0 just do not exist in unsigned iteration space, and we don't want
699// to deal with overflown values.
700
701if (!IndVar->isAffine())
702return std::nullopt;
703
704constSCEV *A =NoopOrExtend(IndVar->getStart(), RCType, SE, IsLatchSigned);
705constSCEVConstant *B = dyn_cast<SCEVConstant>(
706NoopOrExtend(IndVar->getStepRecurrence(SE), RCType, SE, IsLatchSigned));
707if (!B)
708return std::nullopt;
709assert(!B->isZero() &&"Recurrence with zero step?");
710
711constSCEV *C = getBegin();
712constSCEVConstant *D = dyn_cast<SCEVConstant>(getStep());
713if (D !=B)
714return std::nullopt;
715
716assert(!D->getValue()->isZero() &&"Recurrence with zero step?");
717unsignedBitWidth = RCType->getBitWidth();
718constSCEV *SIntMax = SE.getConstant(APInt::getSignedMaxValue(BitWidth));
719constSCEV *SIntMin = SE.getConstant(APInt::getSignedMinValue(BitWidth));
720
721// Subtract Y from X so that it does not go through border of the IV
722// iteration space. Mathematically, it is equivalent to:
723//
724// ClampedSubtract(X, Y) = min(max(X - Y, INT_MIN), INT_MAX). [1]
725//
726// In [1], 'X - Y' is a mathematical subtraction (result is not bounded to
727// any width of bit grid). But after we take min/max, the result is
728// guaranteed to be within [INT_MIN, INT_MAX].
729//
730// In [1], INT_MAX and INT_MIN are respectively signed and unsigned max/min
731// values, depending on type of latch condition that defines IV iteration
732// space.
733auto ClampedSubtract = [&](constSCEV *X,constSCEV *Y) {
734// FIXME: The current implementation assumes that X is in [0, SINT_MAX].
735// This is required to ensure that SINT_MAX - X does not overflow signed and
736// that X - Y does not overflow unsigned if Y is negative. Can we lift this
737// restriction and make it work for negative X either?
738if (IsLatchSigned) {
739// X is a number from signed range, Y is interpreted as signed.
740// Even if Y is SINT_MAX, (X - Y) does not reach SINT_MIN. So the only
741// thing we should care about is that we didn't cross SINT_MAX.
742// So, if Y is positive, we subtract Y safely.
743// Rule 1: Y > 0 ---> Y.
744// If 0 <= -Y <= (SINT_MAX - X), we subtract Y safely.
745// Rule 2: Y >=s (X - SINT_MAX) ---> Y.
746// If 0 <= (SINT_MAX - X) < -Y, we can only subtract (X - SINT_MAX).
747// Rule 3: Y <s (X - SINT_MAX) ---> (X - SINT_MAX).
748// It gives us smax(Y, X - SINT_MAX) to subtract in all cases.
749constSCEV *XMinusSIntMax = SE.getMinusSCEV(X, SIntMax);
750return SE.getMinusSCEV(X, SE.getSMaxExpr(Y, XMinusSIntMax),
751SCEV::FlagNSW);
752 }else
753// X is a number from unsigned range, Y is interpreted as signed.
754// Even if Y is SINT_MIN, (X - Y) does not reach UINT_MAX. So the only
755// thing we should care about is that we didn't cross zero.
756// So, if Y is negative, we subtract Y safely.
757// Rule 1: Y <s 0 ---> Y.
758// If 0 <= Y <= X, we subtract Y safely.
759// Rule 2: Y <=s X ---> Y.
760// If 0 <= X < Y, we should stop at 0 and can only subtract X.
761// Rule 3: Y >s X ---> X.
762// It gives us smin(X, Y) to subtract in all cases.
763return SE.getMinusSCEV(X, SE.getSMinExpr(X,Y),SCEV::FlagNUW);
764 };
765constSCEV *M = SE.getMinusSCEV(C,A);
766constSCEV *Zero = SE.getZero(M->getType());
767
768// This function returns SCEV equal to 1 if X is non-negative 0 otherwise.
769auto SCEVCheckNonNegative = [&](constSCEV *X) {
770constLoop *L = IndVar->getLoop();
771constSCEV *Zero = SE.getZero(X->getType());
772constSCEV *One = SE.getOne(X->getType());
773// Can we trivially prove that X is a non-negative or negative value?
774if (isKnownNonNegativeInLoop(X, L, SE))
775return One;
776elseif (isKnownNegativeInLoop(X, L, SE))
777return Zero;
778// If not, we will have to figure it out during the execution.
779// Function smax(smin(X, 0), -1) + 1 equals to 1 if X >= 0 and 0 if X < 0.
780constSCEV *NegOne = SE.getNegativeSCEV(One);
781return SE.getAddExpr(SE.getSMaxExpr(SE.getSMinExpr(X, Zero), NegOne), One);
782 };
783
784// This function returns SCEV equal to 1 if X will not overflow in terms of
785// range check type, 0 otherwise.
786auto SCEVCheckWillNotOverflow = [&](constSCEV *X) {
787// X doesn't overflow if SINT_MAX >= X.
788// Then if (SINT_MAX - X) >= 0, X doesn't overflow
789constSCEV *SIntMaxExt = SE.getSignExtendExpr(SIntMax,X->getType());
790constSCEV *OverflowCheck =
791 SCEVCheckNonNegative(SE.getMinusSCEV(SIntMaxExt,X));
792
793// X doesn't underflow if X >= SINT_MIN.
794// Then if (X - SINT_MIN) >= 0, X doesn't underflow
795constSCEV *SIntMinExt = SE.getSignExtendExpr(SIntMin,X->getType());
796constSCEV *UnderflowCheck =
797 SCEVCheckNonNegative(SE.getMinusSCEV(X, SIntMinExt));
798
799return SE.getMulExpr(OverflowCheck, UnderflowCheck);
800 };
801
802// FIXME: Current implementation of ClampedSubtract implicitly assumes that
803// X is non-negative (in sense of a signed value). We need to re-implement
804// this function in a way that it will correctly handle negative X as well.
805// We use it twice: for X = 0 everything is fine, but for X = getEnd() we can
806// end up with a negative X and produce wrong results. So currently we ensure
807// that if getEnd() is negative then both ends of the safe range are zero.
808// Note that this may pessimize elimination of unsigned range checks against
809// negative values.
810constSCEV *REnd = getEnd();
811constSCEV *EndWillNotOverflow = SE.getOne(RCType);
812
813auto PrintRangeCheck = [&](raw_ostream &OS) {
814autoL = IndVar->getLoop();
815OS <<"irce: in function ";
816OS <<L->getHeader()->getParent()->getName();
817OS <<", in ";
818L->print(OS);
819OS <<"there is range check with scaled boundary:\n";
820print(OS);
821 };
822
823if (EndType->getBitWidth() > RCType->getBitWidth()) {
824assert(EndType->getBitWidth() == RCType->getBitWidth() * 2);
825if (PrintScaledBoundaryRangeChecks)
826 PrintRangeCheck(errs());
827// End is computed with extended type but will be truncated to a narrow one
828// type of range check. Therefore we need a check that the result will not
829// overflow in terms of narrow type.
830 EndWillNotOverflow =
831 SE.getTruncateExpr(SCEVCheckWillNotOverflow(REnd), RCType);
832 REnd = SE.getTruncateExpr(REnd, RCType);
833 }
834
835constSCEV *RuntimeChecks =
836 SE.getMulExpr(SCEVCheckNonNegative(REnd), EndWillNotOverflow);
837constSCEV *Begin = SE.getMulExpr(ClampedSubtract(Zero, M), RuntimeChecks);
838constSCEV *End = SE.getMulExpr(ClampedSubtract(REnd, M), RuntimeChecks);
839
840return InductiveRangeCheck::Range(Begin,End);
841}
842
843static std::optional<InductiveRangeCheck::Range>
844IntersectSignedRange(ScalarEvolution &SE,
845const std::optional<InductiveRangeCheck::Range> &R1,
846const InductiveRangeCheck::Range &R2) {
847if (R2.isEmpty(SE,/* IsSigned */true))
848return std::nullopt;
849if (!R1)
850returnR2;
851auto &R1Value = *R1;
852// We never return empty ranges from this function, and R1 is supposed to be
853// a result of intersection. Thus, R1 is never empty.
854assert(!R1Value.isEmpty(SE,/* IsSigned */true) &&
855"We should never have empty R1!");
856
857// TODO: we could widen the smaller range and have this work; but for now we
858// bail out to keep things simple.
859if (R1Value.getType() !=R2.getType())
860return std::nullopt;
861
862constSCEV *NewBegin = SE.getSMaxExpr(R1Value.getBegin(),R2.getBegin());
863constSCEV *NewEnd = SE.getSMinExpr(R1Value.getEnd(),R2.getEnd());
864
865// If the resulting range is empty, just return std::nullopt.
866auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
867if (Ret.isEmpty(SE,/* IsSigned */true))
868return std::nullopt;
869return Ret;
870}
871
872static std::optional<InductiveRangeCheck::Range>
873IntersectUnsignedRange(ScalarEvolution &SE,
874const std::optional<InductiveRangeCheck::Range> &R1,
875const InductiveRangeCheck::Range &R2) {
876if (R2.isEmpty(SE,/* IsSigned */false))
877return std::nullopt;
878if (!R1)
879returnR2;
880auto &R1Value = *R1;
881// We never return empty ranges from this function, and R1 is supposed to be
882// a result of intersection. Thus, R1 is never empty.
883assert(!R1Value.isEmpty(SE,/* IsSigned */false) &&
884"We should never have empty R1!");
885
886// TODO: we could widen the smaller range and have this work; but for now we
887// bail out to keep things simple.
888if (R1Value.getType() !=R2.getType())
889return std::nullopt;
890
891constSCEV *NewBegin = SE.getUMaxExpr(R1Value.getBegin(),R2.getBegin());
892constSCEV *NewEnd = SE.getUMinExpr(R1Value.getEnd(),R2.getEnd());
893
894// If the resulting range is empty, just return std::nullopt.
895auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
896if (Ret.isEmpty(SE,/* IsSigned */false))
897return std::nullopt;
898return Ret;
899}
900
901PreservedAnalysesIRCEPass::run(Function &F,FunctionAnalysisManager &AM) {
902auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
903LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
904// There are no loops in the function. Return before computing other expensive
905// analyses.
906if (LI.empty())
907returnPreservedAnalyses::all();
908auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
909auto &BPI = AM.getResult<BranchProbabilityAnalysis>(F);
910
911// Get BFI analysis result on demand. Please note that modification of
912// CFG invalidates this analysis and we should handle it.
913auto getBFI = [&F, &AM ]()->BlockFrequencyInfo & {
914return AM.getResult<BlockFrequencyAnalysis>(F);
915 };
916 InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI, { getBFI });
917
918bool Changed =false;
919 {
920bool CFGChanged =false;
921for (constauto &L : LI) {
922 CFGChanged |=simplifyLoop(L, &DT, &LI, &SE,nullptr,nullptr,
923/*PreserveLCSSA=*/false);
924 Changed |=formLCSSARecursively(*L, DT, &LI, &SE);
925 }
926 Changed |= CFGChanged;
927
928if (CFGChanged && !SkipProfitabilityChecks) {
929PreservedAnalyses PA =PreservedAnalyses::all();
930 PA.abandon<BlockFrequencyAnalysis>();
931 AM.invalidate(F, PA);
932 }
933 }
934
935SmallPriorityWorklist<Loop *, 4> Worklist;
936appendLoopsToWorklist(LI, Worklist);
937auto LPMAddNewLoop = [&Worklist](Loop *NL,bool IsSubloop) {
938if (!IsSubloop)
939appendLoopsToWorklist(*NL, Worklist);
940 };
941
942while (!Worklist.empty()) {
943Loop *L = Worklist.pop_back_val();
944if (IRCE.run(L, LPMAddNewLoop)) {
945 Changed =true;
946if (!SkipProfitabilityChecks) {
947PreservedAnalyses PA =PreservedAnalyses::all();
948 PA.abandon<BlockFrequencyAnalysis>();
949 AM.invalidate(F, PA);
950 }
951 }
952 }
953
954if (!Changed)
955returnPreservedAnalyses::all();
956returngetLoopPassPreservedAnalyses();
957}
958
959std::optional<uint64_t>
960InductiveRangeCheckElimination::estimatedTripCount(constLoop &L) {
961if (GetBFI) {
962BlockFrequencyInfo &BFI = (*GetBFI)();
963uint64_t hFreq = BFI.getBlockFreq(L.getHeader()).getFrequency();
964uint64_t phFreq = BFI.getBlockFreq(L.getLoopPreheader()).getFrequency();
965if (phFreq == 0 || hFreq == 0)
966return std::nullopt;
967return {hFreq / phFreq};
968 }
969
970if (!BPI)
971return std::nullopt;
972
973auto *Latch =L.getLoopLatch();
974if (!Latch)
975return std::nullopt;
976auto *LatchBr = dyn_cast<BranchInst>(Latch->getTerminator());
977if (!LatchBr)
978return std::nullopt;
979
980auto LatchBrExitIdx = LatchBr->getSuccessor(0) ==L.getHeader() ? 1 : 0;
981BranchProbability ExitProbability =
982 BPI->getEdgeProbability(Latch, LatchBrExitIdx);
983if (ExitProbability.isUnknown() || ExitProbability.isZero())
984return std::nullopt;
985
986return {ExitProbability.scaleByInverse(1)};
987}
988
989bool InductiveRangeCheckElimination::run(
990Loop *L,function_ref<void(Loop *,bool)> LPMAddNewLoop) {
991if (L->getBlocks().size() >=LoopSizeCutoff) {
992LLVM_DEBUG(dbgs() <<"irce: giving up constraining loop, too large\n");
993returnfalse;
994 }
995
996BasicBlock *Preheader =L->getLoopPreheader();
997if (!Preheader) {
998LLVM_DEBUG(dbgs() <<"irce: loop has no preheader, leaving\n");
999returnfalse;
1000 }
1001
1002auto EstimatedTripCount = estimatedTripCount(*L);
1003if (!SkipProfitabilityChecks && EstimatedTripCount &&
1004 *EstimatedTripCount <MinEliminatedChecks) {
1005LLVM_DEBUG(dbgs() <<"irce: could not prove profitability: "
1006 <<"the estimated number of iterations is "
1007 << *EstimatedTripCount <<"\n");
1008returnfalse;
1009 }
1010
1011LLVMContext &Context = Preheader->getContext();
1012SmallVector<InductiveRangeCheck, 16> RangeChecks;
1013bool Changed =false;
1014
1015for (auto *BBI :L->getBlocks())
1016if (BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
1017 InductiveRangeCheck::extractRangeChecksFromBranch(
1018 TBI, L, SE, BPI, EstimatedTripCount, RangeChecks, Changed);
1019
1020if (RangeChecks.empty())
1021return Changed;
1022
1023auto PrintRecognizedRangeChecks = [&](raw_ostream &OS) {
1024OS <<"irce: looking at loop ";L->print(OS);
1025OS <<"irce: loop has " << RangeChecks.size()
1026 <<" inductive range checks: \n";
1027for (InductiveRangeCheck &IRC : RangeChecks)
1028 IRC.print(OS);
1029 };
1030
1031LLVM_DEBUG(PrintRecognizedRangeChecks(dbgs()));
1032
1033if (PrintRangeChecks)
1034 PrintRecognizedRangeChecks(errs());
1035
1036constchar *FailureReason =nullptr;
1037 std::optional<LoopStructure> MaybeLoopStructure =
1038LoopStructure::parseLoopStructure(SE, *L,AllowUnsignedLatchCondition,
1039 FailureReason);
1040if (!MaybeLoopStructure) {
1041LLVM_DEBUG(dbgs() <<"irce: could not parse loop structure: "
1042 << FailureReason <<"\n";);
1043return Changed;
1044 }
1045LoopStructureLS = *MaybeLoopStructure;
1046constSCEVAddRecExpr *IndVar =
1047 cast<SCEVAddRecExpr>(SE.getMinusSCEV(SE.getSCEV(LS.IndVarBase), SE.getSCEV(LS.IndVarStep)));
1048
1049 std::optional<InductiveRangeCheck::Range> SafeIterRange;
1050
1051SmallVector<InductiveRangeCheck, 4> RangeChecksToEliminate;
1052// Basing on the type of latch predicate, we interpret the IV iteration range
1053// as signed or unsigned range. We use different min/max functions (signed or
1054// unsigned) when intersecting this range with safe iteration ranges implied
1055// by range checks.
1056auto IntersectRange =
1057LS.IsSignedPredicate ?IntersectSignedRange :IntersectUnsignedRange;
1058
1059for (InductiveRangeCheck &IRC : RangeChecks) {
1060autoResult = IRC.computeSafeIterationSpace(SE, IndVar,
1061LS.IsSignedPredicate);
1062if (Result) {
1063auto MaybeSafeIterRange = IntersectRange(SE, SafeIterRange, *Result);
1064if (MaybeSafeIterRange) {
1065assert(!MaybeSafeIterRange->isEmpty(SE,LS.IsSignedPredicate) &&
1066"We should never return empty ranges!");
1067 RangeChecksToEliminate.push_back(IRC);
1068 SafeIterRange = *MaybeSafeIterRange;
1069 }
1070 }
1071 }
1072
1073if (!SafeIterRange)
1074return Changed;
1075
1076 std::optional<LoopConstrainer::SubRanges> MaybeSR =
1077calculateSubRanges(SE, *L, *SafeIterRange, LS);
1078if (!MaybeSR) {
1079LLVM_DEBUG(dbgs() <<"irce: could not compute subranges\n");
1080returnfalse;
1081 }
1082
1083LoopConstrainer LC(*L, LI, LPMAddNewLoop, LS, SE, DT,
1084 SafeIterRange->getBegin()->getType(), *MaybeSR);
1085
1086if (LC.run()) {
1087 Changed =true;
1088
1089auto PrintConstrainedLoopInfo = [L]() {
1090dbgs() <<"irce: in function ";
1091dbgs() <<L->getHeader()->getParent()->getName() <<": ";
1092dbgs() <<"constrained ";
1093L->print(dbgs());
1094 };
1095
1096LLVM_DEBUG(PrintConstrainedLoopInfo());
1097
1098if (PrintChangedLoops)
1099 PrintConstrainedLoopInfo();
1100
1101// Optimize away the now-redundant range checks.
1102
1103for (InductiveRangeCheck &IRC : RangeChecksToEliminate) {
1104ConstantInt *FoldedRangeCheck = IRC.getPassingDirection()
1105 ?ConstantInt::getTrue(Context)
1106 :ConstantInt::getFalse(Context);
1107 IRC.getCheckUse()->set(FoldedRangeCheck);
1108 }
1109 }
1110
1111return Changed;
1112}
APInt.h
This file implements a class to represent arbitrary precision integral constant values and operations...
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition:ArchiveWriter.cpp:205
ArrayRef.h
BasicBlockUtils.h
BlockFrequencyInfo.h
BranchProbabilityInfo.h
BranchProbability.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Casting.h
Cloning.h
CommandLine.h
Compiler.h
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition:Compiler.h:622
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Debug.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
DerivedTypes.h
Dominators.h
End
bool End
Definition:ELF_riscv.cpp:480
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRBuilder.h
BasicBlock.h
CFG.h
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Function.h
Module.h
Module.h This file contains the declarations for the Module class.
Type.h
Use.h
This defines the Use class.
User.h
Value.h
NoopOrExtend
static const SCEV * NoopOrExtend(const SCEV *S, Type *Ty, ScalarEvolution &SE, bool Signed)
If the type of S matches with Ty, return S.
Definition:InductiveRangeCheckElimination.cpp:573
PrintRangeChecks
static cl::opt< bool > PrintRangeChecks("irce-print-range-checks", cl::Hidden, cl::init(false))
AllowUnsignedLatchCondition
static cl::opt< bool > AllowUnsignedLatchCondition("irce-allow-unsigned-latch", cl::Hidden, cl::init(true))
LoopSizeCutoff
static cl::opt< unsigned > LoopSizeCutoff("irce-loop-size-cutoff", cl::Hidden, cl::init(64))
IntersectSignedRange
static std::optional< InductiveRangeCheck::Range > IntersectSignedRange(ScalarEvolution &SE, const std::optional< InductiveRangeCheck::Range > &R1, const InductiveRangeCheck::Range &R2)
Definition:InductiveRangeCheckElimination.cpp:844
AllowNarrowLatchCondition
static cl::opt< bool > AllowNarrowLatchCondition("irce-allow-narrow-latch", cl::Hidden, cl::init(true), cl::desc("If set to true, IRCE may eliminate wide range checks in loops " "with narrow latch condition."))
MaxTypeSizeForOverflowCheck
static cl::opt< unsigned > MaxTypeSizeForOverflowCheck("irce-max-type-size-for-overflow-check", cl::Hidden, cl::init(32), cl::desc("Maximum size of range check type for which can be produced runtime " "overflow check of its limit's computation"))
MinEliminatedChecks
static cl::opt< unsigned > MinEliminatedChecks("irce-min-eliminated-checks", cl::Hidden, cl::init(10))
PrintChangedLoops
static cl::opt< bool > PrintChangedLoops("irce-print-changed-loops", cl::Hidden, cl::init(false))
IntersectUnsignedRange
static std::optional< InductiveRangeCheck::Range > IntersectUnsignedRange(ScalarEvolution &SE, const std::optional< InductiveRangeCheck::Range > &R1, const InductiveRangeCheck::Range &R2)
Definition:InductiveRangeCheckElimination.cpp:873
SkipProfitabilityChecks
static cl::opt< bool > SkipProfitabilityChecks("irce-skip-profitability-checks", cl::Hidden, cl::init(false))
calculateSubRanges
static std::optional< LoopConstrainer::SubRanges > calculateSubRanges(ScalarEvolution &SE, const Loop &L, InductiveRangeCheck::Range &Range, const LoopStructure &MainLoopStructure)
Definition:InductiveRangeCheckElimination.cpp:582
PrintScaledBoundaryRangeChecks
static cl::opt< bool > PrintScaledBoundaryRangeChecks("irce-print-scaled-boundary-range-checks", cl::Hidden, cl::init(false))
InductiveRangeCheckElimination.h
InstrTypes.h
getFalse
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false.
Definition:InstructionSimplify.cpp:86
Instructions.h
LoopAnalysisManager.h
This header provides classes for managing per-loop analyses.
LoopConstrainer.h
LoopInfo.h
LoopSimplify.h
LoopUtils.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
R2
#define R2(n)
Metadata.h
This file contains the declarations for metadata subclasses.
Signed
@ Signed
Definition:NVPTXISelLowering.cpp:4789
Range
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Operation
PowerPC Reduce CR logical Operation
Definition:PPCReduceCRLogicals.cpp:735
PatternMatch.h
PriorityWorklist.h
This file provides a priority worklist.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
ScalarEvolutionExpressions.h
ScalarEvolution.h
SmallPtrSet.h
This file defines the SmallPtrSet class.
SmallVector.h
This file defines the SmallVector class.
StringRef.h
getType
static SymbolRef::Type getType(const Symbol *Sym)
Definition:TapiFile.cpp:39
Twine.h
ValueMapper.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
IV
static const uint32_t IV[8]
Definition:blake3_impl.h:78
T
llvm::APInt::getSignedMaxValue
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition:APInt.h:209
llvm::APInt::getSignedMinValue
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition:APInt.h:219
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition:PassManager.h:253
llvm::AnalysisManager::invalidate
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
Definition:PassManagerImpl.h:172
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition:PassManager.h:410
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::BasicBlock::getContext
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition:BasicBlock.cpp:168
llvm::BlockFrequencyAnalysis
Analysis pass which computes BlockFrequencyInfo.
Definition:BlockFrequencyInfo.h:114
llvm::BlockFrequencyInfo
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Definition:BlockFrequencyInfo.h:37
llvm::BranchInst
Conditional or Unconditional Branch instruction.
Definition:Instructions.h:3016
llvm::BranchInst::getSuccessor
BasicBlock * getSuccessor(unsigned i) const
Definition:Instructions.h:3104
llvm::BranchInst::isUnconditional
bool isUnconditional() const
Definition:Instructions.h:3089
llvm::BranchProbabilityAnalysis
Analysis pass which computes BranchProbabilityInfo.
Definition:BranchProbabilityInfo.h:425
llvm::BranchProbabilityInfo
Analysis providing branch probability information.
Definition:BranchProbabilityInfo.h:112
llvm::BranchProbabilityInfo::getEdgeProbability
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
Definition:BranchProbabilityInfo.cpp:1094
llvm::BranchProbabilityInfo::swapSuccEdgesProbabilities
void swapSuccEdgesProbabilities(const BasicBlock *Src)
Swap outgoing edges probabilities for Src with branch terminator.
Definition:BranchProbabilityInfo.cpp:1177
llvm::BranchProbability
Definition:BranchProbability.h:30
llvm::BranchProbability::scaleByInverse
uint64_t scaleByInverse(uint64_t Num) const
Scale a large integer by the inverse.
Definition:BranchProbability.cpp:111
llvm::BranchProbability::isZero
bool isZero() const
Definition:BranchProbability.h:46
llvm::BranchProbability::isUnknown
bool isUnknown() const
Definition:BranchProbability.h:47
llvm::BranchProbability::scale
uint64_t scale(uint64_t Num) const
Scale a large integer.
Definition:BranchProbability.cpp:107
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition:InstrTypes.h:673
llvm::CmpInst::getSwappedPredicate
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition:InstrTypes.h:825
llvm::CmpInst::getPredicate
Predicate getPredicate() const
Return the predicate for this instruction.
Definition:InstrTypes.h:763
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::ConstantInt::getTrue
static ConstantInt * getTrue(LLVMContext &Context)
Definition:Constants.cpp:866
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition:Dominators.h:279
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition:Dominators.h:162
llvm::Function
Definition:Function.h:63
llvm::ICmpInst
This instruction compares its operands according to the predicate given to the constructor.
Definition:Instructions.h:1158
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::IRCEPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition:InductiveRangeCheckElimination.cpp:901
llvm::Instruction::BinaryOps
BinaryOps
Definition:Instruction.h:989
llvm::IntegerType::get
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition:Type.cpp:311
llvm::IntegerType::getBitWidth
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition:DerivedTypes.h:74
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::LoopAnalysis
Analysis pass that exposes the LoopInfo for a function.
Definition:LoopInfo.h:566
llvm::LoopConstrainer
This class is used to constrain loops to run within a given iteration space.
Definition:LoopConstrainer.h:95
llvm::LoopInfo
Definition:LoopInfo.h:407
llvm::Loop
Represents a single loop in the control flow graph.
Definition:LoopInfo.h:39
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition:Analysis.h:111
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition:Analysis.h:117
llvm::PreservedAnalyses::abandon
void abandon()
Mark an analysis as abandoned.
Definition:Analysis.h:164
llvm::PriorityWorklist::pop_back_val
T pop_back_val()
Definition:PriorityWorklist.h:153
llvm::PriorityWorklist::empty
bool empty() const
Determine if the PriorityWorklist is empty or not.
Definition:PriorityWorklist.h:67
llvm::SCEVAddRecExpr
This node represents a polynomial recurrence on the trip count of the specified loop.
Definition:ScalarEvolutionExpressions.h:347
llvm::SCEVAddRecExpr::getType
Type * getType() const
Definition:ScalarEvolutionExpressions.h:357
llvm::SCEVAddRecExpr::getStart
const SCEV * getStart() const
Definition:ScalarEvolutionExpressions.h:358
llvm::SCEVAddRecExpr::getStepRecurrence
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
Definition:ScalarEvolutionExpressions.h:365
llvm::SCEVAddRecExpr::isAffine
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
Definition:ScalarEvolutionExpressions.h:375
llvm::SCEVAddRecExpr::getLoop
const Loop * getLoop() const
Definition:ScalarEvolutionExpressions.h:359
llvm::SCEVConstant
This class represents a constant integer value.
Definition:ScalarEvolutionExpressions.h:60
llvm::SCEV
This class represents an analyzed expression in the program.
Definition:ScalarEvolution.h:71
llvm::SCEV::print
void print(raw_ostream &OS) const
Print out the internal representation of this scalar to the specified stream.
Definition:ScalarEvolution.cpp:273
llvm::SCEV::getType
Type * getType() const
Return the LLVM type of this SCEV expression.
Definition:ScalarEvolution.cpp:386
llvm::SCEV::NoWrapFlags
NoWrapFlags
NoWrapFlags are bitfield indices into SubclassData.
Definition:ScalarEvolution.h:126
llvm::SCEV::FlagAnyWrap
@ FlagAnyWrap
Definition:ScalarEvolution.h:127
llvm::SCEV::FlagNSW
@ FlagNSW
Definition:ScalarEvolution.h:130
llvm::SCEV::FlagNUW
@ FlagNUW
Definition:ScalarEvolution.h:129
llvm::ScalarEvolutionAnalysis
Analysis pass that exposes the ScalarEvolution for a function.
Definition:ScalarEvolution.h:2320
llvm::ScalarEvolution
The main scalar evolution driver.
Definition:ScalarEvolution.h:447
llvm::ScalarEvolution::getNegativeSCEV
const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
Definition:ScalarEvolution.cpp:4569
llvm::ScalarEvolution::getSMaxExpr
const SCEV * getSMaxExpr(const SCEV *LHS, const SCEV *RHS)
Definition:ScalarEvolution.cpp:4343
llvm::ScalarEvolution::getSMinExpr
const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
Definition:ScalarEvolution.cpp:4361
llvm::ScalarEvolution::getUMaxExpr
const SCEV * getUMaxExpr(const SCEV *LHS, const SCEV *RHS)
Definition:ScalarEvolution.cpp:4352
llvm::ScalarEvolution::getZero
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
Definition:ScalarEvolution.h:653
llvm::ScalarEvolution::willNotOverflow
bool willNotOverflow(Instruction::BinaryOps BinOp, bool Signed, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI=nullptr)
Is operation BinOp between LHS and RHS provably does not have a signed/unsigned overflow (Signed)?...
Definition:ScalarEvolution.cpp:2314
llvm::ScalarEvolution::getConstant
const SCEV * getConstant(ConstantInt *V)
Definition:ScalarEvolution.cpp:473
llvm::ScalarEvolution::getSCEV
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
Definition:ScalarEvolution.cpp:4547
llvm::ScalarEvolution::getNoopOrSignExtend
const SCEV * getNoopOrSignExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
Definition:ScalarEvolution.cpp:4742
llvm::ScalarEvolution::getOne
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
Definition:ScalarEvolution.h:656
llvm::ScalarEvolution::isLoopInvariant
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
Definition:ScalarEvolution.cpp:14100
llvm::ScalarEvolution::getUMinExpr
const SCEV * getUMinExpr(const SCEV *LHS, const SCEV *RHS, bool Sequential=false)
Definition:ScalarEvolution.cpp:4371
llvm::ScalarEvolution::getTruncateExpr
const SCEV * getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
Definition:ScalarEvolution.cpp:1150
llvm::ScalarEvolution::getMinusSCEV
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
Definition:ScalarEvolution.cpp:4655
llvm::ScalarEvolution::getNoopOrZeroExtend
const SCEV * getNoopOrZeroExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
Definition:ScalarEvolution.cpp:4730
llvm::ScalarEvolution::getSignExtendExpr
const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
Definition:ScalarEvolution.cpp:1900
llvm::ScalarEvolution::getMulExpr
const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
Definition:ScalarEvolution.cpp:3106
llvm::ScalarEvolution::getAddExpr
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
Definition:ScalarEvolution.cpp:2526
llvm::ScalarEvolution::isKnownPredicate
bool isKnownPredicate(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
Definition:ScalarEvolution.cpp:11050
llvm::SmallPriorityWorklist
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
Definition:PriorityWorklist.h:257
llvm::SmallPtrSetImpl
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition:SmallPtrSet.h:363
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition:SmallPtrSet.h:384
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition:SmallPtrSet.h:519
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition:Type.h:237
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition:Use.h:43
llvm::Use::get
Value * get() const
Definition:Use.h:66
llvm::User::getOperandUse
const Use & getOperandUse(unsigned i) const
Definition:User.h:241
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition:User.h:228
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::cl::opt
Definition:CommandLine.h:1423
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition:STLFunctionalExtras.h:37
llvm::ilist_detail::node_parent_access::getParent
const ParentTy * getParent() const
Definition:ilist_node.h:32
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
uint64_t
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::AArch64CC::LS
@ LS
Definition:AArch64BaseInfo.h:264
llvm::ARM::ProfileKind::M
@ M
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::M68k::MemAddrModeKind::V
@ V
llvm::M68k::MemAddrModeKind::L
@ L
llvm::PatternMatch
Definition:PatternMatch.h:47
llvm::PatternMatch::match
bool match(Val *V, const Pattern &P)
Definition:PatternMatch.h:49
llvm::PatternMatch::m_Value
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Definition:PatternMatch.h:92
llvm::PatternMatch::m_LogicalAnd
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
Definition:PatternMatch.h:3081
llvm::PatternMatch::m_Sub
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
Definition:PatternMatch.h:1114
llvm::cl::Hidden
@ Hidden
Definition:CommandLine.h:137
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition:CommandLine.h:443
llvm::dwarf::Index
Index
Definition:Dwarf.h:882
llvm::logicalview::LVAttributeKind::Zero
@ Zero
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::simplifyLoop
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
Definition:LoopSimplify.cpp:697
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition:SparseBitVector.h:877
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::formLCSSARecursively
bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
Definition:LCSSA.cpp:465
llvm::InvertBranch
void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder)
Definition:BasicBlockUtils.cpp:1896
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition:raw_ostream.cpp:907
llvm::appendLoopsToWorklist
void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist< Loop *, 4 > &)
Utility that implements appending of loops onto a worklist given a range.
Definition:LoopUtils.cpp:1814
llvm::isKnownNegativeInLoop
bool isKnownNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE)
Returns true if we can prove that S is defined and always negative in loop L.
Definition:LoopUtils.cpp:1388
llvm::BitWidth
constexpr unsigned BitWidth
Definition:BitmaskEnum.h:217
llvm::getLoopPassPreservedAnalyses
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
Definition:LoopAnalysisManager.cpp:138
llvm::isKnownNonNegativeInLoop
bool isKnownNonNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE)
Returns true if we can prove that S is defined and always non-negative in loop L.
Definition:LoopUtils.cpp:1395
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition:BitVector.h:860
raw_ostream.h
llvm::LoopConstrainer::SubRanges
Definition:LoopConstrainer.h:104
llvm::LoopStructure
Definition:LoopConstrainer.h:34
llvm::LoopStructure::IndVarStart
Value * IndVarStart
Definition:LoopConstrainer.h:56
llvm::LoopStructure::IndVarIncreasing
bool IndVarIncreasing
Definition:LoopConstrainer.h:59
llvm::LoopStructure::ExitCountTy
IntegerType * ExitCountTy
Definition:LoopConstrainer.h:61
llvm::LoopStructure::IsSignedPredicate
bool IsSignedPredicate
Definition:LoopConstrainer.h:60
llvm::LoopStructure::LoopExitAt
Value * LoopExitAt
Definition:LoopConstrainer.h:58
llvm::LoopStructure::parseLoopStructure
static std::optional< LoopStructure > parseLoopStructure(ScalarEvolution &, Loop &, bool, const char *&)
Definition:LoopConstrainer.cpp:125
llvm::cl::desc
Definition:CommandLine.h:409

Generated on Thu Jul 17 2025 17:00:43 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp