@@ -1130,19 +1130,63 @@ struct AAPointerInfoImpl
1130
1130
QueryingAA, IRPosition::function (*LI.getFunction ()),
1131
1131
DepClassTy::OPTIONAL);
1132
1132
1133
- // Helper to determine if the instruction may reach the load.
1134
- auto IsReachableFrom = [&](const Instruction &I) {
1135
- const auto &ReachabilityAA = A.getAAFor <AAReachability>(
1136
- QueryingAA, IRPosition::function (*I.getFunction ()),
1137
- DepClassTy::OPTIONAL);
1138
- return ReachabilityAA.isAssumedReachable (A, I, LI);
1139
- };
1140
-
1141
- const bool CanUseCFGResoning =
1142
- NoRecurseAA.isKnownNoRecurse () && CanIgnoreThreading (LI);
1133
+ const bool CanUseCFGResoning = CanIgnoreThreading (LI);
1143
1134
InformationCache &InfoCache = A.getInfoCache ();
1144
1135
const DominatorTree *DT =
1145
- InfoCache.getAnalysisResultForFunction <DominatorTreeAnalysis>(Scope);
1136
+ NoRecurseAA.isKnownNoRecurse ()
1137
+ ? InfoCache.getAnalysisResultForFunction <DominatorTreeAnalysis>(
1138
+ Scope)
1139
+ : nullptr ;
1140
+
1141
+ enum GPUAddressSpace : unsigned {
1142
+ Generic = 0 ,
1143
+ Global = 1 ,
1144
+ Shared = 3 ,
1145
+ Constant = 4 ,
1146
+ Local = 5 ,
1147
+ };
1148
+
1149
+ // Helper to check if a value has "kernel lifetime", that is it will not
1150
+ // outlive a GPU kernel. This is true for shared, constant, and local
1151
+ // globals on AMD and NVIDIA GPUs.
1152
+ auto HasKernelLifetime = [&](Value *V, Module &M) {
1153
+ Triple T (M.getTargetTriple ());
1154
+ if (!(T.isAMDGPU () || T.isNVPTX ()))
1155
+ return false ;
1156
+ switch (V->getType ()->getPointerAddressSpace ()) {
1157
+ case GPUAddressSpace::Shared:
1158
+ case GPUAddressSpace::Constant:
1159
+ case GPUAddressSpace::Local:
1160
+ return true ;
1161
+ default :
1162
+ return false ;
1163
+ };
1164
+ };
1165
+
1166
+ // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1167
+ // to determine if we should look at reachability from the callee. For
1168
+ // certain pointers we know the lifetime and we do not have to step into the
1169
+ // callee to determine reachability as the pointer would be dead in the
1170
+ // callee. See the conditional initialization below.
1171
+ std::function<bool (const Function &)> IsLiveInCalleeCB;
1172
+
1173
+ if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue ())) {
1174
+ // If the alloca containing function is not recursive the alloca
1175
+ // must be dead in the callee.
1176
+ const Function *AIFn = AI->getFunction ();
1177
+ const auto &NoRecurseAA = A.getAAFor <AANoRecurse>(
1178
+ *this , IRPosition::function (*AIFn), DepClassTy::OPTIONAL);
1179
+ if (NoRecurseAA.isAssumedNoRecurse ()) {
1180
+ IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1181
+ }
1182
+ } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue ())) {
1183
+ // If the global has kernel lifetime we can stop if we reach a kernel
1184
+ // as it is "dead" in the (unknown) callees.
1185
+ if (HasKernelLifetime (GV, *GV->getParent ()))
1186
+ IsLiveInCalleeCB = [](const Function &Fn) {
1187
+ return !Fn.hasFnAttribute (" kernel" );
1188
+ };
1189
+ }
1146
1190
1147
1191
auto AccessCB = [&](const Access &Acc, bool Exact) {
1148
1192
if (!Acc.isWrite ())
@@ -1151,7 +1195,8 @@ struct AAPointerInfoImpl
1151
1195
// For now we only filter accesses based on CFG reasoning which does not
1152
1196
// work yet if we have threading effects, or the access is complicated.
1153
1197
if (CanUseCFGResoning) {
1154
- if (!IsReachableFrom (*Acc.getLocalInst ()))
1198
+ if (!AA::isPotentiallyReachable (A, *Acc.getLocalInst (), LI, QueryingAA,
1199
+ IsLiveInCalleeCB))
1155
1200
return true ;
1156
1201
if (DT && Exact &&
1157
1202
(Acc.getLocalInst ()->getFunction () == LI.getFunction ()) &&
@@ -9674,7 +9719,7 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9674
9719
if (!Reachability.isAssumedReachable (A, Inst, CBInst))
9675
9720
return true ;
9676
9721
9677
- const auto &CB = cast<CallBase>(CBInst);
9722
+ auto &CB = cast<CallBase>(CBInst);
9678
9723
const AACallEdges &AAEdges = A.getAAFor <AACallEdges>(
9679
9724
*this , IRPosition::callsite_function (CB), DepClassTy::REQUIRED);
9680
9725
@@ -9684,47 +9729,8 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9684
9729
9685
9730
bool UsedAssumedInformation = false ;
9686
9731
return A.checkForAllCallLikeInstructions (CheckCallBase, *this ,
9687
- UsedAssumedInformation);
9688
- }
9689
-
9690
- ChangeStatus checkReachableBackwards (Attributor &A, QuerySet &Set) {
9691
- ChangeStatus Change = ChangeStatus::UNCHANGED;
9692
-
9693
- // For all remaining instruction queries, check
9694
- // callers. A call inside that function might satisfy the query.
9695
- auto CheckCallSite = [&](AbstractCallSite CallSite) {
9696
- CallBase *CB = CallSite.getInstruction ();
9697
- if (!CB)
9698
- return false ;
9699
-
9700
- if (isa<InvokeInst>(CB))
9701
- return false ;
9702
-
9703
- Instruction *Inst = CB->getNextNonDebugInstruction ();
9704
- const AAFunctionReachability &AA = A.getAAFor <AAFunctionReachability>(
9705
- *this , IRPosition::function (*Inst->getFunction ()),
9706
- DepClassTy::REQUIRED);
9707
- for (const Function *Fn : make_early_inc_range (Set.Unreachable )) {
9708
- if (AA.instructionCanReach (A, *Inst, *Fn, /* UseBackwards */ false )) {
9709
- Set.markReachable (*Fn);
9710
- Change = ChangeStatus::CHANGED;
9711
- }
9712
- }
9713
- return true ;
9714
- };
9715
-
9716
- bool NoUnknownCall = true ;
9717
- if (A.checkForAllCallSites (CheckCallSite, *this , true , NoUnknownCall))
9718
- return Change;
9719
-
9720
- // If we don't know all callsites we have to assume that we can reach fn.
9721
- for (auto &QSet : InstQueriesBackwards) {
9722
- if (!QSet.second .CanReachUnknownCallee )
9723
- Change = ChangeStatus::CHANGED;
9724
- QSet.second .CanReachUnknownCallee = true ;
9725
- }
9726
-
9727
- return Change;
9732
+ UsedAssumedInformation,
9733
+ /* CheckBBLivenessOnly */ true );
9728
9734
}
9729
9735
9730
9736
public:
@@ -9776,12 +9782,15 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9776
9782
if (!isValidState ())
9777
9783
return true ;
9778
9784
9779
- const auto &Reachability = &A.getAAFor <AAReachability>(
9785
+ if (UseBackwards)
9786
+ return AA::isPotentiallyReachable (A, Inst, Fn, *this , nullptr );
9787
+
9788
+ const auto &Reachability = A.getAAFor <AAReachability>(
9780
9789
*this , IRPosition::function (*getAssociatedFunction ()),
9781
9790
DepClassTy::REQUIRED);
9782
9791
9783
9792
SmallVector<const AACallEdges *> CallEdges;
9784
- bool AllKnown = getReachableCallEdges (A, * Reachability, Inst, CallEdges);
9793
+ bool AllKnown = getReachableCallEdges (A, Reachability, Inst, CallEdges);
9785
9794
// Attributor returns attributes as const, so this function has to be
9786
9795
// const for users of this attribute to use it without having to do
9787
9796
// a const_cast.
@@ -9791,25 +9800,7 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9791
9800
if (!AllKnown)
9792
9801
InstQSet.CanReachUnknownCallee = true ;
9793
9802
9794
- bool ForwardsResult = InstQSet.isReachable (A, *NonConstThis, CallEdges, Fn);
9795
- if (ForwardsResult)
9796
- return true ;
9797
- // We are done.
9798
- if (!UseBackwards)
9799
- return false ;
9800
-
9801
- QuerySet &InstBackwardsQSet = NonConstThis->InstQueriesBackwards [&Inst];
9802
-
9803
- Optional<bool > BackwardsCached = InstBackwardsQSet.isCachedReachable (Fn);
9804
- if (BackwardsCached.hasValue ())
9805
- return BackwardsCached.getValue ();
9806
-
9807
- // Assume unreachable, to prevent problems.
9808
- InstBackwardsQSet.Unreachable .insert (&Fn);
9809
-
9810
- // Check backwards reachability.
9811
- NonConstThis->checkReachableBackwards (A, InstBackwardsQSet);
9812
- return InstBackwardsQSet.isCachedReachable (Fn).getValue ();
9803
+ return InstQSet.isReachable (A, *NonConstThis, CallEdges, Fn);
9813
9804
}
9814
9805
9815
9806
// / See AbstractAttribute::updateImpl(...).
@@ -9847,10 +9838,6 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9847
9838
Change |= InstPair.second .update (A, *this , CallEdges);
9848
9839
}
9849
9840
9850
- // Update backwards queries.
9851
- for (auto &QueryPair : InstQueriesBackwards)
9852
- Change |= checkReachableBackwards (A, QueryPair.second );
9853
-
9854
9841
return Change;
9855
9842
}
9856
9843
@@ -9879,9 +9866,6 @@ struct AAFunctionReachabilityFunction : public AAFunctionReachability {
9879
9866
9880
9867
// / This is for instruction queries than scan "forward".
9881
9868
DenseMap<const Instruction *, QueryResolver> InstQueries;
9882
-
9883
- // / This is for instruction queries than scan "backward".
9884
- DenseMap<const Instruction *, QuerySet> InstQueriesBackwards;
9885
9869
};
9886
9870
9887
9871
// / ---------------------- Assumption Propagation ------------------------------
0 commit comments