Skip to content

Commit 16e9f57

Browse files
committed
[SCEV] Introduce SCEVUse, use it instead of const SCEV * (NFCI) (WIP).
This patch introduces SCEVUse, which is a tagged pointer containing the used const SCEV *, plus extra bits to store NUW/NSW flags that are only valid at the specific use. This was suggested by @nikic as an alternative to llvm#90742. This patch just updates most SCEV infrastructure to operate on SCEVUse instead of const SCEV *. It does not introduce any code that makes use of the use-specific flags yet which I'll share as follow-ups. Note that this should be NFC, but currently there's at least one case where it is not (turn-to-invariant.ll), which I'll investigate once we agree on the overall direction. This PR at the moment also contains a commit that updates various SCEV clients to use `const SCEV *` instead of `const auto *`, to prepare for this patch. This reduces the number of changes needed, as SCEVUse will automatically convert to `const SCEV *`. This is a safe default, as it just drops the use-specific flags for the expression (it will not drop any use-specific flags for any of its operands though). This probably SCEVUse could probably also be used to address mis-compiles due to equivalent AddRecs modulo flags result in an AddRec with incorrect flags for some uses of some phis, e.g. the one llvm#80430 attempted to fix Compile-time impact: stage1-O3: +0.06% stage1-ReleaseThinLTO: +0.07% stage1-ReleaseLTO-g: +0.07% stage2-O3: +0.11% https://llvm-compile-time-tracker.com/compare.php?from=ce055843e2be9643bd58764783a7bb69f6db8c9a&to=8c7f4e9e154ebc4862c4e2716cedc3c688352d7c&stat=instructions:u
1 parent bc5485f commit 16e9f57

File tree

17 files changed

+2043
-1720
lines changed

17 files changed

+2043
-1720
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 480 additions & 350 deletions
Large diffs are not rendered by default.

llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h

Lines changed: 154 additions & 133 deletions
Large diffs are not rendered by default.

llvm/include/llvm/Analysis/ScalarEvolutionPatternMatch.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@
1313
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONPATTERNMATCH_H
1414
#define LLVM_ANALYSIS_SCALAREVOLUTIONPATTERNMATCH_H
1515

16+
#include "llvm/Analysis/ScalarEvolution.h"
1617
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
1718

1819
namespace llvm {
1920
namespace SCEVPatternMatch {
2021

21-
template <typename Val, typename Pattern>
22+
template <typename Pattern>
2223
bool match(const SCEV *S, const Pattern &P) {
23-
return P.match(S);
24+
return const_cast<Pattern &>(P).match(S);
25+
}
26+
27+
template <typename Pattern> bool match(const SCEVUse U, const Pattern &P) {
28+
const SCEV *S = U.getPointer();
29+
return const_cast<Pattern &>(P).match(S);
2430
}
2531

2632
template <typename Predicate> struct cst_pred_ty : public Predicate {
@@ -99,7 +105,7 @@ template <typename SCEVTy, typename Op0_t> struct SCEVUnaryExpr_match {
99105

100106
bool match(const SCEV *S) {
101107
auto *E = dyn_cast<SCEVTy>(S);
102-
return E && E->getNumOperands() == 1 && Op0.match(E->getOperand(0));
108+
return E && E->getNumOperands() == 1 && Op0.match(E->getOperand(0).getPointer());
103109
}
104110
};
105111

@@ -130,8 +136,8 @@ struct SCEVBinaryExpr_match {
130136

131137
bool match(const SCEV *S) {
132138
auto *E = dyn_cast<SCEVTy>(S);
133-
return E && E->getNumOperands() == 2 && Op0.match(E->getOperand(0)) &&
134-
Op1.match(E->getOperand(1));
139+
return E && E->getNumOperands() == 2 && Op0.match(E->getOperand(0).getPointer()) &&
140+
Op1.match(E->getOperand(1).getPointer());
135141
}
136142
};
137143

llvm/lib/Analysis/DependenceAnalysis.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,10 +1245,12 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
12451245
if (const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->getType())) {
12461246
LLVM_DEBUG(dbgs() << "\t UpperBound = " << *UpperBound);
12471247
LLVM_DEBUG(dbgs() << ", " << *UpperBound->getType() << "\n");
1248-
const SCEV *AbsDelta =
1249-
SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
1250-
const SCEV *AbsCoeff =
1251-
SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
1248+
const SCEV *AbsDelta = SE->isKnownNonNegative(Delta)
1249+
? Delta
1250+
: SE->getNegativeSCEV(Delta).getPointer();
1251+
const SCEV *AbsCoeff = SE->isKnownNonNegative(Coeff)
1252+
? Coeff
1253+
: SE->getNegativeSCEV(Coeff).getPointer();
12521254
const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
12531255
if (isKnownPredicate(CmpInst::ICMP_SGT, AbsDelta, Product)) {
12541256
// Distance greater than trip count - no dependence
@@ -1786,8 +1788,9 @@ bool DependenceInfo::weakZeroSrcSIVtest(const SCEV *DstCoeff,
17861788
const SCEV *AbsCoeff =
17871789
SE->isKnownNegative(ConstCoeff) ?
17881790
SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1789-
const SCEV *NewDelta =
1790-
SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1791+
const SCEV *NewDelta = SE->isKnownNegative(ConstCoeff)
1792+
? SE->getNegativeSCEV(Delta).getPointer()
1793+
: Delta;
17911794

17921795
// check that Delta/SrcCoeff < iteration count
17931796
// really check NewDelta < count*AbsCoeff
@@ -1895,8 +1898,9 @@ bool DependenceInfo::weakZeroDstSIVtest(const SCEV *SrcCoeff,
18951898
const SCEV *AbsCoeff =
18961899
SE->isKnownNegative(ConstCoeff) ?
18971900
SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1898-
const SCEV *NewDelta =
1899-
SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1901+
const SCEV *NewDelta = SE->isKnownNegative(ConstCoeff)
1902+
? SE->getNegativeSCEV(Delta).getPointer()
1903+
: Delta;
19001904

19011905
// check that Delta/SrcCoeff < iteration count
19021906
// really check NewDelta < count*AbsCoeff

llvm/lib/Analysis/IVDescriptors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1520,7 +1520,7 @@ bool InductionDescriptor::isInductionPHI(
15201520
return false;
15211521

15221522
// Check that the PHI is consecutive.
1523-
const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi);
1523+
const SCEV *PhiScev = Expr ? Expr : SE->getSCEV(Phi).getPointer();
15241524
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PhiScev);
15251525

15261526
if (!AR) {

llvm/lib/Analysis/LoopCacheAnalysis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ bool IndexedReference::isConsecutive(const Loop &L, const SCEV *&Stride,
500500
SE.getNoopOrSignExtend(ElemSize, WiderType));
501501
const SCEV *CacheLineSize = SE.getConstant(Stride->getType(), CLS);
502502

503-
Stride = SE.isKnownNegative(Stride) ? SE.getNegativeSCEV(Stride) : Stride;
503+
Stride = SE.isKnownNegative(Stride) ? SE.getNegativeSCEV(Stride).getPointer()
504+
: Stride;
504505
return SE.isKnownPredicate(ICmpInst::ICMP_ULT, Stride, CacheLineSize);
505506
}
506507

0 commit comments

Comments
 (0)