@@ -398,8 +398,10 @@ static Value *constructPointer(Type *ResTy, Value *Ptr, int64_t Offset,
398
398
template <typename AAType, typename StateTy>
399
399
static bool genericValueTraversal (
400
400
Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
401
- function_ref<bool (Value &, StateTy &, bool )> VisitValueCB,
402
- int MaxValues = 8, function_ref<Value *(Value *)> StripCB = nullptr) {
401
+ function_ref<bool (Value &, const Instruction *, StateTy &, bool )>
402
+ VisitValueCB,
403
+ const Instruction *CtxI, int MaxValues = 16,
404
+ function_ref<Value *(Value *)> StripCB = nullptr) {
403
405
404
406
const AAIsDead *LivenessAA = nullptr ;
405
407
if (IRP.getAnchorScope ())
@@ -408,20 +410,22 @@ static bool genericValueTraversal(
408
410
/* TrackDependence */ false );
409
411
bool AnyDead = false ;
410
412
411
- // TODO: Use Positions here to allow context sensitivity in VisitValueCB
412
- SmallPtrSet<Value * , 16 > Visited;
413
- SmallVector<Value * , 16 > Worklist;
414
- Worklist.push_back (&IRP.getAssociatedValue ());
413
+ using Item = std::pair<Value *, const Instruction *>;
414
+ SmallSet<Item , 16 > Visited;
415
+ SmallVector<Item , 16 > Worklist;
416
+ Worklist.push_back ({ &IRP.getAssociatedValue (), CtxI} );
415
417
416
418
int Iteration = 0 ;
417
419
do {
418
- Value *V = Worklist.pop_back_val ();
420
+ Item I = Worklist.pop_back_val ();
421
+ Value *V = I.first ;
422
+ CtxI = I.second ;
419
423
if (StripCB)
420
424
V = StripCB (V);
421
425
422
426
// Check if we should process the current value. To prevent endless
423
427
// recursion keep a record of the values we followed!
424
- if (!Visited.insert (V ).second )
428
+ if (!Visited.insert (I ).second )
425
429
continue ;
426
430
427
431
// Make sure we limit the compile time for complex expressions.
@@ -444,14 +448,14 @@ static bool genericValueTraversal(
444
448
}
445
449
}
446
450
if (NewV && NewV != V) {
447
- Worklist.push_back (NewV);
451
+ Worklist.push_back ({ NewV, CtxI} );
448
452
continue ;
449
453
}
450
454
451
455
// Look through select instructions, visit both potential values.
452
456
if (auto *SI = dyn_cast<SelectInst>(V)) {
453
- Worklist.push_back (SI->getTrueValue ());
454
- Worklist.push_back (SI->getFalseValue ());
457
+ Worklist.push_back ({ SI->getTrueValue (), CtxI} );
458
+ Worklist.push_back ({ SI->getFalseValue (), CtxI} );
455
459
continue ;
456
460
}
457
461
@@ -460,20 +464,21 @@ static bool genericValueTraversal(
460
464
assert (LivenessAA &&
461
465
" Expected liveness in the presence of instructions!" );
462
466
for (unsigned u = 0 , e = PHI->getNumIncomingValues (); u < e; u++) {
463
- const BasicBlock *IncomingBB = PHI->getIncomingBlock (u);
467
+ BasicBlock *IncomingBB = PHI->getIncomingBlock (u);
464
468
if (A.isAssumedDead (*IncomingBB->getTerminator (), &QueryingAA,
465
469
LivenessAA,
466
470
/* CheckBBLivenessOnly */ true )) {
467
471
AnyDead = true ;
468
472
continue ;
469
473
}
470
- Worklist.push_back (PHI->getIncomingValue (u));
474
+ Worklist.push_back (
475
+ {PHI->getIncomingValue (u), IncomingBB->getTerminator ()});
471
476
}
472
477
continue ;
473
478
}
474
479
475
480
// Once a leaf is reached we inform the user through the callback.
476
- if (!VisitValueCB (*V, State, Iteration > 1 ))
481
+ if (!VisitValueCB (*V, CtxI, State, Iteration > 1 ))
477
482
return false ;
478
483
} while (!Worklist.empty ());
479
484
@@ -710,7 +715,7 @@ void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
710
715
}
711
716
if (A)
712
717
for (Attribute::AttrKind AK : AKs)
713
- getAttrsFromAssumes (AK, Attrs, *A);
718
+ getAttrsFromAssumes (AK, Attrs, *A);
714
719
}
715
720
716
721
bool IRPosition::getAttrsFromIRAttr (Attribute::AttrKind AK,
@@ -1466,7 +1471,8 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
1466
1471
};
1467
1472
1468
1473
// Callback for a leaf value returned by the associated function.
1469
- auto VisitValueCB = [](Value &Val, RVState &RVS, bool ) -> bool {
1474
+ auto VisitValueCB = [](Value &Val, const Instruction *, RVState &RVS,
1475
+ bool ) -> bool {
1470
1476
auto Size = RVS.RetValsMap [&Val].size ();
1471
1477
RVS.RetValsMap [&Val].insert (RVS.RetInsts .begin (), RVS.RetInsts .end ());
1472
1478
bool Inserted = RVS.RetValsMap [&Val].size () != Size;
@@ -1480,18 +1486,19 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
1480
1486
};
1481
1487
1482
1488
// Helper method to invoke the generic value traversal.
1483
- auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1489
+ auto VisitReturnedValue = [&](Value &RV, RVState &RVS,
1490
+ const Instruction *CtxI) {
1484
1491
IRPosition RetValPos = IRPosition::value (RV);
1485
- return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, * this ,
1486
- RVS, VisitValueCB);
1492
+ return genericValueTraversal<AAReturnedValues, RVState>(
1493
+ A, RetValPos, * this , RVS, VisitValueCB, CtxI );
1487
1494
};
1488
1495
1489
1496
// Callback for all "return intructions" live in the associated function.
1490
1497
auto CheckReturnInst = [this , &VisitReturnedValue, &Changed](Instruction &I) {
1491
1498
ReturnInst &Ret = cast<ReturnInst>(I);
1492
1499
RVState RVS ({ReturnedValues, Changed, {}});
1493
1500
RVS.RetInsts .insert (&Ret);
1494
- return VisitReturnedValue (*Ret.getReturnValue (), RVS);
1501
+ return VisitReturnedValue (*Ret.getReturnValue (), RVS, &I );
1495
1502
};
1496
1503
1497
1504
// Start by discovering returned values from all live returned instructions in
@@ -1576,7 +1583,7 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
1576
1583
// again.
1577
1584
bool Unused = false ;
1578
1585
RVState RVS ({NewRVsMap, Unused, RetValAAIt.second });
1579
- VisitReturnedValue (*CB->getArgOperand (Arg->getArgNo ()), RVS);
1586
+ VisitReturnedValue (*CB->getArgOperand (Arg->getArgNo ()), RVS, CB );
1580
1587
continue ;
1581
1588
} else if (isa<CallBase>(RetVal)) {
1582
1589
// Call sites are resolved by the callee attribute over time, no need to
@@ -2148,11 +2155,11 @@ struct AANonNullFloating
2148
2155
AC = InfoCache.getAnalysisResultForFunction <AssumptionAnalysis>(*Fn);
2149
2156
}
2150
2157
2151
- auto VisitValueCB = [&](Value &V, AANonNull::StateType &T ,
2152
- bool Stripped) -> bool {
2158
+ auto VisitValueCB = [&](Value &V, const Instruction *CtxI ,
2159
+ AANonNull::StateType &T, bool Stripped) -> bool {
2153
2160
const auto &AA = A.getAAFor <AANonNull>(*this , IRPosition::value (V));
2154
2161
if (!Stripped && this == &AA) {
2155
- if (!isKnownNonZero (&V, DL, 0 , AC, getCtxI () , DT))
2162
+ if (!isKnownNonZero (&V, DL, 0 , AC, CtxI , DT))
2156
2163
T.indicatePessimisticFixpoint ();
2157
2164
} else {
2158
2165
// Use abstract attribute information.
@@ -2164,8 +2171,8 @@ struct AANonNullFloating
2164
2171
};
2165
2172
2166
2173
StateType T;
2167
- if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition (), * this ,
2168
- T, VisitValueCB))
2174
+ if (!genericValueTraversal<AANonNull, StateType>(
2175
+ A, getIRPosition (), * this , T, VisitValueCB, getCtxI () ))
2169
2176
return indicatePessimisticFixpoint ();
2170
2177
2171
2178
return clampStateAndIndicateChange (getState (), T);
@@ -3776,7 +3783,8 @@ struct AADereferenceableFloating
3776
3783
3777
3784
const DataLayout &DL = A.getDataLayout ();
3778
3785
3779
- auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3786
+ auto VisitValueCB = [&](Value &V, const Instruction *, DerefState &T,
3787
+ bool Stripped) -> bool {
3780
3788
unsigned IdxWidth =
3781
3789
DL.getIndexSizeInBits (V.getType ()->getPointerAddressSpace ());
3782
3790
APInt Offset (IdxWidth, 0 );
@@ -3831,7 +3839,7 @@ struct AADereferenceableFloating
3831
3839
3832
3840
DerefState T;
3833
3841
if (!genericValueTraversal<AADereferenceable, DerefState>(
3834
- A, getIRPosition (), *this , T, VisitValueCB))
3842
+ A, getIRPosition (), *this , T, VisitValueCB, getCtxI () ))
3835
3843
return indicatePessimisticFixpoint ();
3836
3844
3837
3845
return Change | clampStateAndIndicateChange (getState (), T);
@@ -4073,8 +4081,8 @@ struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
4073
4081
4074
4082
const DataLayout &DL = A.getDataLayout ();
4075
4083
4076
- auto VisitValueCB = [&](Value &V, AAAlign::StateType &T ,
4077
- bool Stripped) -> bool {
4084
+ auto VisitValueCB = [&](Value &V, const Instruction * ,
4085
+ AAAlign::StateType &T, bool Stripped) -> bool {
4078
4086
const auto &AA = A.getAAFor <AAAlign>(*this , IRPosition::value (V));
4079
4087
if (!Stripped && this == &AA) {
4080
4088
// Use only IR information if we did not strip anything.
@@ -4092,7 +4100,7 @@ struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
4092
4100
4093
4101
StateType T;
4094
4102
if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition (), *this , T,
4095
- VisitValueCB))
4103
+ VisitValueCB, getCtxI () ))
4096
4104
return indicatePessimisticFixpoint ();
4097
4105
4098
4106
// TODO: If we know we visited all incoming values, thus no are assumed
@@ -4958,7 +4966,8 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4958
4966
ChangeStatus updateImpl (Attributor &A) override {
4959
4967
bool HasValueBefore = SimplifiedAssociatedValue.hasValue ();
4960
4968
4961
- auto VisitValueCB = [&](Value &V, bool &, bool Stripped) -> bool {
4969
+ auto VisitValueCB = [&](Value &V, const Instruction *CtxI, bool &,
4970
+ bool Stripped) -> bool {
4962
4971
auto &AA = A.getAAFor <AAValueSimplify>(*this , IRPosition::value (V));
4963
4972
if (!Stripped && this == &AA) {
4964
4973
// TODO: Look the instruction and check recursively.
@@ -4971,8 +4980,8 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4971
4980
};
4972
4981
4973
4982
bool Dummy = false ;
4974
- if (!genericValueTraversal<AAValueSimplify, bool >(A, getIRPosition (), * this ,
4975
- Dummy, VisitValueCB))
4983
+ if (!genericValueTraversal<AAValueSimplify, bool >(
4984
+ A, getIRPosition (), * this , Dummy, VisitValueCB, getCtxI () ))
4976
4985
if (!askSimplifiedValueForAAValueConstantRange (A))
4977
4986
return indicatePessimisticFixpoint ();
4978
4987
@@ -6605,7 +6614,8 @@ void AAMemoryLocationImpl::categorizePtrValue(
6605
6614
return V;
6606
6615
};
6607
6616
6608
- auto VisitValueCB = [&](Value &V, AAMemoryLocation::StateType &T,
6617
+ auto VisitValueCB = [&](Value &V, const Instruction *,
6618
+ AAMemoryLocation::StateType &T,
6609
6619
bool Stripped) -> bool {
6610
6620
assert (!isa<GEPOperator>(V) && " GEPs should have been stripped." );
6611
6621
if (isa<UndefValue>(V))
@@ -6652,7 +6662,7 @@ void AAMemoryLocationImpl::categorizePtrValue(
6652
6662
};
6653
6663
6654
6664
if (!genericValueTraversal<AAMemoryLocation, AAMemoryLocation::StateType>(
6655
- A, IRPosition::value (Ptr), *this , State, VisitValueCB,
6665
+ A, IRPosition::value (Ptr), *this , State, VisitValueCB, getCtxI (),
6656
6666
/* MaxValues */ 32 , StripGEPCB)) {
6657
6667
LLVM_DEBUG (
6658
6668
dbgs () << " [AAMemoryLocation] Pointer locations not categorized\n " );
@@ -7132,7 +7142,7 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
7132
7142
7133
7143
bool calculateBinaryOperator (
7134
7144
Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
7135
- Instruction *CtxI,
7145
+ const Instruction *CtxI,
7136
7146
SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
7137
7147
Value *LHS = BinOp->getOperand (0 );
7138
7148
Value *RHS = BinOp->getOperand (1 );
@@ -7160,7 +7170,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
7160
7170
}
7161
7171
7162
7172
bool calculateCastInst (
7163
- Attributor &A, CastInst *CastI, IntegerRangeState &T, Instruction *CtxI,
7173
+ Attributor &A, CastInst *CastI, IntegerRangeState &T,
7174
+ const Instruction *CtxI,
7164
7175
SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
7165
7176
assert (CastI->getNumOperands () == 1 && " Expected cast to be unary!" );
7166
7177
// TODO: Allow non integers as well.
@@ -7178,7 +7189,7 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
7178
7189
7179
7190
bool
7180
7191
calculateCmpInst (Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
7181
- Instruction *CtxI,
7192
+ const Instruction *CtxI,
7182
7193
SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
7183
7194
Value *LHS = CmpI->getOperand (0 );
7184
7195
Value *RHS = CmpI->getOperand (1 );
@@ -7233,9 +7244,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
7233
7244
7234
7245
// / See AbstractAttribute::updateImpl(...).
7235
7246
ChangeStatus updateImpl (Attributor &A) override {
7236
- Instruction *CtxI = getCtxI ();
7237
- auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
7238
- bool Stripped) -> bool {
7247
+ auto VisitValueCB = [&](Value &V, const Instruction *CtxI,
7248
+ IntegerRangeState &T, bool Stripped) -> bool {
7239
7249
Instruction *I = dyn_cast<Instruction>(&V);
7240
7250
if (!I || isa<CallBase>(I)) {
7241
7251
@@ -7285,7 +7295,7 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
7285
7295
IntegerRangeState T (getBitWidth ());
7286
7296
7287
7297
if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
7288
- A, getIRPosition (), *this , T, VisitValueCB))
7298
+ A, getIRPosition (), *this , T, VisitValueCB, getCtxI () ))
7289
7299
return indicatePessimisticFixpoint ();
7290
7300
7291
7301
return clampStateAndIndicateChange (getState (), T);
0 commit comments