@@ -584,7 +584,8 @@ struct AAComposeTwoGenericDeduction
584
584
585
585
// / See AbstractAttribute::updateImpl(...).
586
586
ChangeStatus updateImpl (Attributor &A) override {
587
- ChangeStatus ChangedF = F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl (A);
587
+ ChangeStatus ChangedF =
588
+ F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl (A);
588
589
ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl (A);
589
590
return ChangedF | ChangedG;
590
591
}
@@ -731,7 +732,7 @@ struct AAFromMustBeExecutedContext : public Base {
731
732
A.getInfoCache ().getMustBeExecutedContextExplorer ();
732
733
733
734
auto EIt = Explorer.begin (CtxI), EEnd = Explorer.end (CtxI);
734
- for (unsigned u = 0 ; u < Uses.size (); ++u) {
735
+ for (unsigned u = 0 ; u < Uses.size (); ++u) {
735
736
const Use *U = Uses[u];
736
737
if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser ())) {
737
738
bool Found = Explorer.findInContextOf (UserI, EIt, EEnd);
@@ -1524,6 +1525,138 @@ struct AANoFreeCallSite final : AANoFreeImpl {
1524
1525
void trackStatistics () const override { STATS_DECLTRACK_CS_ATTR (nofree); }
1525
1526
};
1526
1527
1528
+ // / NoFree attribute for floating values.
1529
+ struct AANoFreeFloating : AANoFreeImpl {
1530
+ AANoFreeFloating (const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1531
+
1532
+ // / See AbstractAttribute::trackStatistics()
1533
+ void trackStatistics () const override {STATS_DECLTRACK_FLOATING_ATTR (nofree)}
1534
+
1535
+ // / See Abstract Attribute::updateImpl(...).
1536
+ ChangeStatus updateImpl (Attributor &A) override {
1537
+ const IRPosition &IRP = getIRPosition ();
1538
+ Function *F = IRP.getAnchorScope ();
1539
+
1540
+ const AAIsDead &LivenessAA =
1541
+ A.getAAFor <AAIsDead>(*this , IRPosition::function (*F));
1542
+
1543
+ const auto &NoFreeAA =
1544
+ A.getAAFor <AANoFree>(*this , IRPosition::function_scope (IRP));
1545
+ if (NoFreeAA.isAssumedNoFree ())
1546
+ return ChangeStatus::UNCHANGED;
1547
+
1548
+ SmallPtrSet<const Use *, 8 > Visited;
1549
+ SmallVector<const Use *, 8 > Worklist;
1550
+
1551
+ Value &AssociatedValue = getIRPosition ().getAssociatedValue ();
1552
+ for (Use &U : AssociatedValue.uses ())
1553
+ Worklist.push_back (&U);
1554
+
1555
+ while (!Worklist.empty ()) {
1556
+ const Use *U = Worklist.pop_back_val ();
1557
+ if (!Visited.insert (U).second )
1558
+ continue ;
1559
+
1560
+ auto *UserI = U->getUser ();
1561
+ if (!UserI)
1562
+ continue ;
1563
+
1564
+ if (LivenessAA.isAssumedDead (cast<Instruction>(UserI)))
1565
+ continue ;
1566
+
1567
+ if (auto *CB = dyn_cast<CallBase>(UserI)) {
1568
+ if (CB->isBundleOperand (U))
1569
+ return indicatePessimisticFixpoint ();
1570
+ if (!CB->isArgOperand (U))
1571
+ continue ;
1572
+
1573
+ unsigned ArgNo = U - CB->arg_begin ();
1574
+
1575
+ const auto &NoFreeArg = A.getAAFor <AANoFree>(
1576
+ *this , IRPosition::callsite_argument (*CB, ArgNo));
1577
+
1578
+ if (NoFreeArg.isAssumedNoFree ())
1579
+ continue ;
1580
+
1581
+ return indicatePessimisticFixpoint ();
1582
+ }
1583
+
1584
+ if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1585
+ isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
1586
+ for (Use &U : UserI->uses ())
1587
+ Worklist.push_back (&U);
1588
+ continue ;
1589
+ }
1590
+
1591
+ // Unknown user.
1592
+ return indicatePessimisticFixpoint ();
1593
+ }
1594
+ return ChangeStatus::UNCHANGED;
1595
+ }
1596
+ };
1597
+
1598
+ // / NoFree attribute for a call site argument.
1599
+ struct AANoFreeArgument final : AANoFreeFloating {
1600
+ AANoFreeArgument (const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1601
+
1602
+ // / See AbstractAttribute::trackStatistics()
1603
+ void trackStatistics () const override { STATS_DECLTRACK_ARG_ATTR (nofree) }
1604
+ };
1605
+
1606
+ // / NoFree attribute for call site arguments.
1607
+ struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1608
+ AANoFreeCallSiteArgument (const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1609
+
1610
+ // / See AbstractAttribute::updateImpl(...).
1611
+ ChangeStatus updateImpl (Attributor &A) override {
1612
+ // TODO: Once we have call site specific value information we can provide
1613
+ // call site specific liveness information and then it makes
1614
+ // sense to specialize attributes for call sites arguments instead of
1615
+ // redirecting requests to the callee argument.
1616
+ Argument *Arg = getAssociatedArgument ();
1617
+ if (!Arg)
1618
+ return indicatePessimisticFixpoint ();
1619
+ const IRPosition &ArgPos = IRPosition::argument (*Arg);
1620
+ auto &ArgAA = A.getAAFor <AANoFree>(*this , ArgPos);
1621
+ return clampStateAndIndicateChange (
1622
+ getState (), static_cast <const AANoFree::StateType &>(ArgAA.getState ()));
1623
+ }
1624
+
1625
+ // / See AbstractAttribute::trackStatistics()
1626
+ void trackStatistics () const override {STATS_DECLTRACK_CSARG_ATTR (nofree)};
1627
+ };
1628
+
1629
+ // / NoFree attribute for function return value.
1630
+ struct AANoFreeReturned final : AANoFreeFloating {
1631
+ AANoFreeReturned (const IRPosition &IRP) : AANoFreeFloating(IRP) {
1632
+ llvm_unreachable (" NoFree is not applicable to function returns!" );
1633
+ }
1634
+
1635
+ // / See AbstractAttribute::initialize(...).
1636
+ void initialize (Attributor &A) override {
1637
+ llvm_unreachable (" NoFree is not applicable to function returns!" );
1638
+ }
1639
+
1640
+ // / See AbstractAttribute::updateImpl(...).
1641
+ ChangeStatus updateImpl (Attributor &A) override {
1642
+ llvm_unreachable (" NoFree is not applicable to function returns!" );
1643
+ }
1644
+
1645
+ // / See AbstractAttribute::trackStatistics()
1646
+ void trackStatistics () const override {}
1647
+ };
1648
+
1649
+ // / NoFree attribute deduction for a call site return value.
1650
+ struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1651
+ AANoFreeCallSiteReturned (const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1652
+
1653
+ ChangeStatus manifest (Attributor &A) override {
1654
+ return ChangeStatus::UNCHANGED;
1655
+ }
1656
+ // / See AbstractAttribute::trackStatistics()
1657
+ void trackStatistics () const override { STATS_DECLTRACK_CSRET_ATTR (nofree) }
1658
+ };
1659
+
1527
1660
// / ------------------------ NonNull Argument Attribute ------------------------
1528
1661
static int64_t getKnownNonNullAndDerefBytesForUse (
1529
1662
Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
@@ -1646,7 +1779,8 @@ struct AANonNullFloating
1646
1779
return Change;
1647
1780
1648
1781
if (!NullIsDefined) {
1649
- const auto &DerefAA = A.getAAFor <AADereferenceable>(*this , getIRPosition ());
1782
+ const auto &DerefAA =
1783
+ A.getAAFor <AADereferenceable>(*this , getIRPosition ());
1650
1784
if (DerefAA.getAssumedDereferenceableBytes ())
1651
1785
return Change;
1652
1786
}
@@ -3250,7 +3384,7 @@ struct AANoCaptureImpl : public AANoCapture {
3250
3384
// Check existing "returned" attributes.
3251
3385
int ArgNo = IRP.getArgNo ();
3252
3386
if (F.doesNotThrow () && ArgNo >= 0 ) {
3253
- for (unsigned u = 0 , e = F.arg_size (); u< e; ++u)
3387
+ for (unsigned u = 0 , e = F.arg_size (); u < e; ++u)
3254
3388
if (F.hasParamAttribute (u, Attribute::Returned)) {
3255
3389
if (u == unsigned (ArgNo))
3256
3390
State.removeAssumedBits (NOT_CAPTURED_IN_RET);
@@ -4053,7 +4187,7 @@ ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4053
4187
if (auto *Num = dyn_cast<ConstantInt>(I.getOperand (0 )))
4054
4188
if (auto *Size = dyn_cast<ConstantInt>(I.getOperand (1 )))
4055
4189
if ((Size->getValue ().umul_ov (Num->getValue (), Overflow))
4056
- .sle (MaxHeapToStackSize))
4190
+ .sle (MaxHeapToStackSize))
4057
4191
if (!Overflow && (UsesCheck (I) || FreeCheck (I))) {
4058
4192
MallocCalls.insert (&I);
4059
4193
return true ;
@@ -4244,7 +4378,6 @@ struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4244
4378
return AAMemoryBehaviorFloating::manifest (A);
4245
4379
}
4246
4380
4247
-
4248
4381
// / See AbstractAttribute::trackStatistics()
4249
4382
void trackStatistics () const override {
4250
4383
if (isAssumedReadNone ())
@@ -4654,8 +4787,7 @@ bool Attributor::checkForAllCallSites(
4654
4787
for (const Use &U : Fn.uses ()) {
4655
4788
AbstractCallSite ACS (&U);
4656
4789
if (!ACS) {
4657
- LLVM_DEBUG (dbgs () << " [Attributor] Function "
4658
- << Fn.getName ()
4790
+ LLVM_DEBUG (dbgs () << " [Attributor] Function " << Fn.getName ()
4659
4791
<< " has non call site use " << *U.get () << " in "
4660
4792
<< *U.getUser () << " \n " );
4661
4793
// BlockAddress users are allowed.
@@ -4669,7 +4801,7 @@ bool Attributor::checkForAllCallSites(
4669
4801
4670
4802
const auto *LivenessAA =
4671
4803
lookupAAFor<AAIsDead>(IRPosition::function (*Caller), QueryingAA,
4672
- /* TrackDependence */ false );
4804
+ /* TrackDependence */ false );
4673
4805
4674
4806
// Skip dead calls.
4675
4807
if (LivenessAA && LivenessAA->isAssumedDead (I)) {
@@ -4686,8 +4818,7 @@ bool Attributor::checkForAllCallSites(
4686
4818
if (!RequireAllCallSites)
4687
4819
continue ;
4688
4820
LLVM_DEBUG (dbgs () << " [Attributor] User " << EffectiveUse->getUser ()
4689
- << " is an invalid use of "
4690
- << Fn.getName () << " \n " );
4821
+ << " is an invalid use of " << Fn.getName () << " \n " );
4691
4822
return false ;
4692
4823
}
4693
4824
@@ -5006,7 +5137,8 @@ ChangeStatus Attributor::run(Module &M) {
5006
5137
<< " instead of " << *OldV << " \n " );
5007
5138
U->set (NewV);
5008
5139
if (Instruction *I = dyn_cast<Instruction>(OldV))
5009
- if (!isa<PHINode>(I) && !ToBeDeletedInsts.count (I) && isInstructionTriviallyDead (I)) {
5140
+ if (!isa<PHINode>(I) && !ToBeDeletedInsts.count (I) &&
5141
+ isInstructionTriviallyDead (I)) {
5010
5142
DeadInsts.push_back (I);
5011
5143
}
5012
5144
if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser ())) {
@@ -5242,6 +5374,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
5242
5374
// Every argument with pointer type might be marked
5243
5375
// "readnone/readonly/writeonly/..."
5244
5376
getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
5377
+
5378
+ // Every argument with pointer type might be marked nofree.
5379
+ getOrCreateAAFor<AANoFree>(ArgPos);
5245
5380
}
5246
5381
}
5247
5382
@@ -5284,6 +5419,9 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
5284
5419
5285
5420
// Call site argument attribute "align".
5286
5421
getOrCreateAAFor<AAAlign>(CSArgPos);
5422
+
5423
+ // Call site argument attribute "nofree".
5424
+ getOrCreateAAFor<AANoFree>(CSArgPos);
5287
5425
}
5288
5426
}
5289
5427
return true ;
@@ -5564,7 +5702,6 @@ const char AAMemoryBehavior::ID = 0;
5564
5702
5565
5703
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoUnwind)
5566
5704
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoSync)
5567
- CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoFree)
5568
5705
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoRecurse)
5569
5706
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAWillReturn)
5570
5707
CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoReturn)
@@ -5578,6 +5715,7 @@ CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
5578
5715
5579
5716
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAValueSimplify)
5580
5717
CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAIsDead)
5718
+ CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION (AANoFree)
5581
5719
5582
5720
CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION (AAHeapToStack)
5583
5721
0 commit comments