1 //===- Attributor.cpp - Module-wide attribute deduction -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements an inter procedural pass that deduces and/or propagating
10 // attributes. This is done in an abstract interpretation style fixpoint
11 // iteration. See the Attributor.h file comment and the class descriptions in
12 // that file for more information.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/Transforms/IPO/Attributor.h"
18 #include "llvm/ADT/DepthFirstIterator.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Analysis/CaptureTracking.h"
24 #include "llvm/Analysis/EHPersonalities.h"
25 #include "llvm/Analysis/GlobalsModRef.h"
26 #include "llvm/Analysis/Loads.h"
27 #include "llvm/Analysis/MemoryBuiltins.h"
28 #include "llvm/Analysis/ValueTracking.h"
29 #include "llvm/IR/Argument.h"
30 #include "llvm/IR/Attributes.h"
31 #include "llvm/IR/CFG.h"
32 #include "llvm/IR/InstIterator.h"
33 #include "llvm/IR/IntrinsicInst.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Debug.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
38 #include "llvm/Transforms/Utils/Local.h"
44 #define DEBUG_TYPE "attributor"
46 STATISTIC(NumFnWithExactDefinition
,
47 "Number of function with exact definitions");
48 STATISTIC(NumFnWithoutExactDefinition
,
49 "Number of function without exact definitions");
50 STATISTIC(NumAttributesTimedOut
,
51 "Number of abstract attributes timed out before fixpoint");
52 STATISTIC(NumAttributesValidFixpoint
,
53 "Number of abstract attributes in a valid fixpoint state");
54 STATISTIC(NumAttributesManifested
,
55 "Number of abstract attributes manifested in IR");
57 // Some helper macros to deal with statistics tracking.
60 // For simple IR attribute tracking overload trackStatistics in the abstract
61 // attribute and choose the right STATS_DECLTRACK_********* macro,
63 // void trackStatistics() const override {
64 // STATS_DECLTRACK_ARG_ATTR(returned)
66 // If there is a single "increment" side one can use the macro
67 // STATS_DECLTRACK with a custom message. If there are multiple increment
68 // sides, STATS_DECL and STATS_TRACK can also be used separatly.
70 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
71 ("Number of " #TYPE " marked '" #NAME "'")
72 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
73 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
74 #define STATS_DECL(NAME, TYPE, MSG) \
75 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
76 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
77 #define STATS_DECLTRACK(NAME, TYPE, MSG) \
79 STATS_DECL(NAME, TYPE, MSG) \
80 STATS_TRACK(NAME, TYPE) \
82 #define STATS_DECLTRACK_ARG_ATTR(NAME) \
83 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
84 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \
85 STATS_DECLTRACK(NAME, CSArguments, \
86 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
87 #define STATS_DECLTRACK_FN_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
89 #define STATS_DECLTRACK_CS_ATTR(NAME) \
90 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
91 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \
92 STATS_DECLTRACK(NAME, FunctionReturn, \
93 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
94 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, CSReturn, \
96 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
97 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, Floating, \
99 ("Number of floating values known to be '" #NAME "'"))
101 // TODO: Determine a good default value.
103 // In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
104 // (when run with the first 5 abstract attributes). The results also indicate
105 // that we never reach 32 iterations but always find a fixpoint sooner.
107 // This will become more evolved once we perform two interleaved fixpoint
108 // iterations: bottom-up and top-down.
109 static cl::opt
<unsigned>
110 MaxFixpointIterations("attributor-max-iterations", cl::Hidden
,
111 cl::desc("Maximal number of fixpoint iterations."),
113 static cl::opt
<bool> VerifyMaxFixpointIterations(
114 "attributor-max-iterations-verify", cl::Hidden
,
115 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
118 static cl::opt
<bool> DisableAttributor(
119 "attributor-disable", cl::Hidden
,
120 cl::desc("Disable the attributor inter-procedural deduction pass."),
123 static cl::opt
<bool> ManifestInternal(
124 "attributor-manifest-internal", cl::Hidden
,
125 cl::desc("Manifest Attributor internal string attributes."),
128 static cl::opt
<bool> VerifyAttributor(
129 "attributor-verify", cl::Hidden
,
130 cl::desc("Verify the Attributor deduction and "
131 "manifestation of attributes -- may issue false-positive errors"),
134 static cl::opt
<unsigned> DepRecInterval(
135 "attributor-dependence-recompute-interval", cl::Hidden
,
136 cl::desc("Number of iterations until dependences are recomputed."),
139 static cl::opt
<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
140 cl::init(true), cl::Hidden
);
142 static cl::opt
<int> MaxHeapToStackSize("max-heap-to-stack-size",
143 cl::init(128), cl::Hidden
);
145 /// Logic operators for the change status enum class.
148 ChangeStatus
llvm::operator|(ChangeStatus l
, ChangeStatus r
) {
149 return l
== ChangeStatus::CHANGED
? l
: r
;
151 ChangeStatus
llvm::operator&(ChangeStatus l
, ChangeStatus r
) {
152 return l
== ChangeStatus::UNCHANGED
? l
: r
;
156 /// Recursively visit all values that might become \p IRP at some point. This
157 /// will be done by looking through cast instructions, selects, phis, and calls
158 /// with the "returned" attribute. Once we cannot look through the value any
159 /// further, the callback \p VisitValueCB is invoked and passed the current
160 /// value, the \p State, and a flag to indicate if we stripped anything. To
161 /// limit how much effort is invested, we will never visit more values than
162 /// specified by \p MaxValues.
163 template <typename AAType
, typename StateTy
>
164 static bool genericValueTraversal(
165 Attributor
&A
, IRPosition IRP
, const AAType
&QueryingAA
, StateTy
&State
,
166 const function_ref
<bool(Value
&, StateTy
&, bool)> &VisitValueCB
,
169 const AAIsDead
*LivenessAA
= nullptr;
170 if (IRP
.getAnchorScope())
171 LivenessAA
= &A
.getAAFor
<AAIsDead
>(
172 QueryingAA
, IRPosition::function(*IRP
.getAnchorScope()),
173 /* TrackDependence */ false);
174 bool AnyDead
= false;
176 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
177 SmallPtrSet
<Value
*, 16> Visited
;
178 SmallVector
<Value
*, 16> Worklist
;
179 Worklist
.push_back(&IRP
.getAssociatedValue());
183 Value
*V
= Worklist
.pop_back_val();
185 // Check if we should process the current value. To prevent endless
186 // recursion keep a record of the values we followed!
187 if (!Visited
.insert(V
).second
)
190 // Make sure we limit the compile time for complex expressions.
191 if (Iteration
++ >= MaxValues
)
194 // Explicitly look through calls with a "returned" attribute if we do
195 // not have a pointer as stripPointerCasts only works on them.
196 Value
*NewV
= nullptr;
197 if (V
->getType()->isPointerTy()) {
198 NewV
= V
->stripPointerCasts();
201 if (CS
&& CS
.getCalledFunction()) {
202 for (Argument
&Arg
: CS
.getCalledFunction()->args())
203 if (Arg
.hasReturnedAttr()) {
204 NewV
= CS
.getArgOperand(Arg
.getArgNo());
209 if (NewV
&& NewV
!= V
) {
210 Worklist
.push_back(NewV
);
214 // Look through select instructions, visit both potential values.
215 if (auto *SI
= dyn_cast
<SelectInst
>(V
)) {
216 Worklist
.push_back(SI
->getTrueValue());
217 Worklist
.push_back(SI
->getFalseValue());
221 // Look through phi nodes, visit all live operands.
222 if (auto *PHI
= dyn_cast
<PHINode
>(V
)) {
224 "Expected liveness in the presence of instructions!");
225 for (unsigned u
= 0, e
= PHI
->getNumIncomingValues(); u
< e
; u
++) {
226 const BasicBlock
*IncomingBB
= PHI
->getIncomingBlock(u
);
227 if (LivenessAA
->isAssumedDead(IncomingBB
->getTerminator())) {
231 Worklist
.push_back(PHI
->getIncomingValue(u
));
236 // Once a leaf is reached we inform the user through the callback.
237 if (!VisitValueCB(*V
, State
, Iteration
> 1))
239 } while (!Worklist
.empty());
241 // If we actually used liveness information so we have to record a dependence.
243 A
.recordDependence(*LivenessAA
, QueryingAA
);
245 // All values have been visited.
249 /// Return true if \p New is equal or worse than \p Old.
250 static bool isEqualOrWorse(const Attribute
&New
, const Attribute
&Old
) {
251 if (!Old
.isIntAttribute())
254 return Old
.getValueAsInt() >= New
.getValueAsInt();
257 /// Return true if the information provided by \p Attr was added to the
258 /// attribute list \p Attrs. This is only the case if it was not already present
259 /// in \p Attrs at the position describe by \p PK and \p AttrIdx.
260 static bool addIfNotExistent(LLVMContext
&Ctx
, const Attribute
&Attr
,
261 AttributeList
&Attrs
, int AttrIdx
) {
263 if (Attr
.isEnumAttribute()) {
264 Attribute::AttrKind Kind
= Attr
.getKindAsEnum();
265 if (Attrs
.hasAttribute(AttrIdx
, Kind
))
266 if (isEqualOrWorse(Attr
, Attrs
.getAttribute(AttrIdx
, Kind
)))
268 Attrs
= Attrs
.addAttribute(Ctx
, AttrIdx
, Attr
);
271 if (Attr
.isStringAttribute()) {
272 StringRef Kind
= Attr
.getKindAsString();
273 if (Attrs
.hasAttribute(AttrIdx
, Kind
))
274 if (isEqualOrWorse(Attr
, Attrs
.getAttribute(AttrIdx
, Kind
)))
276 Attrs
= Attrs
.addAttribute(Ctx
, AttrIdx
, Attr
);
279 if (Attr
.isIntAttribute()) {
280 Attribute::AttrKind Kind
= Attr
.getKindAsEnum();
281 if (Attrs
.hasAttribute(AttrIdx
, Kind
))
282 if (isEqualOrWorse(Attr
, Attrs
.getAttribute(AttrIdx
, Kind
)))
284 Attrs
= Attrs
.removeAttribute(Ctx
, AttrIdx
, Kind
);
285 Attrs
= Attrs
.addAttribute(Ctx
, AttrIdx
, Attr
);
289 llvm_unreachable("Expected enum or string attribute!");
292 ChangeStatus
AbstractAttribute::update(Attributor
&A
) {
293 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
294 if (getState().isAtFixpoint())
297 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
299 HasChanged
= updateImpl(A
);
301 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged
<< " " << *this
308 IRAttributeManifest::manifestAttrs(Attributor
&A
, IRPosition
&IRP
,
309 const ArrayRef
<Attribute
> &DeducedAttrs
) {
310 Function
*ScopeFn
= IRP
.getAssociatedFunction();
311 IRPosition::Kind PK
= IRP
.getPositionKind();
313 // In the following some generic code that will manifest attributes in
314 // DeducedAttrs if they improve the current IR. Due to the different
315 // annotation positions we use the underlying AttributeList interface.
319 case IRPosition::IRP_INVALID
:
320 case IRPosition::IRP_FLOAT
:
321 return ChangeStatus::UNCHANGED
;
322 case IRPosition::IRP_ARGUMENT
:
323 case IRPosition::IRP_FUNCTION
:
324 case IRPosition::IRP_RETURNED
:
325 Attrs
= ScopeFn
->getAttributes();
327 case IRPosition::IRP_CALL_SITE
:
328 case IRPosition::IRP_CALL_SITE_RETURNED
:
329 case IRPosition::IRP_CALL_SITE_ARGUMENT
:
330 Attrs
= ImmutableCallSite(&IRP
.getAnchorValue()).getAttributes();
334 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
335 LLVMContext
&Ctx
= IRP
.getAnchorValue().getContext();
336 for (const Attribute
&Attr
: DeducedAttrs
) {
337 if (!addIfNotExistent(Ctx
, Attr
, Attrs
, IRP
.getAttrIdx()))
340 HasChanged
= ChangeStatus::CHANGED
;
343 if (HasChanged
== ChangeStatus::UNCHANGED
)
347 case IRPosition::IRP_ARGUMENT
:
348 case IRPosition::IRP_FUNCTION
:
349 case IRPosition::IRP_RETURNED
:
350 ScopeFn
->setAttributes(Attrs
);
352 case IRPosition::IRP_CALL_SITE
:
353 case IRPosition::IRP_CALL_SITE_RETURNED
:
354 case IRPosition::IRP_CALL_SITE_ARGUMENT
:
355 CallSite(&IRP
.getAnchorValue()).setAttributes(Attrs
);
357 case IRPosition::IRP_INVALID
:
358 case IRPosition::IRP_FLOAT
:
365 const IRPosition
IRPosition::EmptyKey(255);
366 const IRPosition
IRPosition::TombstoneKey(256);
368 SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition
&IRP
) {
369 IRPositions
.emplace_back(IRP
);
371 ImmutableCallSite
ICS(&IRP
.getAnchorValue());
372 switch (IRP
.getPositionKind()) {
373 case IRPosition::IRP_INVALID
:
374 case IRPosition::IRP_FLOAT
:
375 case IRPosition::IRP_FUNCTION
:
377 case IRPosition::IRP_ARGUMENT
:
378 case IRPosition::IRP_RETURNED
:
379 IRPositions
.emplace_back(
380 IRPosition::function(*IRP
.getAssociatedFunction()));
382 case IRPosition::IRP_CALL_SITE
:
383 assert(ICS
&& "Expected call site!");
384 // TODO: We need to look at the operand bundles similar to the redirection
386 if (!ICS
.hasOperandBundles())
387 if (const Function
*Callee
= ICS
.getCalledFunction())
388 IRPositions
.emplace_back(IRPosition::function(*Callee
));
390 case IRPosition::IRP_CALL_SITE_RETURNED
:
391 assert(ICS
&& "Expected call site!");
392 // TODO: We need to look at the operand bundles similar to the redirection
394 if (!ICS
.hasOperandBundles()) {
395 if (const Function
*Callee
= ICS
.getCalledFunction()) {
396 IRPositions
.emplace_back(IRPosition::returned(*Callee
));
397 IRPositions
.emplace_back(IRPosition::function(*Callee
));
400 IRPositions
.emplace_back(
401 IRPosition::callsite_function(cast
<CallBase
>(*ICS
.getInstruction())));
403 case IRPosition::IRP_CALL_SITE_ARGUMENT
: {
404 int ArgNo
= IRP
.getArgNo();
405 assert(ICS
&& ArgNo
>= 0 && "Expected call site!");
406 // TODO: We need to look at the operand bundles similar to the redirection
408 if (!ICS
.hasOperandBundles()) {
409 const Function
*Callee
= ICS
.getCalledFunction();
410 if (Callee
&& Callee
->arg_size() > unsigned(ArgNo
))
411 IRPositions
.emplace_back(IRPosition::argument(*Callee
->getArg(ArgNo
)));
413 IRPositions
.emplace_back(IRPosition::function(*Callee
));
415 IRPositions
.emplace_back(IRPosition::value(IRP
.getAssociatedValue()));
421 bool IRPosition::hasAttr(ArrayRef
<Attribute::AttrKind
> AKs
) const {
422 for (const IRPosition
&EquivIRP
: SubsumingPositionIterator(*this))
423 for (Attribute::AttrKind AK
: AKs
)
424 if (EquivIRP
.getAttr(AK
).getKindAsEnum() == AK
)
429 void IRPosition::getAttrs(ArrayRef
<Attribute::AttrKind
> AKs
,
430 SmallVectorImpl
<Attribute
> &Attrs
) const {
431 for (const IRPosition
&EquivIRP
: SubsumingPositionIterator(*this))
432 for (Attribute::AttrKind AK
: AKs
) {
433 const Attribute
&Attr
= EquivIRP
.getAttr(AK
);
434 if (Attr
.getKindAsEnum() == AK
)
435 Attrs
.push_back(Attr
);
439 void IRPosition::verify() {
440 switch (KindOrArgNo
) {
442 assert(KindOrArgNo
>= 0 && "Expected argument or call site argument!");
443 assert((isa
<CallBase
>(AnchorVal
) || isa
<Argument
>(AnchorVal
)) &&
444 "Expected call base or argument for positive attribute index!");
445 if (isa
<Argument
>(AnchorVal
)) {
446 assert(cast
<Argument
>(AnchorVal
)->getArgNo() == unsigned(getArgNo()) &&
447 "Argument number mismatch!");
448 assert(cast
<Argument
>(AnchorVal
) == &getAssociatedValue() &&
449 "Associated value mismatch!");
451 assert(cast
<CallBase
>(*AnchorVal
).arg_size() > unsigned(getArgNo()) &&
452 "Call site argument number mismatch!");
453 assert(cast
<CallBase
>(*AnchorVal
).getArgOperand(getArgNo()) ==
454 &getAssociatedValue() &&
455 "Associated value mismatch!");
459 assert(!AnchorVal
&& "Expected no value for an invalid position!");
462 assert((!isa
<CallBase
>(&getAssociatedValue()) &&
463 !isa
<Argument
>(&getAssociatedValue())) &&
464 "Expected specialized kind for call base and argument values!");
467 assert(isa
<Function
>(AnchorVal
) &&
468 "Expected function for a 'returned' position!");
469 assert(AnchorVal
== &getAssociatedValue() && "Associated value mismatch!");
471 case IRP_CALL_SITE_RETURNED
:
472 assert((isa
<CallBase
>(AnchorVal
)) &&
473 "Expected call base for 'call site returned' position!");
474 assert(AnchorVal
== &getAssociatedValue() && "Associated value mismatch!");
477 assert((isa
<CallBase
>(AnchorVal
)) &&
478 "Expected call base for 'call site function' position!");
479 assert(AnchorVal
== &getAssociatedValue() && "Associated value mismatch!");
482 assert(isa
<Function
>(AnchorVal
) &&
483 "Expected function for a 'function' position!");
484 assert(AnchorVal
== &getAssociatedValue() && "Associated value mismatch!");
490 /// Helper functions to clamp a state \p S of type \p StateType with the
491 /// information in \p R and indicate/return if \p S did change (as-in update is
492 /// required to be run again).
495 template <typename StateType
>
496 ChangeStatus
clampStateAndIndicateChange(StateType
&S
, const StateType
&R
);
499 ChangeStatus clampStateAndIndicateChange
<IntegerState
>(IntegerState
&S
,
500 const IntegerState
&R
) {
501 auto Assumed
= S
.getAssumed();
503 return Assumed
== S
.getAssumed() ? ChangeStatus::UNCHANGED
504 : ChangeStatus::CHANGED
;
508 ChangeStatus clampStateAndIndicateChange
<BooleanState
>(BooleanState
&S
,
509 const BooleanState
&R
) {
510 return clampStateAndIndicateChange
<IntegerState
>(S
, R
);
514 /// Clamp the information known for all returned values of a function
515 /// (identified by \p QueryingAA) into \p S.
516 template <typename AAType
, typename StateType
= typename
AAType::StateType
>
517 static void clampReturnedValueStates(Attributor
&A
, const AAType
&QueryingAA
,
519 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
520 << static_cast<const AbstractAttribute
&>(QueryingAA
)
521 << " into " << S
<< "\n");
523 assert((QueryingAA
.getIRPosition().getPositionKind() ==
524 IRPosition::IRP_RETURNED
||
525 QueryingAA
.getIRPosition().getPositionKind() ==
526 IRPosition::IRP_CALL_SITE_RETURNED
) &&
527 "Can only clamp returned value states for a function returned or call "
528 "site returned position!");
530 // Use an optional state as there might not be any return values and we want
531 // to join (IntegerState::operator&) the state of all there are.
532 Optional
<StateType
> T
;
534 // Callback for each possibly returned value.
535 auto CheckReturnValue
= [&](Value
&RV
) -> bool {
536 const IRPosition
&RVPos
= IRPosition::value(RV
);
537 const AAType
&AA
= A
.getAAFor
<AAType
>(QueryingAA
, RVPos
);
538 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
<< " AA: " << AA
.getAsStr()
539 << " @ " << RVPos
<< "\n");
540 const StateType
&AAS
= static_cast<const StateType
&>(AA
.getState());
545 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS
<< " RV State: " << T
547 return T
->isValidState();
550 if (!A
.checkForAllReturnedValues(CheckReturnValue
, QueryingAA
))
551 S
.indicatePessimisticFixpoint();
552 else if (T
.hasValue())
556 /// Helper class for generic deduction: return value -> returned position.
557 template <typename AAType
, typename Base
,
558 typename StateType
= typename
AAType::StateType
>
559 struct AAReturnedFromReturnedValues
: public Base
{
560 AAReturnedFromReturnedValues(const IRPosition
&IRP
) : Base(IRP
) {}
562 /// See AbstractAttribute::updateImpl(...).
563 ChangeStatus
updateImpl(Attributor
&A
) override
{
565 clampReturnedValueStates
<AAType
, StateType
>(A
, *this, S
);
566 // TODO: If we know we visited all returned values, thus no are assumed
567 // dead, we can take the known information from the state T.
568 return clampStateAndIndicateChange
<StateType
>(this->getState(), S
);
572 /// Clamp the information known at all call sites for a given argument
573 /// (identified by \p QueryingAA) into \p S.
574 template <typename AAType
, typename StateType
= typename
AAType::StateType
>
575 static void clampCallSiteArgumentStates(Attributor
&A
, const AAType
&QueryingAA
,
577 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
578 << static_cast<const AbstractAttribute
&>(QueryingAA
)
579 << " into " << S
<< "\n");
581 assert(QueryingAA
.getIRPosition().getPositionKind() ==
582 IRPosition::IRP_ARGUMENT
&&
583 "Can only clamp call site argument states for an argument position!");
585 // Use an optional state as there might not be any return values and we want
586 // to join (IntegerState::operator&) the state of all there are.
587 Optional
<StateType
> T
;
589 // The argument number which is also the call site argument number.
590 unsigned ArgNo
= QueryingAA
.getIRPosition().getArgNo();
592 auto CallSiteCheck
= [&](CallSite CS
) {
593 const IRPosition
&CSArgPos
= IRPosition::callsite_argument(CS
, ArgNo
);
594 const AAType
&AA
= A
.getAAFor
<AAType
>(QueryingAA
, CSArgPos
);
595 LLVM_DEBUG(dbgs() << "[Attributor] CS: " << *CS
.getInstruction()
596 << " AA: " << AA
.getAsStr() << " @" << CSArgPos
<< "\n");
597 const StateType
&AAS
= static_cast<const StateType
&>(AA
.getState());
602 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS
<< " CSA State: " << T
604 return T
->isValidState();
607 if (!A
.checkForAllCallSites(CallSiteCheck
, QueryingAA
, true))
608 S
.indicatePessimisticFixpoint();
609 else if (T
.hasValue())
613 /// Helper class for generic deduction: call site argument -> argument position.
614 template <typename AAType
, typename Base
,
615 typename StateType
= typename
AAType::StateType
>
616 struct AAArgumentFromCallSiteArguments
: public Base
{
617 AAArgumentFromCallSiteArguments(const IRPosition
&IRP
) : Base(IRP
) {}
619 /// See AbstractAttribute::updateImpl(...).
620 ChangeStatus
updateImpl(Attributor
&A
) override
{
622 clampCallSiteArgumentStates
<AAType
, StateType
>(A
, *this, S
);
623 // TODO: If we know we visited all incoming values, thus no are assumed
624 // dead, we can take the known information from the state T.
625 return clampStateAndIndicateChange
<StateType
>(this->getState(), S
);
629 /// Helper class for generic replication: function returned -> cs returned.
630 template <typename AAType
, typename Base
>
631 struct AACallSiteReturnedFromReturned
: public Base
{
632 AACallSiteReturnedFromReturned(const IRPosition
&IRP
) : Base(IRP
) {}
634 /// See AbstractAttribute::updateImpl(...).
635 ChangeStatus
updateImpl(Attributor
&A
) override
{
636 assert(this->getIRPosition().getPositionKind() ==
637 IRPosition::IRP_CALL_SITE_RETURNED
&&
638 "Can only wrap function returned positions for call site returned "
640 auto &S
= this->getState();
642 const Function
*AssociatedFunction
=
643 this->getIRPosition().getAssociatedFunction();
644 if (!AssociatedFunction
)
645 return S
.indicatePessimisticFixpoint();
647 IRPosition FnPos
= IRPosition::returned(*AssociatedFunction
);
648 const AAType
&AA
= A
.getAAFor
<AAType
>(*this, FnPos
);
649 return clampStateAndIndicateChange(
650 S
, static_cast<const typename
AAType::StateType
&>(AA
.getState()));
654 /// -----------------------NoUnwind Function Attribute--------------------------
656 struct AANoUnwindImpl
: AANoUnwind
{
657 AANoUnwindImpl(const IRPosition
&IRP
) : AANoUnwind(IRP
) {}
659 const std::string
getAsStr() const override
{
660 return getAssumed() ? "nounwind" : "may-unwind";
663 /// See AbstractAttribute::updateImpl(...).
664 ChangeStatus
updateImpl(Attributor
&A
) override
{
666 (unsigned)Instruction::Invoke
, (unsigned)Instruction::CallBr
,
667 (unsigned)Instruction::Call
, (unsigned)Instruction::CleanupRet
,
668 (unsigned)Instruction::CatchSwitch
, (unsigned)Instruction::Resume
};
670 auto CheckForNoUnwind
= [&](Instruction
&I
) {
674 if (ImmutableCallSite ICS
= ImmutableCallSite(&I
)) {
675 const auto &NoUnwindAA
=
676 A
.getAAFor
<AANoUnwind
>(*this, IRPosition::callsite_function(ICS
));
677 return NoUnwindAA
.isAssumedNoUnwind();
682 if (!A
.checkForAllInstructions(CheckForNoUnwind
, *this, Opcodes
))
683 return indicatePessimisticFixpoint();
685 return ChangeStatus::UNCHANGED
;
689 struct AANoUnwindFunction final
: public AANoUnwindImpl
{
690 AANoUnwindFunction(const IRPosition
&IRP
) : AANoUnwindImpl(IRP
) {}
692 /// See AbstractAttribute::trackStatistics()
693 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nounwind
) }
696 /// NoUnwind attribute deduction for a call sites.
697 struct AANoUnwindCallSite final
: AANoUnwindImpl
{
698 AANoUnwindCallSite(const IRPosition
&IRP
) : AANoUnwindImpl(IRP
) {}
700 /// See AbstractAttribute::initialize(...).
701 void initialize(Attributor
&A
) override
{
702 AANoUnwindImpl::initialize(A
);
703 Function
*F
= getAssociatedFunction();
705 indicatePessimisticFixpoint();
708 /// See AbstractAttribute::updateImpl(...).
709 ChangeStatus
updateImpl(Attributor
&A
) override
{
710 // TODO: Once we have call site specific value information we can provide
711 // call site specific liveness information and then it makes
712 // sense to specialize attributes for call sites arguments instead of
713 // redirecting requests to the callee argument.
714 Function
*F
= getAssociatedFunction();
715 const IRPosition
&FnPos
= IRPosition::function(*F
);
716 auto &FnAA
= A
.getAAFor
<AANoUnwind
>(*this, FnPos
);
717 return clampStateAndIndicateChange(
719 static_cast<const AANoUnwind::StateType
&>(FnAA
.getState()));
722 /// See AbstractAttribute::trackStatistics()
723 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nounwind
); }
726 /// --------------------- Function Return Values -------------------------------
728 /// "Attribute" that collects all potential returned values and the return
729 /// instructions that they arise from.
731 /// If there is a unique returned value R, the manifest method will:
732 /// - mark R with the "returned" attribute, if R is an argument.
733 class AAReturnedValuesImpl
: public AAReturnedValues
, public AbstractState
{
735 /// Mapping of values potentially returned by the associated function to the
736 /// return instructions that might return them.
737 MapVector
<Value
*, SmallSetVector
<ReturnInst
*, 4>> ReturnedValues
;
739 /// Mapping to remember the number of returned values for a call site such
740 /// that we can avoid updates if nothing changed.
741 DenseMap
<const CallBase
*, unsigned> NumReturnedValuesPerKnownAA
;
743 /// Set of unresolved calls returned by the associated function.
744 SmallSetVector
<CallBase
*, 4> UnresolvedCalls
;
749 bool IsFixed
= false;
750 bool IsValidState
= true;
754 AAReturnedValuesImpl(const IRPosition
&IRP
) : AAReturnedValues(IRP
) {}
756 /// See AbstractAttribute::initialize(...).
757 void initialize(Attributor
&A
) override
{
761 ReturnedValues
.clear();
763 Function
*F
= getAssociatedFunction();
765 indicatePessimisticFixpoint();
769 // The map from instruction opcodes to those instructions in the function.
770 auto &OpcodeInstMap
= A
.getInfoCache().getOpcodeInstMapForFunction(*F
);
772 // Look through all arguments, if one is marked as returned we are done.
773 for (Argument
&Arg
: F
->args()) {
774 if (Arg
.hasReturnedAttr()) {
775 auto &ReturnInstSet
= ReturnedValues
[&Arg
];
776 for (Instruction
*RI
: OpcodeInstMap
[Instruction::Ret
])
777 ReturnInstSet
.insert(cast
<ReturnInst
>(RI
));
779 indicateOptimisticFixpoint();
784 if (!F
->hasExactDefinition())
785 indicatePessimisticFixpoint();
788 /// See AbstractAttribute::manifest(...).
789 ChangeStatus
manifest(Attributor
&A
) override
;
791 /// See AbstractAttribute::getState(...).
792 AbstractState
&getState() override
{ return *this; }
794 /// See AbstractAttribute::getState(...).
795 const AbstractState
&getState() const override
{ return *this; }
797 /// See AbstractAttribute::updateImpl(Attributor &A).
798 ChangeStatus
updateImpl(Attributor
&A
) override
;
800 llvm::iterator_range
<iterator
> returned_values() override
{
801 return llvm::make_range(ReturnedValues
.begin(), ReturnedValues
.end());
804 llvm::iterator_range
<const_iterator
> returned_values() const override
{
805 return llvm::make_range(ReturnedValues
.begin(), ReturnedValues
.end());
808 const SmallSetVector
<CallBase
*, 4> &getUnresolvedCalls() const override
{
809 return UnresolvedCalls
;
812 /// Return the number of potential return values, -1 if unknown.
813 size_t getNumReturnValues() const override
{
814 return isValidState() ? ReturnedValues
.size() : -1;
817 /// Return an assumed unique return value if a single candidate is found. If
818 /// there cannot be one, return a nullptr. If it is not clear yet, return the
819 /// Optional::NoneType.
820 Optional
<Value
*> getAssumedUniqueReturnValue(Attributor
&A
) const;
822 /// See AbstractState::checkForAllReturnedValues(...).
823 bool checkForAllReturnedValuesAndReturnInsts(
824 const function_ref
<bool(Value
&, const SmallSetVector
<ReturnInst
*, 4> &)>
825 &Pred
) const override
;
827 /// Pretty print the attribute similar to the IR representation.
828 const std::string
getAsStr() const override
;
830 /// See AbstractState::isAtFixpoint().
831 bool isAtFixpoint() const override
{ return IsFixed
; }
833 /// See AbstractState::isValidState().
834 bool isValidState() const override
{ return IsValidState
; }
836 /// See AbstractState::indicateOptimisticFixpoint(...).
837 ChangeStatus
indicateOptimisticFixpoint() override
{
839 return ChangeStatus::UNCHANGED
;
842 ChangeStatus
indicatePessimisticFixpoint() override
{
844 IsValidState
= false;
845 return ChangeStatus::CHANGED
;
849 ChangeStatus
AAReturnedValuesImpl::manifest(Attributor
&A
) {
850 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
853 assert(isValidState());
854 STATS_DECLTRACK(KnownReturnValues
, FunctionReturn
,
855 "Number of function with known return values");
857 // Check if we have an assumed unique return value that we could manifest.
858 Optional
<Value
*> UniqueRV
= getAssumedUniqueReturnValue(A
);
860 if (!UniqueRV
.hasValue() || !UniqueRV
.getValue())
864 STATS_DECLTRACK(UniqueReturnValue
, FunctionReturn
,
865 "Number of function with unique return");
867 // Callback to replace the uses of CB with the constant C.
868 auto ReplaceCallSiteUsersWith
= [](CallBase
&CB
, Constant
&C
) {
869 if (CB
.getNumUses() == 0)
870 return ChangeStatus::UNCHANGED
;
871 CB
.replaceAllUsesWith(&C
);
872 return ChangeStatus::CHANGED
;
875 // If the assumed unique return value is an argument, annotate it.
876 if (auto *UniqueRVArg
= dyn_cast
<Argument
>(UniqueRV
.getValue())) {
877 getIRPosition() = IRPosition::argument(*UniqueRVArg
);
878 Changed
= IRAttribute::manifest(A
);
879 } else if (auto *RVC
= dyn_cast
<Constant
>(UniqueRV
.getValue())) {
880 // We can replace the returned value with the unique returned constant.
881 Value
&AnchorValue
= getAnchorValue();
882 if (Function
*F
= dyn_cast
<Function
>(&AnchorValue
)) {
883 for (const Use
&U
: F
->uses())
884 if (CallBase
*CB
= dyn_cast
<CallBase
>(U
.getUser()))
885 if (CB
->isCallee(&U
)) {
887 ConstantExpr::getTruncOrBitCast(RVC
, CB
->getType());
888 Changed
= ReplaceCallSiteUsersWith(*CB
, *RVCCast
) | Changed
;
891 assert(isa
<CallBase
>(AnchorValue
) &&
892 "Expcected a function or call base anchor!");
894 ConstantExpr::getTruncOrBitCast(RVC
, AnchorValue
.getType());
895 Changed
= ReplaceCallSiteUsersWith(cast
<CallBase
>(AnchorValue
), *RVCCast
);
897 if (Changed
== ChangeStatus::CHANGED
)
898 STATS_DECLTRACK(UniqueConstantReturnValue
, FunctionReturn
,
899 "Number of function returns replaced by constant return");
905 const std::string
AAReturnedValuesImpl::getAsStr() const {
906 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
907 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
908 ")[#UC: " + std::to_string(UnresolvedCalls
.size()) + "]";
912 AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor
&A
) const {
913 // If checkForAllReturnedValues provides a unique value, ignoring potential
914 // undef values that can also be present, it is assumed to be the actual
915 // return value and forwarded to the caller of this method. If there are
916 // multiple, a nullptr is returned indicating there cannot be a unique
918 Optional
<Value
*> UniqueRV
;
920 auto Pred
= [&](Value
&RV
) -> bool {
921 // If we found a second returned value and neither the current nor the saved
922 // one is an undef, there is no unique returned value. Undefs are special
923 // since we can pretend they have any value.
924 if (UniqueRV
.hasValue() && UniqueRV
!= &RV
&&
925 !(isa
<UndefValue
>(RV
) || isa
<UndefValue
>(UniqueRV
.getValue()))) {
930 // Do not overwrite a value with an undef.
931 if (!UniqueRV
.hasValue() || !isa
<UndefValue
>(RV
))
937 if (!A
.checkForAllReturnedValues(Pred
, *this))
943 bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
944 const function_ref
<bool(Value
&, const SmallSetVector
<ReturnInst
*, 4> &)>
949 // Check all returned values but ignore call sites as long as we have not
950 // encountered an overdefined one during an update.
951 for (auto &It
: ReturnedValues
) {
952 Value
*RV
= It
.first
;
954 CallBase
*CB
= dyn_cast
<CallBase
>(RV
);
955 if (CB
&& !UnresolvedCalls
.count(CB
))
958 if (!Pred(*RV
, It
.second
))
965 ChangeStatus
AAReturnedValuesImpl::updateImpl(Attributor
&A
) {
966 size_t NumUnresolvedCalls
= UnresolvedCalls
.size();
967 bool Changed
= false;
969 // State used in the value traversals starting in returned values.
971 // The map in which we collect return values -> return instrs.
972 decltype(ReturnedValues
) &RetValsMap
;
973 // The flag to indicate a change.
975 // The return instrs we come from.
976 SmallSetVector
<ReturnInst
*, 4> RetInsts
;
979 // Callback for a leaf value returned by the associated function.
980 auto VisitValueCB
= [](Value
&Val
, RVState
&RVS
, bool) -> bool {
981 auto Size
= RVS
.RetValsMap
[&Val
].size();
982 RVS
.RetValsMap
[&Val
].insert(RVS
.RetInsts
.begin(), RVS
.RetInsts
.end());
983 bool Inserted
= RVS
.RetValsMap
[&Val
].size() != Size
;
984 RVS
.Changed
|= Inserted
;
987 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
988 << " => " << RVS
.RetInsts
.size() << "\n";
993 // Helper method to invoke the generic value traversal.
994 auto VisitReturnedValue
= [&](Value
&RV
, RVState
&RVS
) {
995 IRPosition RetValPos
= IRPosition::value(RV
);
996 return genericValueTraversal
<AAReturnedValues
, RVState
>(A
, RetValPos
, *this,
1000 // Callback for all "return intructions" live in the associated function.
1001 auto CheckReturnInst
= [this, &VisitReturnedValue
, &Changed
](Instruction
&I
) {
1002 ReturnInst
&Ret
= cast
<ReturnInst
>(I
);
1003 RVState
RVS({ReturnedValues
, Changed
, {}});
1004 RVS
.RetInsts
.insert(&Ret
);
1005 return VisitReturnedValue(*Ret
.getReturnValue(), RVS
);
1008 // Start by discovering returned values from all live returned instructions in
1009 // the associated function.
1010 if (!A
.checkForAllInstructions(CheckReturnInst
, *this, {Instruction::Ret
}))
1011 return indicatePessimisticFixpoint();
1013 // Once returned values "directly" present in the code are handled we try to
1014 // resolve returned calls.
1015 decltype(ReturnedValues
) NewRVsMap
;
1016 for (auto &It
: ReturnedValues
) {
1017 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It
.first
1018 << " by #" << It
.second
.size() << " RIs\n");
1019 CallBase
*CB
= dyn_cast
<CallBase
>(It
.first
);
1020 if (!CB
|| UnresolvedCalls
.count(CB
))
1023 if (!CB
->getCalledFunction()) {
1024 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1026 UnresolvedCalls
.insert(CB
);
1030 // TODO: use the function scope once we have call site AAReturnedValues.
1031 const auto &RetValAA
= A
.getAAFor
<AAReturnedValues
>(
1032 *this, IRPosition::function(*CB
->getCalledFunction()));
1033 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1034 << static_cast<const AbstractAttribute
&>(RetValAA
)
1037 // Skip dead ends, thus if we do not know anything about the returned
1038 // call we mark it as unresolved and it will stay that way.
1039 if (!RetValAA
.getState().isValidState()) {
1040 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1042 UnresolvedCalls
.insert(CB
);
1046 // Do not try to learn partial information. If the callee has unresolved
1047 // return values we will treat the call as unresolved/opaque.
1048 auto &RetValAAUnresolvedCalls
= RetValAA
.getUnresolvedCalls();
1049 if (!RetValAAUnresolvedCalls
.empty()) {
1050 UnresolvedCalls
.insert(CB
);
1054 // Now check if we can track transitively returned values. If possible, thus
1055 // if all return value can be represented in the current scope, do so.
1056 bool Unresolved
= false;
1057 for (auto &RetValAAIt
: RetValAA
.returned_values()) {
1058 Value
*RetVal
= RetValAAIt
.first
;
1059 if (isa
<Argument
>(RetVal
) || isa
<CallBase
>(RetVal
) ||
1060 isa
<Constant
>(RetVal
))
1062 // Anything that did not fit in the above categories cannot be resolved,
1063 // mark the call as unresolved.
1064 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1065 "cannot be translated: "
1066 << *RetVal
<< "\n");
1067 UnresolvedCalls
.insert(CB
);
1075 // Now track transitively returned values.
1076 unsigned &NumRetAA
= NumReturnedValuesPerKnownAA
[CB
];
1077 if (NumRetAA
== RetValAA
.getNumReturnValues()) {
1078 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1079 "changed since it was seen last\n");
1082 NumRetAA
= RetValAA
.getNumReturnValues();
1084 for (auto &RetValAAIt
: RetValAA
.returned_values()) {
1085 Value
*RetVal
= RetValAAIt
.first
;
1086 if (Argument
*Arg
= dyn_cast
<Argument
>(RetVal
)) {
1087 // Arguments are mapped to call site operands and we begin the traversal
1089 bool Unused
= false;
1090 RVState
RVS({NewRVsMap
, Unused
, RetValAAIt
.second
});
1091 VisitReturnedValue(*CB
->getArgOperand(Arg
->getArgNo()), RVS
);
1093 } else if (isa
<CallBase
>(RetVal
)) {
1094 // Call sites are resolved by the callee attribute over time, no need to
1095 // do anything for us.
1097 } else if (isa
<Constant
>(RetVal
)) {
1098 // Constants are valid everywhere, we can simply take them.
1099 NewRVsMap
[RetVal
].insert(It
.second
.begin(), It
.second
.end());
1105 // To avoid modifications to the ReturnedValues map while we iterate over it
1106 // we kept record of potential new entries in a copy map, NewRVsMap.
1107 for (auto &It
: NewRVsMap
) {
1108 assert(!It
.second
.empty() && "Entry does not add anything.");
1109 auto &ReturnInsts
= ReturnedValues
[It
.first
];
1110 for (ReturnInst
*RI
: It
.second
)
1111 if (ReturnInsts
.insert(RI
)) {
1112 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1113 << *It
.first
<< " => " << *RI
<< "\n");
1118 Changed
|= (NumUnresolvedCalls
!= UnresolvedCalls
.size());
1119 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
1122 struct AAReturnedValuesFunction final
: public AAReturnedValuesImpl
{
1123 AAReturnedValuesFunction(const IRPosition
&IRP
) : AAReturnedValuesImpl(IRP
) {}
1125 /// See AbstractAttribute::trackStatistics()
1126 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(returned
) }
1129 /// Returned values information for a call sites.
1130 struct AAReturnedValuesCallSite final
: AAReturnedValuesImpl
{
1131 AAReturnedValuesCallSite(const IRPosition
&IRP
) : AAReturnedValuesImpl(IRP
) {}
1133 /// See AbstractAttribute::initialize(...).
1134 void initialize(Attributor
&A
) override
{
1135 // TODO: Once we have call site specific value information we can provide
1136 // call site specific liveness information and then it makes
1137 // sense to specialize attributes for call sites instead of
1138 // redirecting requests to the callee.
1139 llvm_unreachable("Abstract attributes for returned values are not "
1140 "supported for call sites yet!");
1143 /// See AbstractAttribute::updateImpl(...).
1144 ChangeStatus
updateImpl(Attributor
&A
) override
{
1145 return indicatePessimisticFixpoint();
1148 /// See AbstractAttribute::trackStatistics()
1149 void trackStatistics() const override
{}
1152 /// ------------------------ NoSync Function Attribute -------------------------
1154 struct AANoSyncImpl
: AANoSync
{
1155 AANoSyncImpl(const IRPosition
&IRP
) : AANoSync(IRP
) {}
1157 const std::string
getAsStr() const override
{
1158 return getAssumed() ? "nosync" : "may-sync";
1161 /// See AbstractAttribute::updateImpl(...).
1162 ChangeStatus
updateImpl(Attributor
&A
) override
;
1164 /// Helper function used to determine whether an instruction is non-relaxed
1165 /// atomic. In other words, if an atomic instruction does not have unordered
1166 /// or monotonic ordering
1167 static bool isNonRelaxedAtomic(Instruction
*I
);
1169 /// Helper function used to determine whether an instruction is volatile.
1170 static bool isVolatile(Instruction
*I
);
1172 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1174 static bool isNoSyncIntrinsic(Instruction
*I
);
1177 bool AANoSyncImpl::isNonRelaxedAtomic(Instruction
*I
) {
1181 AtomicOrdering Ordering
;
1182 switch (I
->getOpcode()) {
1183 case Instruction::AtomicRMW
:
1184 Ordering
= cast
<AtomicRMWInst
>(I
)->getOrdering();
1186 case Instruction::Store
:
1187 Ordering
= cast
<StoreInst
>(I
)->getOrdering();
1189 case Instruction::Load
:
1190 Ordering
= cast
<LoadInst
>(I
)->getOrdering();
1192 case Instruction::Fence
: {
1193 auto *FI
= cast
<FenceInst
>(I
);
1194 if (FI
->getSyncScopeID() == SyncScope::SingleThread
)
1196 Ordering
= FI
->getOrdering();
1199 case Instruction::AtomicCmpXchg
: {
1200 AtomicOrdering Success
= cast
<AtomicCmpXchgInst
>(I
)->getSuccessOrdering();
1201 AtomicOrdering Failure
= cast
<AtomicCmpXchgInst
>(I
)->getFailureOrdering();
1202 // Only if both are relaxed, than it can be treated as relaxed.
1203 // Otherwise it is non-relaxed.
1204 if (Success
!= AtomicOrdering::Unordered
&&
1205 Success
!= AtomicOrdering::Monotonic
)
1207 if (Failure
!= AtomicOrdering::Unordered
&&
1208 Failure
!= AtomicOrdering::Monotonic
)
1214 "New atomic operations need to be known in the attributor.");
1218 if (Ordering
== AtomicOrdering::Unordered
||
1219 Ordering
== AtomicOrdering::Monotonic
)
1224 /// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1225 /// FIXME: We should ipmrove the handling of intrinsics.
1226 bool AANoSyncImpl::isNoSyncIntrinsic(Instruction
*I
) {
1227 if (auto *II
= dyn_cast
<IntrinsicInst
>(I
)) {
1228 switch (II
->getIntrinsicID()) {
1229 /// Element wise atomic memory intrinsics are can only be unordered,
1230 /// therefore nosync.
1231 case Intrinsic::memset_element_unordered_atomic
:
1232 case Intrinsic::memmove_element_unordered_atomic
:
1233 case Intrinsic::memcpy_element_unordered_atomic
:
1235 case Intrinsic::memset
:
1236 case Intrinsic::memmove
:
1237 case Intrinsic::memcpy
:
1238 if (!cast
<MemIntrinsic
>(II
)->isVolatile())
1248 bool AANoSyncImpl::isVolatile(Instruction
*I
) {
1249 assert(!ImmutableCallSite(I
) && !isa
<CallBase
>(I
) &&
1250 "Calls should not be checked here");
1252 switch (I
->getOpcode()) {
1253 case Instruction::AtomicRMW
:
1254 return cast
<AtomicRMWInst
>(I
)->isVolatile();
1255 case Instruction::Store
:
1256 return cast
<StoreInst
>(I
)->isVolatile();
1257 case Instruction::Load
:
1258 return cast
<LoadInst
>(I
)->isVolatile();
1259 case Instruction::AtomicCmpXchg
:
1260 return cast
<AtomicCmpXchgInst
>(I
)->isVolatile();
1266 ChangeStatus
AANoSyncImpl::updateImpl(Attributor
&A
) {
1268 auto CheckRWInstForNoSync
= [&](Instruction
&I
) {
1269 /// We are looking for volatile instructions or Non-Relaxed atomics.
1270 /// FIXME: We should ipmrove the handling of intrinsics.
1272 if (isa
<IntrinsicInst
>(&I
) && isNoSyncIntrinsic(&I
))
1275 if (ImmutableCallSite ICS
= ImmutableCallSite(&I
)) {
1276 if (ICS
.hasFnAttr(Attribute::NoSync
))
1279 const auto &NoSyncAA
=
1280 A
.getAAFor
<AANoSync
>(*this, IRPosition::callsite_function(ICS
));
1281 if (NoSyncAA
.isAssumedNoSync())
1286 if (!isVolatile(&I
) && !isNonRelaxedAtomic(&I
))
1292 auto CheckForNoSync
= [&](Instruction
&I
) {
1293 // At this point we handled all read/write effects and they are all
1294 // nosync, so they can be skipped.
1295 if (I
.mayReadOrWriteMemory())
1298 // non-convergent and readnone imply nosync.
1299 return !ImmutableCallSite(&I
).isConvergent();
1302 if (!A
.checkForAllReadWriteInstructions(CheckRWInstForNoSync
, *this) ||
1303 !A
.checkForAllCallLikeInstructions(CheckForNoSync
, *this))
1304 return indicatePessimisticFixpoint();
1306 return ChangeStatus::UNCHANGED
;
1309 struct AANoSyncFunction final
: public AANoSyncImpl
{
1310 AANoSyncFunction(const IRPosition
&IRP
) : AANoSyncImpl(IRP
) {}
1312 /// See AbstractAttribute::trackStatistics()
1313 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nosync
) }
1316 /// NoSync attribute deduction for a call sites.
1317 struct AANoSyncCallSite final
: AANoSyncImpl
{
1318 AANoSyncCallSite(const IRPosition
&IRP
) : AANoSyncImpl(IRP
) {}
1320 /// See AbstractAttribute::initialize(...).
1321 void initialize(Attributor
&A
) override
{
1322 AANoSyncImpl::initialize(A
);
1323 Function
*F
= getAssociatedFunction();
1325 indicatePessimisticFixpoint();
1328 /// See AbstractAttribute::updateImpl(...).
1329 ChangeStatus
updateImpl(Attributor
&A
) override
{
1330 // TODO: Once we have call site specific value information we can provide
1331 // call site specific liveness information and then it makes
1332 // sense to specialize attributes for call sites arguments instead of
1333 // redirecting requests to the callee argument.
1334 Function
*F
= getAssociatedFunction();
1335 const IRPosition
&FnPos
= IRPosition::function(*F
);
1336 auto &FnAA
= A
.getAAFor
<AANoSync
>(*this, FnPos
);
1337 return clampStateAndIndicateChange(
1338 getState(), static_cast<const AANoSync::StateType
&>(FnAA
.getState()));
1341 /// See AbstractAttribute::trackStatistics()
1342 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nosync
); }
1345 /// ------------------------ No-Free Attributes ----------------------------
1347 struct AANoFreeImpl
: public AANoFree
{
1348 AANoFreeImpl(const IRPosition
&IRP
) : AANoFree(IRP
) {}
1350 /// See AbstractAttribute::updateImpl(...).
1351 ChangeStatus
updateImpl(Attributor
&A
) override
{
1352 auto CheckForNoFree
= [&](Instruction
&I
) {
1353 ImmutableCallSite
ICS(&I
);
1354 if (ICS
.hasFnAttr(Attribute::NoFree
))
1357 const auto &NoFreeAA
=
1358 A
.getAAFor
<AANoFree
>(*this, IRPosition::callsite_function(ICS
));
1359 return NoFreeAA
.isAssumedNoFree();
1362 if (!A
.checkForAllCallLikeInstructions(CheckForNoFree
, *this))
1363 return indicatePessimisticFixpoint();
1364 return ChangeStatus::UNCHANGED
;
1367 /// See AbstractAttribute::getAsStr().
1368 const std::string
getAsStr() const override
{
1369 return getAssumed() ? "nofree" : "may-free";
1373 struct AANoFreeFunction final
: public AANoFreeImpl
{
1374 AANoFreeFunction(const IRPosition
&IRP
) : AANoFreeImpl(IRP
) {}
1376 /// See AbstractAttribute::trackStatistics()
1377 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nofree
) }
1380 /// NoFree attribute deduction for a call sites.
1381 struct AANoFreeCallSite final
: AANoFreeImpl
{
1382 AANoFreeCallSite(const IRPosition
&IRP
) : AANoFreeImpl(IRP
) {}
1384 /// See AbstractAttribute::initialize(...).
1385 void initialize(Attributor
&A
) override
{
1386 AANoFreeImpl::initialize(A
);
1387 Function
*F
= getAssociatedFunction();
1389 indicatePessimisticFixpoint();
1392 /// See AbstractAttribute::updateImpl(...).
1393 ChangeStatus
updateImpl(Attributor
&A
) override
{
1394 // TODO: Once we have call site specific value information we can provide
1395 // call site specific liveness information and then it makes
1396 // sense to specialize attributes for call sites arguments instead of
1397 // redirecting requests to the callee argument.
1398 Function
*F
= getAssociatedFunction();
1399 const IRPosition
&FnPos
= IRPosition::function(*F
);
1400 auto &FnAA
= A
.getAAFor
<AANoFree
>(*this, FnPos
);
1401 return clampStateAndIndicateChange(
1402 getState(), static_cast<const AANoFree::StateType
&>(FnAA
.getState()));
1405 /// See AbstractAttribute::trackStatistics()
1406 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nofree
); }
1409 /// ------------------------ NonNull Argument Attribute ------------------------
1410 struct AANonNullImpl
: AANonNull
{
1411 AANonNullImpl(const IRPosition
&IRP
) : AANonNull(IRP
) {}
1413 /// See AbstractAttribute::initialize(...).
1414 void initialize(Attributor
&A
) override
{
1415 if (hasAttr({Attribute::NonNull
, Attribute::Dereferenceable
}))
1416 indicateOptimisticFixpoint();
1418 AANonNull::initialize(A
);
1421 /// See AbstractAttribute::getAsStr().
1422 const std::string
getAsStr() const override
{
1423 return getAssumed() ? "nonnull" : "may-null";
1427 /// NonNull attribute for a floating value.
1428 struct AANonNullFloating
: AANonNullImpl
{
1429 AANonNullFloating(const IRPosition
&IRP
) : AANonNullImpl(IRP
) {}
1431 /// See AbstractAttribute::initialize(...).
1432 void initialize(Attributor
&A
) override
{
1433 AANonNullImpl::initialize(A
);
1438 const IRPosition
&IRP
= getIRPosition();
1439 const Value
&V
= IRP
.getAssociatedValue();
1440 const DataLayout
&DL
= A
.getDataLayout();
1442 // TODO: This context sensitive query should be removed once we can do
1443 // context sensitive queries in the genericValueTraversal below.
1444 if (isKnownNonZero(&V
, DL
, 0, /* TODO: AC */ nullptr, IRP
.getCtxI(),
1445 /* TODO: DT */ nullptr))
1446 indicateOptimisticFixpoint();
1449 /// See AbstractAttribute::updateImpl(...).
1450 ChangeStatus
updateImpl(Attributor
&A
) override
{
1451 const DataLayout
&DL
= A
.getDataLayout();
1453 auto VisitValueCB
= [&](Value
&V
, AAAlign::StateType
&T
,
1454 bool Stripped
) -> bool {
1455 const auto &AA
= A
.getAAFor
<AANonNull
>(*this, IRPosition::value(V
));
1456 if (!Stripped
&& this == &AA
) {
1457 if (!isKnownNonZero(&V
, DL
, 0, /* TODO: AC */ nullptr,
1458 /* TODO: CtxI */ nullptr,
1459 /* TODO: DT */ nullptr))
1460 T
.indicatePessimisticFixpoint();
1462 // Use abstract attribute information.
1463 const AANonNull::StateType
&NS
=
1464 static_cast<const AANonNull::StateType
&>(AA
.getState());
1467 return T
.isValidState();
1471 if (!genericValueTraversal
<AANonNull
, StateType
>(A
, getIRPosition(), *this,
1473 return indicatePessimisticFixpoint();
1475 return clampStateAndIndicateChange(getState(), T
);
1478 /// See AbstractAttribute::trackStatistics()
1479 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(nonnull
) }
1482 /// NonNull attribute for function return value.
1483 struct AANonNullReturned final
1484 : AAReturnedFromReturnedValues
<AANonNull
, AANonNullImpl
> {
1485 AANonNullReturned(const IRPosition
&IRP
)
1486 : AAReturnedFromReturnedValues
<AANonNull
, AANonNullImpl
>(IRP
) {}
1488 /// See AbstractAttribute::trackStatistics()
1489 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(nonnull
) }
1492 /// NonNull attribute for function argument.
1493 struct AANonNullArgument final
1494 : AAArgumentFromCallSiteArguments
<AANonNull
, AANonNullImpl
> {
1495 AANonNullArgument(const IRPosition
&IRP
)
1496 : AAArgumentFromCallSiteArguments
<AANonNull
, AANonNullImpl
>(IRP
) {}
1498 /// See AbstractAttribute::trackStatistics()
1499 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nonnull
) }
1502 struct AANonNullCallSiteArgument final
: AANonNullFloating
{
1503 AANonNullCallSiteArgument(const IRPosition
&IRP
) : AANonNullFloating(IRP
) {}
1505 /// See AbstractAttribute::trackStatistics()
1506 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(nonnull
) }
1509 /// NonNull attribute for a call site return position.
1510 struct AANonNullCallSiteReturned final
1511 : AACallSiteReturnedFromReturned
<AANonNull
, AANonNullImpl
> {
1512 AANonNullCallSiteReturned(const IRPosition
&IRP
)
1513 : AACallSiteReturnedFromReturned
<AANonNull
, AANonNullImpl
>(IRP
) {}
1515 /// See AbstractAttribute::trackStatistics()
1516 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(nonnull
) }
1519 /// ------------------------ No-Recurse Attributes ----------------------------
1521 struct AANoRecurseImpl
: public AANoRecurse
{
1522 AANoRecurseImpl(const IRPosition
&IRP
) : AANoRecurse(IRP
) {}
1524 /// See AbstractAttribute::getAsStr()
1525 const std::string
getAsStr() const override
{
1526 return getAssumed() ? "norecurse" : "may-recurse";
1530 struct AANoRecurseFunction final
: AANoRecurseImpl
{
1531 AANoRecurseFunction(const IRPosition
&IRP
) : AANoRecurseImpl(IRP
) {}
1533 /// See AbstractAttribute::initialize(...).
1534 void initialize(Attributor
&A
) override
{
1535 AANoRecurseImpl::initialize(A
);
1536 if (const Function
*F
= getAnchorScope())
1537 if (A
.getInfoCache().getSccSize(*F
) == 1)
1539 indicatePessimisticFixpoint();
1542 /// See AbstractAttribute::updateImpl(...).
1543 ChangeStatus
updateImpl(Attributor
&A
) override
{
1545 auto CheckForNoRecurse
= [&](Instruction
&I
) {
1546 ImmutableCallSite
ICS(&I
);
1547 if (ICS
.hasFnAttr(Attribute::NoRecurse
))
1550 const auto &NoRecurseAA
=
1551 A
.getAAFor
<AANoRecurse
>(*this, IRPosition::callsite_function(ICS
));
1552 if (!NoRecurseAA
.isAssumedNoRecurse())
1555 // Recursion to the same function
1556 if (ICS
.getCalledFunction() == getAnchorScope())
1562 if (!A
.checkForAllCallLikeInstructions(CheckForNoRecurse
, *this))
1563 return indicatePessimisticFixpoint();
1564 return ChangeStatus::UNCHANGED
;
1567 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(norecurse
) }
1570 /// NoRecurse attribute deduction for a call sites.
1571 struct AANoRecurseCallSite final
: AANoRecurseImpl
{
1572 AANoRecurseCallSite(const IRPosition
&IRP
) : AANoRecurseImpl(IRP
) {}
1574 /// See AbstractAttribute::initialize(...).
1575 void initialize(Attributor
&A
) override
{
1576 AANoRecurseImpl::initialize(A
);
1577 Function
*F
= getAssociatedFunction();
1579 indicatePessimisticFixpoint();
1582 /// See AbstractAttribute::updateImpl(...).
1583 ChangeStatus
updateImpl(Attributor
&A
) override
{
1584 // TODO: Once we have call site specific value information we can provide
1585 // call site specific liveness information and then it makes
1586 // sense to specialize attributes for call sites arguments instead of
1587 // redirecting requests to the callee argument.
1588 Function
*F
= getAssociatedFunction();
1589 const IRPosition
&FnPos
= IRPosition::function(*F
);
1590 auto &FnAA
= A
.getAAFor
<AANoRecurse
>(*this, FnPos
);
1591 return clampStateAndIndicateChange(
1593 static_cast<const AANoRecurse::StateType
&>(FnAA
.getState()));
1596 /// See AbstractAttribute::trackStatistics()
1597 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(norecurse
); }
1600 /// ------------------------ Will-Return Attributes ----------------------------
1602 // Helper function that checks whether a function has any cycle.
1603 // TODO: Replace with more efficent code
1604 static bool containsCycle(Function
&F
) {
1605 SmallPtrSet
<BasicBlock
*, 32> Visited
;
1607 // Traverse BB by dfs and check whether successor is already visited.
1608 for (BasicBlock
*BB
: depth_first(&F
)) {
1610 for (auto *SuccBB
: successors(BB
)) {
1611 if (Visited
.count(SuccBB
))
1618 // Helper function that checks the function have a loop which might become an
1620 // FIXME: Any cycle is regarded as endless loop for now.
1621 // We have to allow some patterns.
1622 static bool containsPossiblyEndlessLoop(Function
*F
) {
1623 return !F
|| !F
->hasExactDefinition() || containsCycle(*F
);
1626 struct AAWillReturnImpl
: public AAWillReturn
{
1627 AAWillReturnImpl(const IRPosition
&IRP
) : AAWillReturn(IRP
) {}
1629 /// See AbstractAttribute::initialize(...).
1630 void initialize(Attributor
&A
) override
{
1631 AAWillReturn::initialize(A
);
1633 Function
*F
= getAssociatedFunction();
1634 if (containsPossiblyEndlessLoop(F
))
1635 indicatePessimisticFixpoint();
1638 /// See AbstractAttribute::updateImpl(...).
1639 ChangeStatus
updateImpl(Attributor
&A
) override
{
1640 auto CheckForWillReturn
= [&](Instruction
&I
) {
1641 IRPosition IPos
= IRPosition::callsite_function(ImmutableCallSite(&I
));
1642 const auto &WillReturnAA
= A
.getAAFor
<AAWillReturn
>(*this, IPos
);
1643 if (WillReturnAA
.isKnownWillReturn())
1645 if (!WillReturnAA
.isAssumedWillReturn())
1647 const auto &NoRecurseAA
= A
.getAAFor
<AANoRecurse
>(*this, IPos
);
1648 return NoRecurseAA
.isAssumedNoRecurse();
1651 if (!A
.checkForAllCallLikeInstructions(CheckForWillReturn
, *this))
1652 return indicatePessimisticFixpoint();
1654 return ChangeStatus::UNCHANGED
;
1657 /// See AbstractAttribute::getAsStr()
1658 const std::string
getAsStr() const override
{
1659 return getAssumed() ? "willreturn" : "may-noreturn";
1663 struct AAWillReturnFunction final
: AAWillReturnImpl
{
1664 AAWillReturnFunction(const IRPosition
&IRP
) : AAWillReturnImpl(IRP
) {}
1666 /// See AbstractAttribute::trackStatistics()
1667 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(willreturn
) }
1670 /// WillReturn attribute deduction for a call sites.
1671 struct AAWillReturnCallSite final
: AAWillReturnImpl
{
1672 AAWillReturnCallSite(const IRPosition
&IRP
) : AAWillReturnImpl(IRP
) {}
1674 /// See AbstractAttribute::initialize(...).
1675 void initialize(Attributor
&A
) override
{
1676 AAWillReturnImpl::initialize(A
);
1677 Function
*F
= getAssociatedFunction();
1679 indicatePessimisticFixpoint();
1682 /// See AbstractAttribute::updateImpl(...).
1683 ChangeStatus
updateImpl(Attributor
&A
) override
{
1684 // TODO: Once we have call site specific value information we can provide
1685 // call site specific liveness information and then it makes
1686 // sense to specialize attributes for call sites arguments instead of
1687 // redirecting requests to the callee argument.
1688 Function
*F
= getAssociatedFunction();
1689 const IRPosition
&FnPos
= IRPosition::function(*F
);
1690 auto &FnAA
= A
.getAAFor
<AAWillReturn
>(*this, FnPos
);
1691 return clampStateAndIndicateChange(
1693 static_cast<const AAWillReturn::StateType
&>(FnAA
.getState()));
1696 /// See AbstractAttribute::trackStatistics()
1697 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(willreturn
); }
1700 /// ------------------------ NoAlias Argument Attribute ------------------------
1702 struct AANoAliasImpl
: AANoAlias
{
1703 AANoAliasImpl(const IRPosition
&IRP
) : AANoAlias(IRP
) {}
1705 const std::string
getAsStr() const override
{
1706 return getAssumed() ? "noalias" : "may-alias";
1710 /// NoAlias attribute for a floating value.
1711 struct AANoAliasFloating final
: AANoAliasImpl
{
1712 AANoAliasFloating(const IRPosition
&IRP
) : AANoAliasImpl(IRP
) {}
1714 /// See AbstractAttribute::initialize(...).
1715 void initialize(Attributor
&A
) override
{
1716 AANoAliasImpl::initialize(A
);
1717 if (isa
<AllocaInst
>(getAnchorValue()))
1718 indicateOptimisticFixpoint();
1721 /// See AbstractAttribute::updateImpl(...).
1722 ChangeStatus
updateImpl(Attributor
&A
) override
{
1723 // TODO: Implement this.
1724 return indicatePessimisticFixpoint();
1727 /// See AbstractAttribute::trackStatistics()
1728 void trackStatistics() const override
{
1729 STATS_DECLTRACK_FLOATING_ATTR(noalias
)
1733 /// NoAlias attribute for an argument.
1734 struct AANoAliasArgument final
1735 : AAArgumentFromCallSiteArguments
<AANoAlias
, AANoAliasImpl
> {
1736 AANoAliasArgument(const IRPosition
&IRP
)
1737 : AAArgumentFromCallSiteArguments
<AANoAlias
, AANoAliasImpl
>(IRP
) {}
1739 /// See AbstractAttribute::trackStatistics()
1740 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(noalias
) }
1743 struct AANoAliasCallSiteArgument final
: AANoAliasImpl
{
1744 AANoAliasCallSiteArgument(const IRPosition
&IRP
) : AANoAliasImpl(IRP
) {}
1746 /// See AbstractAttribute::initialize(...).
1747 void initialize(Attributor
&A
) override
{
1748 // See callsite argument attribute and callee argument attribute.
1749 ImmutableCallSite
ICS(&getAnchorValue());
1750 if (ICS
.paramHasAttr(getArgNo(), Attribute::NoAlias
))
1751 indicateOptimisticFixpoint();
1754 /// See AbstractAttribute::updateImpl(...).
1755 ChangeStatus
updateImpl(Attributor
&A
) override
{
1756 // We can deduce "noalias" if the following conditions hold.
1757 // (i) Associated value is assumed to be noalias in the definition.
1758 // (ii) Associated value is assumed to be no-capture in all the uses
1759 // possibly executed before this callsite.
1760 // (iii) There is no other pointer argument which could alias with the
1763 const Value
&V
= getAssociatedValue();
1764 const IRPosition IRP
= IRPosition::value(V
);
1766 // (i) Check whether noalias holds in the definition.
1768 auto &NoAliasAA
= A
.getAAFor
<AANoAlias
>(*this, IRP
);
1770 if (!NoAliasAA
.isAssumedNoAlias())
1771 return indicatePessimisticFixpoint();
1773 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1774 << " is assumed NoAlias in the definition\n");
1776 // (ii) Check whether the value is captured in the scope using AANoCapture.
1777 // FIXME: This is conservative though, it is better to look at CFG and
1778 // check only uses possibly executed before this callsite.
1780 auto &NoCaptureAA
= A
.getAAFor
<AANoCapture
>(*this, IRP
);
1781 if (!NoCaptureAA
.isAssumedNoCaptureMaybeReturned())
1782 return indicatePessimisticFixpoint();
1784 // (iii) Check there is no other pointer argument which could alias with the
1786 ImmutableCallSite
ICS(&getAnchorValue());
1787 for (unsigned i
= 0; i
< ICS
.getNumArgOperands(); i
++) {
1788 if (getArgNo() == (int)i
)
1790 const Value
*ArgOp
= ICS
.getArgOperand(i
);
1791 if (!ArgOp
->getType()->isPointerTy())
1794 if (const Function
*F
= getAnchorScope()) {
1795 if (AAResults
*AAR
= A
.getInfoCache().getAAResultsForFunction(*F
)) {
1797 << "[Attributor][NoAliasCSArg] Check alias between "
1798 "callsite arguments "
1799 << AAR
->isNoAlias(&getAssociatedValue(), ArgOp
) << " "
1800 << getAssociatedValue() << " " << *ArgOp
<< "\n");
1802 if (AAR
->isNoAlias(&getAssociatedValue(), ArgOp
))
1806 return indicatePessimisticFixpoint();
1809 return ChangeStatus::UNCHANGED
;
1812 /// See AbstractAttribute::trackStatistics()
1813 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(noalias
) }
1816 /// NoAlias attribute for function return value.
1817 struct AANoAliasReturned final
: AANoAliasImpl
{
1818 AANoAliasReturned(const IRPosition
&IRP
) : AANoAliasImpl(IRP
) {}
1820 /// See AbstractAttribute::updateImpl(...).
1821 virtual ChangeStatus
updateImpl(Attributor
&A
) override
{
1823 auto CheckReturnValue
= [&](Value
&RV
) -> bool {
1824 if (Constant
*C
= dyn_cast
<Constant
>(&RV
))
1825 if (C
->isNullValue() || isa
<UndefValue
>(C
))
1828 /// For now, we can only deduce noalias if we have call sites.
1829 /// FIXME: add more support.
1830 ImmutableCallSite
ICS(&RV
);
1834 const IRPosition
&RVPos
= IRPosition::value(RV
);
1835 const auto &NoAliasAA
= A
.getAAFor
<AANoAlias
>(*this, RVPos
);
1836 if (!NoAliasAA
.isAssumedNoAlias())
1839 const auto &NoCaptureAA
= A
.getAAFor
<AANoCapture
>(*this, RVPos
);
1840 return NoCaptureAA
.isAssumedNoCaptureMaybeReturned();
1843 if (!A
.checkForAllReturnedValues(CheckReturnValue
, *this))
1844 return indicatePessimisticFixpoint();
1846 return ChangeStatus::UNCHANGED
;
1849 /// See AbstractAttribute::trackStatistics()
1850 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(noalias
) }
1853 /// NoAlias attribute deduction for a call site return value.
1854 struct AANoAliasCallSiteReturned final
: AANoAliasImpl
{
1855 AANoAliasCallSiteReturned(const IRPosition
&IRP
) : AANoAliasImpl(IRP
) {}
1857 /// See AbstractAttribute::initialize(...).
1858 void initialize(Attributor
&A
) override
{
1859 AANoAliasImpl::initialize(A
);
1860 Function
*F
= getAssociatedFunction();
1862 indicatePessimisticFixpoint();
1865 /// See AbstractAttribute::updateImpl(...).
1866 ChangeStatus
updateImpl(Attributor
&A
) override
{
1867 // TODO: Once we have call site specific value information we can provide
1868 // call site specific liveness information and then it makes
1869 // sense to specialize attributes for call sites arguments instead of
1870 // redirecting requests to the callee argument.
1871 Function
*F
= getAssociatedFunction();
1872 const IRPosition
&FnPos
= IRPosition::returned(*F
);
1873 auto &FnAA
= A
.getAAFor
<AANoAlias
>(*this, FnPos
);
1874 return clampStateAndIndicateChange(
1875 getState(), static_cast<const AANoAlias::StateType
&>(FnAA
.getState()));
1878 /// See AbstractAttribute::trackStatistics()
1879 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(noalias
); }
1882 /// -------------------AAIsDead Function Attribute-----------------------
1884 struct AAIsDeadImpl
: public AAIsDead
{
1885 AAIsDeadImpl(const IRPosition
&IRP
) : AAIsDead(IRP
) {}
1887 void initialize(Attributor
&A
) override
{
1888 const Function
*F
= getAssociatedFunction();
1889 if (F
&& !F
->isDeclaration())
1890 exploreFromEntry(A
, F
);
1893 void exploreFromEntry(Attributor
&A
, const Function
*F
) {
1894 ToBeExploredPaths
.insert(&(F
->getEntryBlock().front()));
1896 for (size_t i
= 0; i
< ToBeExploredPaths
.size(); ++i
)
1897 if (const Instruction
*NextNoReturnI
=
1898 findNextNoReturn(A
, ToBeExploredPaths
[i
]))
1899 NoReturnCalls
.insert(NextNoReturnI
);
1901 // Mark the block live after we looked for no-return instructions.
1902 assumeLive(A
, F
->getEntryBlock());
1905 /// Find the next assumed noreturn instruction in the block of \p I starting
1906 /// from, thus including, \p I.
1908 /// The caller is responsible to monitor the ToBeExploredPaths set as new
1909 /// instructions discovered in other basic block will be placed in there.
1911 /// \returns The next assumed noreturn instructions in the block of \p I
1912 /// starting from, thus including, \p I.
1913 const Instruction
*findNextNoReturn(Attributor
&A
, const Instruction
*I
);
1915 /// See AbstractAttribute::getAsStr().
1916 const std::string
getAsStr() const override
{
1917 return "Live[#BB " + std::to_string(AssumedLiveBlocks
.size()) + "/" +
1918 std::to_string(getAssociatedFunction()->size()) + "][#NRI " +
1919 std::to_string(NoReturnCalls
.size()) + "]";
1922 /// See AbstractAttribute::manifest(...).
1923 ChangeStatus
manifest(Attributor
&A
) override
{
1924 assert(getState().isValidState() &&
1925 "Attempted to manifest an invalid state!");
1927 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
1928 Function
&F
= *getAssociatedFunction();
1930 if (AssumedLiveBlocks
.empty()) {
1931 A
.deleteAfterManifest(F
);
1932 return ChangeStatus::CHANGED
;
1935 // Flag to determine if we can change an invoke to a call assuming the
1936 // callee is nounwind. This is not possible if the personality of the
1937 // function allows to catch asynchronous exceptions.
1938 bool Invoke2CallAllowed
= !mayCatchAsynchronousExceptions(F
);
1940 for (const Instruction
*NRC
: NoReturnCalls
) {
1941 Instruction
*I
= const_cast<Instruction
*>(NRC
);
1942 BasicBlock
*BB
= I
->getParent();
1943 Instruction
*SplitPos
= I
->getNextNode();
1944 // TODO: mark stuff before unreachable instructions as dead.
1945 if (isa_and_nonnull
<UnreachableInst
>(SplitPos
))
1948 if (auto *II
= dyn_cast
<InvokeInst
>(I
)) {
1949 // If we keep the invoke the split position is at the beginning of the
1950 // normal desitination block (it invokes a noreturn function after all).
1951 BasicBlock
*NormalDestBB
= II
->getNormalDest();
1952 SplitPos
= &NormalDestBB
->front();
1954 /// Invoke is replaced with a call and unreachable is placed after it if
1955 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
1956 /// and only place an unreachable in the normal successor.
1957 if (Invoke2CallAllowed
) {
1958 if (II
->getCalledFunction()) {
1959 const IRPosition
&IPos
= IRPosition::callsite_function(*II
);
1960 const auto &AANoUnw
= A
.getAAFor
<AANoUnwind
>(*this, IPos
);
1961 if (AANoUnw
.isAssumedNoUnwind()) {
1963 << "[AAIsDead] Replace invoke with call inst\n");
1964 // We do not need an invoke (II) but instead want a call followed
1965 // by an unreachable. However, we do not remove II as other
1966 // abstract attributes might have it cached as part of their
1967 // results. Given that we modify the CFG anyway, we simply keep II
1968 // around but in a new dead block. To avoid II being live through
1969 // a different edge we have to ensure the block we place it in is
1970 // only reached from the current block of II and then not reached
1971 // at all when we insert the unreachable.
1972 SplitBlockPredecessors(NormalDestBB
, {BB
}, ".i2c");
1973 CallInst
*CI
= createCallMatchingInvoke(II
);
1974 CI
->insertBefore(II
);
1976 II
->replaceAllUsesWith(CI
);
1977 SplitPos
= CI
->getNextNode();
1982 if (SplitPos
== &NormalDestBB
->front()) {
1983 // If this is an invoke of a noreturn function the edge to the normal
1984 // destination block is dead but not necessarily the block itself.
1985 // TODO: We need to move to an edge based system during deduction and
1987 assert(!NormalDestBB
->isLandingPad() &&
1988 "Expected the normal destination not to be a landingpad!");
1989 BasicBlock
*SplitBB
=
1990 SplitBlockPredecessors(NormalDestBB
, {BB
}, ".dead");
1991 // The split block is live even if it contains only an unreachable
1992 // instruction at the end.
1993 assumeLive(A
, *SplitBB
);
1994 SplitPos
= SplitBB
->getTerminator();
1998 BB
= SplitPos
->getParent();
1999 SplitBlock(BB
, SplitPos
);
2000 changeToUnreachable(BB
->getTerminator(), /* UseLLVMTrap */ false);
2001 HasChanged
= ChangeStatus::CHANGED
;
2004 for (BasicBlock
&BB
: F
)
2005 if (!AssumedLiveBlocks
.count(&BB
))
2006 A
.deleteAfterManifest(BB
);
2011 /// See AbstractAttribute::updateImpl(...).
2012 ChangeStatus
updateImpl(Attributor
&A
) override
;
2014 /// See AAIsDead::isAssumedDead(BasicBlock *).
2015 bool isAssumedDead(const BasicBlock
*BB
) const override
{
2016 assert(BB
->getParent() == getAssociatedFunction() &&
2017 "BB must be in the same anchor scope function.");
2021 return !AssumedLiveBlocks
.count(BB
);
2024 /// See AAIsDead::isKnownDead(BasicBlock *).
2025 bool isKnownDead(const BasicBlock
*BB
) const override
{
2026 return getKnown() && isAssumedDead(BB
);
2029 /// See AAIsDead::isAssumed(Instruction *I).
2030 bool isAssumedDead(const Instruction
*I
) const override
{
2031 assert(I
->getParent()->getParent() == getAssociatedFunction() &&
2032 "Instruction must be in the same anchor scope function.");
2037 // If it is not in AssumedLiveBlocks then it for sure dead.
2038 // Otherwise, it can still be after noreturn call in a live block.
2039 if (!AssumedLiveBlocks
.count(I
->getParent()))
2042 // If it is not after a noreturn call, than it is live.
2043 return isAfterNoReturn(I
);
2046 /// See AAIsDead::isKnownDead(Instruction *I).
2047 bool isKnownDead(const Instruction
*I
) const override
{
2048 return getKnown() && isAssumedDead(I
);
2051 /// Check if instruction is after noreturn call, in other words, assumed dead.
2052 bool isAfterNoReturn(const Instruction
*I
) const;
2054 /// Determine if \p F might catch asynchronous exceptions.
2055 static bool mayCatchAsynchronousExceptions(const Function
&F
) {
2056 return F
.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F
);
2059 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2060 /// that internal function called from \p BB should now be looked at.
2061 void assumeLive(Attributor
&A
, const BasicBlock
&BB
) {
2062 if (!AssumedLiveBlocks
.insert(&BB
).second
)
2065 // We assume that all of BB is (probably) live now and if there are calls to
2066 // internal functions we will assume that those are now live as well. This
2067 // is a performance optimization for blocks with calls to a lot of internal
2068 // functions. It can however cause dead functions to be treated as live.
2069 for (const Instruction
&I
: BB
)
2070 if (ImmutableCallSite ICS
= ImmutableCallSite(&I
))
2071 if (const Function
*F
= ICS
.getCalledFunction())
2072 if (F
->hasInternalLinkage())
2073 A
.markLiveInternalFunction(*F
);
2076 /// Collection of to be explored paths.
2077 SmallSetVector
<const Instruction
*, 8> ToBeExploredPaths
;
2079 /// Collection of all assumed live BasicBlocks.
2080 DenseSet
<const BasicBlock
*> AssumedLiveBlocks
;
2082 /// Collection of calls with noreturn attribute, assumed or knwon.
2083 SmallSetVector
<const Instruction
*, 4> NoReturnCalls
;
2086 struct AAIsDeadFunction final
: public AAIsDeadImpl
{
2087 AAIsDeadFunction(const IRPosition
&IRP
) : AAIsDeadImpl(IRP
) {}
2089 /// See AbstractAttribute::trackStatistics()
2090 void trackStatistics() const override
{
2091 STATS_DECL(PartiallyDeadBlocks
, Function
,
2092 "Number of basic blocks classified as partially dead");
2093 BUILD_STAT_NAME(PartiallyDeadBlocks
, Function
) += NoReturnCalls
.size();
2097 bool AAIsDeadImpl::isAfterNoReturn(const Instruction
*I
) const {
2098 const Instruction
*PrevI
= I
->getPrevNode();
2100 if (NoReturnCalls
.count(PrevI
))
2102 PrevI
= PrevI
->getPrevNode();
2107 const Instruction
*AAIsDeadImpl::findNextNoReturn(Attributor
&A
,
2108 const Instruction
*I
) {
2109 const BasicBlock
*BB
= I
->getParent();
2110 const Function
&F
= *BB
->getParent();
2112 // Flag to determine if we can change an invoke to a call assuming the callee
2113 // is nounwind. This is not possible if the personality of the function allows
2114 // to catch asynchronous exceptions.
2115 bool Invoke2CallAllowed
= !mayCatchAsynchronousExceptions(F
);
2117 // TODO: We should have a function that determines if an "edge" is dead.
2118 // Edges could be from an instruction to the next or from a terminator
2119 // to the successor. For now, we need to special case the unwind block
2120 // of InvokeInst below.
2123 ImmutableCallSite
ICS(I
);
2126 const IRPosition
&IPos
= IRPosition::callsite_function(ICS
);
2127 // Regarless of the no-return property of an invoke instruction we only
2128 // learn that the regular successor is not reachable through this
2129 // instruction but the unwind block might still be.
2130 if (auto *Invoke
= dyn_cast
<InvokeInst
>(I
)) {
2131 // Use nounwind to justify the unwind block is dead as well.
2132 const auto &AANoUnw
= A
.getAAFor
<AANoUnwind
>(*this, IPos
);
2133 if (!Invoke2CallAllowed
|| !AANoUnw
.isAssumedNoUnwind()) {
2134 assumeLive(A
, *Invoke
->getUnwindDest());
2135 ToBeExploredPaths
.insert(&Invoke
->getUnwindDest()->front());
2139 const auto &NoReturnAA
= A
.getAAFor
<AANoReturn
>(*this, IPos
);
2140 if (NoReturnAA
.isAssumedNoReturn())
2144 I
= I
->getNextNode();
2147 // get new paths (reachable blocks).
2148 for (const BasicBlock
*SuccBB
: successors(BB
)) {
2149 assumeLive(A
, *SuccBB
);
2150 ToBeExploredPaths
.insert(&SuccBB
->front());
2153 // No noreturn instruction found.
2157 ChangeStatus
AAIsDeadImpl::updateImpl(Attributor
&A
) {
2158 ChangeStatus Status
= ChangeStatus::UNCHANGED
;
2160 // Temporary collection to iterate over existing noreturn instructions. This
2161 // will alow easier modification of NoReturnCalls collection
2162 SmallVector
<const Instruction
*, 8> NoReturnChanged
;
2164 for (const Instruction
*I
: NoReturnCalls
)
2165 NoReturnChanged
.push_back(I
);
2167 for (const Instruction
*I
: NoReturnChanged
) {
2168 size_t Size
= ToBeExploredPaths
.size();
2170 const Instruction
*NextNoReturnI
= findNextNoReturn(A
, I
);
2171 if (NextNoReturnI
!= I
) {
2172 Status
= ChangeStatus::CHANGED
;
2173 NoReturnCalls
.remove(I
);
2175 NoReturnCalls
.insert(NextNoReturnI
);
2178 // Explore new paths.
2179 while (Size
!= ToBeExploredPaths
.size()) {
2180 Status
= ChangeStatus::CHANGED
;
2181 if (const Instruction
*NextNoReturnI
=
2182 findNextNoReturn(A
, ToBeExploredPaths
[Size
++]))
2183 NoReturnCalls
.insert(NextNoReturnI
);
2187 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
2188 << AssumedLiveBlocks
.size() << " Total number of blocks: "
2189 << getAssociatedFunction()->size() << "\n");
2191 // If we know everything is live there is no need to query for liveness.
2192 if (NoReturnCalls
.empty() &&
2193 getAssociatedFunction()->size() == AssumedLiveBlocks
.size()) {
2194 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
2195 // which will cause the Attributor to not return the AAIsDead on request,
2196 // which will prevent us from querying isAssumedDead().
2197 indicatePessimisticFixpoint();
2198 assert(!isValidState() && "Expected an invalid state!");
2199 Status
= ChangeStatus::CHANGED
;
2205 /// Liveness information for a call sites.
2206 struct AAIsDeadCallSite final
: AAIsDeadImpl
{
2207 AAIsDeadCallSite(const IRPosition
&IRP
) : AAIsDeadImpl(IRP
) {}
2209 /// See AbstractAttribute::initialize(...).
2210 void initialize(Attributor
&A
) override
{
2211 // TODO: Once we have call site specific value information we can provide
2212 // call site specific liveness information and then it makes
2213 // sense to specialize attributes for call sites instead of
2214 // redirecting requests to the callee.
2215 llvm_unreachable("Abstract attributes for liveness are not "
2216 "supported for call sites yet!");
2219 /// See AbstractAttribute::updateImpl(...).
2220 ChangeStatus
updateImpl(Attributor
&A
) override
{
2221 return indicatePessimisticFixpoint();
2224 /// See AbstractAttribute::trackStatistics()
2225 void trackStatistics() const override
{}
2228 /// -------------------- Dereferenceable Argument Attribute --------------------
2231 ChangeStatus clampStateAndIndicateChange
<DerefState
>(DerefState
&S
,
2232 const DerefState
&R
) {
2233 ChangeStatus CS0
= clampStateAndIndicateChange
<IntegerState
>(
2234 S
.DerefBytesState
, R
.DerefBytesState
);
2236 clampStateAndIndicateChange
<IntegerState
>(S
.GlobalState
, R
.GlobalState
);
2240 struct AADereferenceableImpl
: AADereferenceable
{
2241 AADereferenceableImpl(const IRPosition
&IRP
) : AADereferenceable(IRP
) {}
2242 using StateType
= DerefState
;
2244 void initialize(Attributor
&A
) override
{
2245 SmallVector
<Attribute
, 4> Attrs
;
2246 getAttrs({Attribute::Dereferenceable
, Attribute::DereferenceableOrNull
},
2248 for (const Attribute
&Attr
: Attrs
)
2249 takeKnownDerefBytesMaximum(Attr
.getValueAsInt());
2251 NonNullAA
= &A
.getAAFor
<AANonNull
>(*this, getIRPosition());
2253 const IRPosition
&IRP
= this->getIRPosition();
2254 bool IsFnInterface
= IRP
.isFnInterfaceKind();
2255 const Function
*FnScope
= IRP
.getAnchorScope();
2256 if (IsFnInterface
&& (!FnScope
|| !FnScope
->hasExactDefinition()))
2257 indicatePessimisticFixpoint();
2260 /// See AbstractAttribute::getState()
2262 StateType
&getState() override
{ return *this; }
2263 const StateType
&getState() const override
{ return *this; }
2266 void getDeducedAttributes(LLVMContext
&Ctx
,
2267 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
2268 // TODO: Add *_globally support
2269 if (isAssumedNonNull())
2270 Attrs
.emplace_back(Attribute::getWithDereferenceableBytes(
2271 Ctx
, getAssumedDereferenceableBytes()));
2273 Attrs
.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2274 Ctx
, getAssumedDereferenceableBytes()));
2277 /// See AbstractAttribute::getAsStr().
2278 const std::string
getAsStr() const override
{
2279 if (!getAssumedDereferenceableBytes())
2280 return "unknown-dereferenceable";
2281 return std::string("dereferenceable") +
2282 (isAssumedNonNull() ? "" : "_or_null") +
2283 (isAssumedGlobal() ? "_globally" : "") + "<" +
2284 std::to_string(getKnownDereferenceableBytes()) + "-" +
2285 std::to_string(getAssumedDereferenceableBytes()) + ">";
2289 /// Dereferenceable attribute for a floating value.
2290 struct AADereferenceableFloating
: AADereferenceableImpl
{
2291 AADereferenceableFloating(const IRPosition
&IRP
)
2292 : AADereferenceableImpl(IRP
) {}
2294 /// See AbstractAttribute::updateImpl(...).
2295 ChangeStatus
updateImpl(Attributor
&A
) override
{
2296 const DataLayout
&DL
= A
.getDataLayout();
2298 auto VisitValueCB
= [&](Value
&V
, DerefState
&T
, bool Stripped
) -> bool {
2300 DL
.getIndexSizeInBits(V
.getType()->getPointerAddressSpace());
2301 APInt
Offset(IdxWidth
, 0);
2303 V
.stripAndAccumulateInBoundsConstantOffsets(DL
, Offset
);
2306 A
.getAAFor
<AADereferenceable
>(*this, IRPosition::value(*Base
));
2307 int64_t DerefBytes
= 0;
2308 if (!Stripped
&& this == &AA
) {
2309 // Use IR information if we did not strip anything.
2310 // TODO: track globally.
2312 DerefBytes
= Base
->getPointerDereferenceableBytes(DL
, CanBeNull
);
2313 T
.GlobalState
.indicatePessimisticFixpoint();
2315 const DerefState
&DS
= static_cast<const DerefState
&>(AA
.getState());
2316 DerefBytes
= DS
.DerefBytesState
.getAssumed();
2317 T
.GlobalState
&= DS
.GlobalState
;
2320 // For now we do not try to "increase" dereferenceability due to negative
2321 // indices as we first have to come up with code to deal with loops and
2322 // for overflows of the dereferenceable bytes.
2323 int64_t OffsetSExt
= Offset
.getSExtValue();
2327 T
.takeAssumedDerefBytesMinimum(
2328 std::max(int64_t(0), DerefBytes
- OffsetSExt
));
2332 // If nothing was stripped IR information is all we got.
2333 T
.takeKnownDerefBytesMaximum(
2334 std::max(int64_t(0), DerefBytes
- OffsetSExt
));
2335 T
.indicatePessimisticFixpoint();
2336 } else if (OffsetSExt
> 0) {
2337 // If something was stripped but there is circular reasoning we look
2338 // for the offset. If it is positive we basically decrease the
2339 // dereferenceable bytes in a circluar loop now, which will simply
2340 // drive them down to the known value in a very slow way which we
2342 T
.indicatePessimisticFixpoint();
2346 return T
.isValidState();
2350 if (!genericValueTraversal
<AADereferenceable
, DerefState
>(
2351 A
, getIRPosition(), *this, T
, VisitValueCB
))
2352 return indicatePessimisticFixpoint();
2354 return clampStateAndIndicateChange(getState(), T
);
2357 /// See AbstractAttribute::trackStatistics()
2358 void trackStatistics() const override
{
2359 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable
)
2363 /// Dereferenceable attribute for a return value.
2364 struct AADereferenceableReturned final
2365 : AAReturnedFromReturnedValues
<AADereferenceable
, AADereferenceableImpl
,
2367 AADereferenceableReturned(const IRPosition
&IRP
)
2368 : AAReturnedFromReturnedValues
<AADereferenceable
, AADereferenceableImpl
,
2371 /// See AbstractAttribute::trackStatistics()
2372 void trackStatistics() const override
{
2373 STATS_DECLTRACK_FNRET_ATTR(dereferenceable
)
2377 /// Dereferenceable attribute for an argument
2378 struct AADereferenceableArgument final
2379 : AAArgumentFromCallSiteArguments
<AADereferenceable
, AADereferenceableImpl
,
2381 AADereferenceableArgument(const IRPosition
&IRP
)
2382 : AAArgumentFromCallSiteArguments
<AADereferenceable
,
2383 AADereferenceableImpl
, DerefState
>(
2386 /// See AbstractAttribute::trackStatistics()
2387 void trackStatistics() const override
{
2388 STATS_DECLTRACK_ARG_ATTR(dereferenceable
)
2392 /// Dereferenceable attribute for a call site argument.
2393 struct AADereferenceableCallSiteArgument final
: AADereferenceableFloating
{
2394 AADereferenceableCallSiteArgument(const IRPosition
&IRP
)
2395 : AADereferenceableFloating(IRP
) {}
2397 /// See AbstractAttribute::trackStatistics()
2398 void trackStatistics() const override
{
2399 STATS_DECLTRACK_CSARG_ATTR(dereferenceable
)
2403 /// Dereferenceable attribute deduction for a call site return value.
2404 struct AADereferenceableCallSiteReturned final
: AADereferenceableImpl
{
2405 AADereferenceableCallSiteReturned(const IRPosition
&IRP
)
2406 : AADereferenceableImpl(IRP
) {}
2408 /// See AbstractAttribute::initialize(...).
2409 void initialize(Attributor
&A
) override
{
2410 AADereferenceableImpl::initialize(A
);
2411 Function
*F
= getAssociatedFunction();
2413 indicatePessimisticFixpoint();
2416 /// See AbstractAttribute::updateImpl(...).
2417 ChangeStatus
updateImpl(Attributor
&A
) override
{
2418 // TODO: Once we have call site specific value information we can provide
2419 // call site specific liveness information and then it makes
2420 // sense to specialize attributes for call sites arguments instead of
2421 // redirecting requests to the callee argument.
2422 Function
*F
= getAssociatedFunction();
2423 const IRPosition
&FnPos
= IRPosition::returned(*F
);
2424 auto &FnAA
= A
.getAAFor
<AADereferenceable
>(*this, FnPos
);
2425 return clampStateAndIndicateChange(
2426 getState(), static_cast<const DerefState
&>(FnAA
.getState()));
2429 /// See AbstractAttribute::trackStatistics()
2430 void trackStatistics() const override
{
2431 STATS_DECLTRACK_CS_ATTR(dereferenceable
);
2435 // ------------------------ Align Argument Attribute ------------------------
2437 struct AAAlignImpl
: AAAlign
{
2438 AAAlignImpl(const IRPosition
&IRP
) : AAAlign(IRP
) {}
2440 // Max alignemnt value allowed in IR
2441 static const unsigned MAX_ALIGN
= 1U << 29;
2443 /// See AbstractAttribute::initialize(...).
2444 void initialize(Attributor
&A
) override
{
2445 takeAssumedMinimum(MAX_ALIGN
);
2447 SmallVector
<Attribute
, 4> Attrs
;
2448 getAttrs({Attribute::Alignment
}, Attrs
);
2449 for (const Attribute
&Attr
: Attrs
)
2450 takeKnownMaximum(Attr
.getValueAsInt());
2452 if (getIRPosition().isFnInterfaceKind() &&
2453 (!getAssociatedFunction() ||
2454 !getAssociatedFunction()->hasExactDefinition()))
2455 indicatePessimisticFixpoint();
2458 /// See AbstractAttribute::manifest(...).
2459 ChangeStatus
manifest(Attributor
&A
) override
{
2460 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
2462 // Check for users that allow alignment annotations.
2463 Value
&AnchorVal
= getIRPosition().getAnchorValue();
2464 for (const Use
&U
: AnchorVal
.uses()) {
2465 if (auto *SI
= dyn_cast
<StoreInst
>(U
.getUser())) {
2466 if (SI
->getPointerOperand() == &AnchorVal
)
2467 if (SI
->getAlignment() < getAssumedAlign()) {
2468 STATS_DECLTRACK(AAAlign
, Store
,
2469 "Number of times alignemnt added to a store");
2470 SI
->setAlignment(getAssumedAlign());
2471 Changed
= ChangeStatus::CHANGED
;
2473 } else if (auto *LI
= dyn_cast
<LoadInst
>(U
.getUser())) {
2474 if (LI
->getPointerOperand() == &AnchorVal
)
2475 if (LI
->getAlignment() < getAssumedAlign()) {
2476 LI
->setAlignment(Align(getAssumedAlign()));
2477 STATS_DECLTRACK(AAAlign
, Load
,
2478 "Number of times alignemnt added to a load");
2479 Changed
= ChangeStatus::CHANGED
;
2484 return AAAlign::manifest(A
) | Changed
;
2487 // TODO: Provide a helper to determine the implied ABI alignment and check in
2488 // the existing manifest method and a new one for AAAlignImpl that value
2489 // to avoid making the alignment explicit if it did not improve.
2491 /// See AbstractAttribute::getDeducedAttributes
2493 getDeducedAttributes(LLVMContext
&Ctx
,
2494 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
2495 if (getAssumedAlign() > 1)
2496 Attrs
.emplace_back(Attribute::getWithAlignment(Ctx
, getAssumedAlign()));
2499 /// See AbstractAttribute::getAsStr().
2500 const std::string
getAsStr() const override
{
2501 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2502 "-" + std::to_string(getAssumedAlign()) + ">")
2507 /// Align attribute for a floating value.
2508 struct AAAlignFloating
: AAAlignImpl
{
2509 AAAlignFloating(const IRPosition
&IRP
) : AAAlignImpl(IRP
) {}
2511 /// See AbstractAttribute::updateImpl(...).
2512 ChangeStatus
updateImpl(Attributor
&A
) override
{
2513 const DataLayout
&DL
= A
.getDataLayout();
2515 auto VisitValueCB
= [&](Value
&V
, AAAlign::StateType
&T
,
2516 bool Stripped
) -> bool {
2517 const auto &AA
= A
.getAAFor
<AAAlign
>(*this, IRPosition::value(V
));
2518 if (!Stripped
&& this == &AA
) {
2519 // Use only IR information if we did not strip anything.
2520 T
.takeKnownMaximum(V
.getPointerAlignment(DL
));
2521 T
.indicatePessimisticFixpoint();
2523 // Use abstract attribute information.
2524 const AAAlign::StateType
&DS
=
2525 static_cast<const AAAlign::StateType
&>(AA
.getState());
2528 return T
.isValidState();
2532 if (!genericValueTraversal
<AAAlign
, StateType
>(A
, getIRPosition(), *this, T
,
2534 return indicatePessimisticFixpoint();
2536 // TODO: If we know we visited all incoming values, thus no are assumed
2537 // dead, we can take the known information from the state T.
2538 return clampStateAndIndicateChange(getState(), T
);
2541 /// See AbstractAttribute::trackStatistics()
2542 void trackStatistics() const override
{ STATS_DECLTRACK_FLOATING_ATTR(align
) }
2545 /// Align attribute for function return value.
2546 struct AAAlignReturned final
2547 : AAReturnedFromReturnedValues
<AAAlign
, AAAlignImpl
> {
2548 AAAlignReturned(const IRPosition
&IRP
)
2549 : AAReturnedFromReturnedValues
<AAAlign
, AAAlignImpl
>(IRP
) {}
2551 /// See AbstractAttribute::trackStatistics()
2552 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(aligned
) }
2555 /// Align attribute for function argument.
2556 struct AAAlignArgument final
2557 : AAArgumentFromCallSiteArguments
<AAAlign
, AAAlignImpl
> {
2558 AAAlignArgument(const IRPosition
&IRP
)
2559 : AAArgumentFromCallSiteArguments
<AAAlign
, AAAlignImpl
>(IRP
) {}
2561 /// See AbstractAttribute::trackStatistics()
2562 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(aligned
) }
2565 struct AAAlignCallSiteArgument final
: AAAlignFloating
{
2566 AAAlignCallSiteArgument(const IRPosition
&IRP
) : AAAlignFloating(IRP
) {}
2568 /// See AbstractAttribute::manifest(...).
2569 ChangeStatus
manifest(Attributor
&A
) override
{
2570 return AAAlignImpl::manifest(A
);
2573 /// See AbstractAttribute::trackStatistics()
2574 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(aligned
) }
2577 /// Align attribute deduction for a call site return value.
2578 struct AAAlignCallSiteReturned final
: AAAlignImpl
{
2579 AAAlignCallSiteReturned(const IRPosition
&IRP
) : AAAlignImpl(IRP
) {}
2581 /// See AbstractAttribute::initialize(...).
2582 void initialize(Attributor
&A
) override
{
2583 AAAlignImpl::initialize(A
);
2584 Function
*F
= getAssociatedFunction();
2586 indicatePessimisticFixpoint();
2589 /// See AbstractAttribute::updateImpl(...).
2590 ChangeStatus
updateImpl(Attributor
&A
) override
{
2591 // TODO: Once we have call site specific value information we can provide
2592 // call site specific liveness information and then it makes
2593 // sense to specialize attributes for call sites arguments instead of
2594 // redirecting requests to the callee argument.
2595 Function
*F
= getAssociatedFunction();
2596 const IRPosition
&FnPos
= IRPosition::returned(*F
);
2597 auto &FnAA
= A
.getAAFor
<AAAlign
>(*this, FnPos
);
2598 return clampStateAndIndicateChange(
2599 getState(), static_cast<const AAAlign::StateType
&>(FnAA
.getState()));
2602 /// See AbstractAttribute::trackStatistics()
2603 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(align
); }
2606 /// ------------------ Function No-Return Attribute ----------------------------
2607 struct AANoReturnImpl
: public AANoReturn
{
2608 AANoReturnImpl(const IRPosition
&IRP
) : AANoReturn(IRP
) {}
2610 /// See AbstractAttribute::getAsStr().
2611 const std::string
getAsStr() const override
{
2612 return getAssumed() ? "noreturn" : "may-return";
2615 /// See AbstractAttribute::updateImpl(Attributor &A).
2616 virtual ChangeStatus
updateImpl(Attributor
&A
) override
{
2617 auto CheckForNoReturn
= [](Instruction
&) { return false; };
2618 if (!A
.checkForAllInstructions(CheckForNoReturn
, *this,
2619 {(unsigned)Instruction::Ret
}))
2620 return indicatePessimisticFixpoint();
2621 return ChangeStatus::UNCHANGED
;
2625 struct AANoReturnFunction final
: AANoReturnImpl
{
2626 AANoReturnFunction(const IRPosition
&IRP
) : AANoReturnImpl(IRP
) {}
2628 /// See AbstractAttribute::trackStatistics()
2629 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(noreturn
) }
2632 /// NoReturn attribute deduction for a call sites.
2633 struct AANoReturnCallSite final
: AANoReturnImpl
{
2634 AANoReturnCallSite(const IRPosition
&IRP
) : AANoReturnImpl(IRP
) {}
2636 /// See AbstractAttribute::initialize(...).
2637 void initialize(Attributor
&A
) override
{
2638 AANoReturnImpl::initialize(A
);
2639 Function
*F
= getAssociatedFunction();
2641 indicatePessimisticFixpoint();
2644 /// See AbstractAttribute::updateImpl(...).
2645 ChangeStatus
updateImpl(Attributor
&A
) override
{
2646 // TODO: Once we have call site specific value information we can provide
2647 // call site specific liveness information and then it makes
2648 // sense to specialize attributes for call sites arguments instead of
2649 // redirecting requests to the callee argument.
2650 Function
*F
= getAssociatedFunction();
2651 const IRPosition
&FnPos
= IRPosition::function(*F
);
2652 auto &FnAA
= A
.getAAFor
<AANoReturn
>(*this, FnPos
);
2653 return clampStateAndIndicateChange(
2655 static_cast<const AANoReturn::StateType
&>(FnAA
.getState()));
2658 /// See AbstractAttribute::trackStatistics()
2659 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(noreturn
); }
2662 /// ----------------------- Variable Capturing ---------------------------------
2664 /// A class to hold the state of for no-capture attributes.
2665 struct AANoCaptureImpl
: public AANoCapture
{
2666 AANoCaptureImpl(const IRPosition
&IRP
) : AANoCapture(IRP
) {}
2668 /// See AbstractAttribute::initialize(...).
2669 void initialize(Attributor
&A
) override
{
2670 AANoCapture::initialize(A
);
2672 const IRPosition
&IRP
= getIRPosition();
2674 getArgNo() >= 0 ? IRP
.getAssociatedFunction() : IRP
.getAnchorScope();
2676 // Check what state the associated function can actually capture.
2678 determineFunctionCaptureCapabilities(*F
, *this);
2680 indicatePessimisticFixpoint();
2683 /// See AbstractAttribute::updateImpl(...).
2684 ChangeStatus
updateImpl(Attributor
&A
) override
;
2686 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
2688 getDeducedAttributes(LLVMContext
&Ctx
,
2689 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
2690 if (!isAssumedNoCaptureMaybeReturned())
2693 if (getArgNo() >= 0) {
2694 if (isAssumedNoCapture())
2695 Attrs
.emplace_back(Attribute::get(Ctx
, Attribute::NoCapture
));
2696 else if (ManifestInternal
)
2697 Attrs
.emplace_back(Attribute::get(Ctx
, "no-capture-maybe-returned"));
2701 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
2702 /// depending on the ability of the function associated with \p IRP to capture
2703 /// state in memory and through "returning/throwing", respectively.
2704 static void determineFunctionCaptureCapabilities(const Function
&F
,
2705 IntegerState
&State
) {
2706 // TODO: Once we have memory behavior attributes we should use them here.
2708 // If we know we cannot communicate or write to memory, we do not care about
2710 if (F
.onlyReadsMemory() && F
.doesNotThrow() &&
2711 F
.getReturnType()->isVoidTy()) {
2712 State
.addKnownBits(NO_CAPTURE
);
2716 // A function cannot capture state in memory if it only reads memory, it can
2717 // however return/throw state and the state might be influenced by the
2718 // pointer value, e.g., loading from a returned pointer might reveal a bit.
2719 if (F
.onlyReadsMemory())
2720 State
.addKnownBits(NOT_CAPTURED_IN_MEM
);
2722 // A function cannot communicate state back if it does not through
2723 // exceptions and doesn not return values.
2724 if (F
.doesNotThrow() && F
.getReturnType()->isVoidTy())
2725 State
.addKnownBits(NOT_CAPTURED_IN_RET
);
2728 /// See AbstractState::getAsStr().
2729 const std::string
getAsStr() const override
{
2730 if (isKnownNoCapture())
2731 return "known not-captured";
2732 if (isAssumedNoCapture())
2733 return "assumed not-captured";
2734 if (isKnownNoCaptureMaybeReturned())
2735 return "known not-captured-maybe-returned";
2736 if (isAssumedNoCaptureMaybeReturned())
2737 return "assumed not-captured-maybe-returned";
2738 return "assumed-captured";
2742 /// Attributor-aware capture tracker.
2743 struct AACaptureUseTracker final
: public CaptureTracker
{
2745 /// Create a capture tracker that can lookup in-flight abstract attributes
2746 /// through the Attributor \p A.
2748 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
2749 /// search is stopped. If a use leads to a return instruction,
2750 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
2751 /// If a use leads to a ptr2int which may capture the value,
2752 /// \p CapturedInInteger is set. If a use is found that is currently assumed
2753 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
2754 /// set. All values in \p PotentialCopies are later tracked as well. For every
2755 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
2756 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
2757 /// conservatively set to true.
2758 AACaptureUseTracker(Attributor
&A
, AANoCapture
&NoCaptureAA
,
2759 const AAIsDead
&IsDeadAA
, IntegerState
&State
,
2760 SmallVectorImpl
<const Value
*> &PotentialCopies
,
2761 unsigned &RemainingUsesToExplore
)
2762 : A(A
), NoCaptureAA(NoCaptureAA
), IsDeadAA(IsDeadAA
), State(State
),
2763 PotentialCopies(PotentialCopies
),
2764 RemainingUsesToExplore(RemainingUsesToExplore
) {}
2766 /// Determine if \p V maybe captured. *Also updates the state!*
2767 bool valueMayBeCaptured(const Value
*V
) {
2768 if (V
->getType()->isPointerTy()) {
2769 PointerMayBeCaptured(V
, this);
2771 State
.indicatePessimisticFixpoint();
2773 return State
.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED
);
2776 /// See CaptureTracker::tooManyUses().
2777 void tooManyUses() override
{
2778 State
.removeAssumedBits(AANoCapture::NO_CAPTURE
);
2781 bool isDereferenceableOrNull(Value
*O
, const DataLayout
&DL
) override
{
2782 if (CaptureTracker::isDereferenceableOrNull(O
, DL
))
2784 const auto &DerefAA
=
2785 A
.getAAFor
<AADereferenceable
>(NoCaptureAA
, IRPosition::value(*O
));
2786 return DerefAA
.getAssumedDereferenceableBytes();
2789 /// See CaptureTracker::captured(...).
2790 bool captured(const Use
*U
) override
{
2791 Instruction
*UInst
= cast
<Instruction
>(U
->getUser());
2792 LLVM_DEBUG(dbgs() << "Check use: " << *U
->get() << " in " << *UInst
2795 // Because we may reuse the tracker multiple times we keep track of the
2796 // number of explored uses ourselves as well.
2797 if (RemainingUsesToExplore
-- == 0) {
2798 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
2799 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2803 // Deal with ptr2int by following uses.
2804 if (isa
<PtrToIntInst
>(UInst
)) {
2805 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
2806 return valueMayBeCaptured(UInst
);
2809 // Explicitly catch return instructions.
2810 if (isa
<ReturnInst
>(UInst
))
2811 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2814 // For now we only use special logic for call sites. However, the tracker
2815 // itself knows about a lot of other non-capturing cases already.
2817 if (!CS
|| !CS
.isArgOperand(U
))
2818 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2821 unsigned ArgNo
= CS
.getArgumentNo(U
);
2822 const IRPosition
&CSArgPos
= IRPosition::callsite_argument(CS
, ArgNo
);
2823 // If we have a abstract no-capture attribute for the argument we can use
2824 // it to justify a non-capture attribute here. This allows recursion!
2825 auto &ArgNoCaptureAA
= A
.getAAFor
<AANoCapture
>(NoCaptureAA
, CSArgPos
);
2826 if (ArgNoCaptureAA
.isAssumedNoCapture())
2827 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2828 /* Return */ false);
2829 if (ArgNoCaptureAA
.isAssumedNoCaptureMaybeReturned()) {
2830 addPotentialCopy(CS
);
2831 return isCapturedIn(/* Memory */ false, /* Integer */ false,
2832 /* Return */ false);
2835 // Lastly, we could not find a reason no-capture can be assumed so we don't.
2836 return isCapturedIn(/* Memory */ true, /* Integer */ true,
2840 /// Register \p CS as potential copy of the value we are checking.
2841 void addPotentialCopy(CallSite CS
) {
2842 PotentialCopies
.push_back(CS
.getInstruction());
2845 /// See CaptureTracker::shouldExplore(...).
2846 bool shouldExplore(const Use
*U
) override
{
2848 return !IsDeadAA
.isAssumedDead(cast
<Instruction
>(U
->getUser()));
2851 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
2852 /// \p CapturedInRet, then return the appropriate value for use in the
2853 /// CaptureTracker::captured() interface.
2854 bool isCapturedIn(bool CapturedInMem
, bool CapturedInInt
,
2855 bool CapturedInRet
) {
2856 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem
<< "|Int "
2857 << CapturedInInt
<< "|Ret " << CapturedInRet
<< "]\n");
2859 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM
);
2861 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT
);
2863 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET
);
2864 return !State
.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED
);
2868 /// The attributor providing in-flight abstract attributes.
2871 /// The abstract attribute currently updated.
2872 AANoCapture
&NoCaptureAA
;
2874 /// The abstract liveness state.
2875 const AAIsDead
&IsDeadAA
;
2877 /// The state currently updated.
2878 IntegerState
&State
;
2880 /// Set of potential copies of the tracked value.
2881 SmallVectorImpl
<const Value
*> &PotentialCopies
;
2883 /// Global counter to limit the number of explored uses.
2884 unsigned &RemainingUsesToExplore
;
2887 ChangeStatus
AANoCaptureImpl::updateImpl(Attributor
&A
) {
2888 const IRPosition
&IRP
= getIRPosition();
2890 getArgNo() >= 0 ? IRP
.getAssociatedArgument() : &IRP
.getAssociatedValue();
2892 return indicatePessimisticFixpoint();
2895 getArgNo() >= 0 ? IRP
.getAssociatedFunction() : IRP
.getAnchorScope();
2896 assert(F
&& "Expected a function!");
2897 const auto &IsDeadAA
= A
.getAAFor
<AAIsDead
>(*this, IRPosition::function(*F
));
2899 AANoCapture::StateType T
;
2900 // TODO: Once we have memory behavior attributes we should use them here
2901 // similar to the reasoning in
2902 // AANoCaptureImpl::determineFunctionCaptureCapabilities(...).
2904 // TODO: Use the AAReturnedValues to learn if the argument can return or
2907 // Use the CaptureTracker interface and logic with the specialized tracker,
2908 // defined in AACaptureUseTracker, that can look at in-flight abstract
2909 // attributes and directly updates the assumed state.
2910 SmallVector
<const Value
*, 4> PotentialCopies
;
2911 unsigned RemainingUsesToExplore
= DefaultMaxUsesToExplore
;
2912 AACaptureUseTracker
Tracker(A
, *this, IsDeadAA
, T
, PotentialCopies
,
2913 RemainingUsesToExplore
);
2915 // Check all potential copies of the associated value until we can assume
2916 // none will be captured or we have to assume at least one might be.
2918 PotentialCopies
.push_back(V
);
2919 while (T
.isAssumed(NO_CAPTURE_MAYBE_RETURNED
) && Idx
< PotentialCopies
.size())
2920 Tracker
.valueMayBeCaptured(PotentialCopies
[Idx
++]);
2922 AAAlign::StateType
&S
= getState();
2923 auto Assumed
= S
.getAssumed();
2924 S
.intersectAssumedBits(T
.getAssumed());
2925 return Assumed
== S
.getAssumed() ? ChangeStatus::UNCHANGED
2926 : ChangeStatus::CHANGED
;
2929 /// NoCapture attribute for function arguments.
2930 struct AANoCaptureArgument final
: AANoCaptureImpl
{
2931 AANoCaptureArgument(const IRPosition
&IRP
) : AANoCaptureImpl(IRP
) {}
2933 /// See AbstractAttribute::trackStatistics()
2934 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nocapture
) }
2937 /// NoCapture attribute for call site arguments.
2938 struct AANoCaptureCallSiteArgument final
: AANoCaptureImpl
{
2939 AANoCaptureCallSiteArgument(const IRPosition
&IRP
) : AANoCaptureImpl(IRP
) {}
2941 /// See AbstractAttribute::updateImpl(...).
2942 ChangeStatus
updateImpl(Attributor
&A
) override
{
2943 // TODO: Once we have call site specific value information we can provide
2944 // call site specific liveness information and then it makes
2945 // sense to specialize attributes for call sites arguments instead of
2946 // redirecting requests to the callee argument.
2947 Argument
*Arg
= getAssociatedArgument();
2949 return indicatePessimisticFixpoint();
2950 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
2951 auto &ArgAA
= A
.getAAFor
<AANoCapture
>(*this, ArgPos
);
2952 return clampStateAndIndicateChange(
2954 static_cast<const AANoCapture::StateType
&>(ArgAA
.getState()));
2957 /// See AbstractAttribute::trackStatistics()
2958 void trackStatistics() const override
{STATS_DECLTRACK_CSARG_ATTR(nocapture
)};
2961 /// NoCapture attribute for floating values.
2962 struct AANoCaptureFloating final
: AANoCaptureImpl
{
2963 AANoCaptureFloating(const IRPosition
&IRP
) : AANoCaptureImpl(IRP
) {}
2965 /// See AbstractAttribute::trackStatistics()
2966 void trackStatistics() const override
{
2967 STATS_DECLTRACK_FLOATING_ATTR(nocapture
)
2971 /// NoCapture attribute for function return value.
2972 struct AANoCaptureReturned final
: AANoCaptureImpl
{
2973 AANoCaptureReturned(const IRPosition
&IRP
) : AANoCaptureImpl(IRP
) {
2974 llvm_unreachable("NoCapture is not applicable to function returns!");
2977 /// See AbstractAttribute::initialize(...).
2978 void initialize(Attributor
&A
) override
{
2979 llvm_unreachable("NoCapture is not applicable to function returns!");
2982 /// See AbstractAttribute::updateImpl(...).
2983 ChangeStatus
updateImpl(Attributor
&A
) override
{
2984 llvm_unreachable("NoCapture is not applicable to function returns!");
2987 /// See AbstractAttribute::trackStatistics()
2988 void trackStatistics() const override
{}
2991 /// NoCapture attribute deduction for a call site return value.
2992 struct AANoCaptureCallSiteReturned final
: AANoCaptureImpl
{
2993 AANoCaptureCallSiteReturned(const IRPosition
&IRP
) : AANoCaptureImpl(IRP
) {}
2995 /// See AbstractAttribute::trackStatistics()
2996 void trackStatistics() const override
{
2997 STATS_DECLTRACK_CSRET_ATTR(nocapture
)
3001 /// ------------------ Value Simplify Attribute ----------------------------
3002 struct AAValueSimplifyImpl
: AAValueSimplify
{
3003 AAValueSimplifyImpl(const IRPosition
&IRP
) : AAValueSimplify(IRP
) {}
3005 /// See AbstractAttribute::getAsStr().
3006 const std::string
getAsStr() const override
{
3007 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3011 /// See AbstractAttribute::trackStatistics()
3012 void trackStatistics() const override
{}
3014 /// See AAValueSimplify::getAssumedSimplifiedValue()
3015 Optional
<Value
*> getAssumedSimplifiedValue(Attributor
&A
) const override
{
3017 return const_cast<Value
*>(&getAssociatedValue());
3018 return SimplifiedAssociatedValue
;
3020 void initialize(Attributor
&A
) override
{}
3022 /// Helper function for querying AAValueSimplify and updating candicate.
3023 /// \param QueryingValue Value trying to unify with SimplifiedValue
3024 /// \param AccumulatedSimplifiedValue Current simplification result.
3025 static bool checkAndUpdate(Attributor
&A
, const AbstractAttribute
&QueryingAA
,
3026 Value
&QueryingValue
,
3027 Optional
<Value
*> &AccumulatedSimplifiedValue
) {
3028 // FIXME: Add a typecast support.
3030 auto &ValueSimpifyAA
= A
.getAAFor
<AAValueSimplify
>(
3031 QueryingAA
, IRPosition::value(QueryingValue
));
3033 Optional
<Value
*> QueryingValueSimplified
=
3034 ValueSimpifyAA
.getAssumedSimplifiedValue(A
);
3036 if (!QueryingValueSimplified
.hasValue())
3039 if (!QueryingValueSimplified
.getValue())
3042 Value
&QueryingValueSimplifiedUnwrapped
=
3043 *QueryingValueSimplified
.getValue();
3045 if (isa
<UndefValue
>(QueryingValueSimplifiedUnwrapped
))
3048 if (AccumulatedSimplifiedValue
.hasValue())
3049 return AccumulatedSimplifiedValue
== QueryingValueSimplified
;
3051 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3052 << " is assumed to be "
3053 << QueryingValueSimplifiedUnwrapped
<< "\n");
3055 AccumulatedSimplifiedValue
= QueryingValueSimplified
;
3059 /// See AbstractAttribute::manifest(...).
3060 ChangeStatus
manifest(Attributor
&A
) override
{
3061 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
3063 if (!SimplifiedAssociatedValue
.hasValue() ||
3064 !SimplifiedAssociatedValue
.getValue())
3067 if (auto *C
= dyn_cast
<Constant
>(SimplifiedAssociatedValue
.getValue())) {
3068 // We can replace the AssociatedValue with the constant.
3069 Value
&V
= getAssociatedValue();
3070 if (!V
.user_empty() && &V
!= C
&& V
.getType() == C
->getType()) {
3071 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V
<< " -> " << *C
3073 V
.replaceAllUsesWith(C
);
3074 Changed
= ChangeStatus::CHANGED
;
3078 return Changed
| AAValueSimplify::manifest(A
);
3082 // An assumed simplified value. Initially, it is set to Optional::None, which
3083 // means that the value is not clear under current assumption. If in the
3084 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3085 // returns orignal associated value.
3086 Optional
<Value
*> SimplifiedAssociatedValue
;
3089 struct AAValueSimplifyArgument final
: AAValueSimplifyImpl
{
3090 AAValueSimplifyArgument(const IRPosition
&IRP
) : AAValueSimplifyImpl(IRP
) {}
3092 /// See AbstractAttribute::updateImpl(...).
3093 ChangeStatus
updateImpl(Attributor
&A
) override
{
3094 bool HasValueBefore
= SimplifiedAssociatedValue
.hasValue();
3096 auto PredForCallSite
= [&](CallSite CS
) {
3097 return checkAndUpdate(A
, *this, *CS
.getArgOperand(getArgNo()),
3098 SimplifiedAssociatedValue
);
3101 if (!A
.checkForAllCallSites(PredForCallSite
, *this, true))
3102 return indicatePessimisticFixpoint();
3104 // If a candicate was found in this update, return CHANGED.
3105 return HasValueBefore
== SimplifiedAssociatedValue
.hasValue()
3106 ? ChangeStatus::UNCHANGED
3107 : ChangeStatus ::CHANGED
;
3110 /// See AbstractAttribute::trackStatistics()
3111 void trackStatistics() const override
{
3112 STATS_DECLTRACK_ARG_ATTR(value_simplify
)
3116 struct AAValueSimplifyReturned
: AAValueSimplifyImpl
{
3117 AAValueSimplifyReturned(const IRPosition
&IRP
) : AAValueSimplifyImpl(IRP
) {}
3119 /// See AbstractAttribute::updateImpl(...).
3120 ChangeStatus
updateImpl(Attributor
&A
) override
{
3121 bool HasValueBefore
= SimplifiedAssociatedValue
.hasValue();
3123 auto PredForReturned
= [&](Value
&V
) {
3124 return checkAndUpdate(A
, *this, V
, SimplifiedAssociatedValue
);
3127 if (!A
.checkForAllReturnedValues(PredForReturned
, *this))
3128 return indicatePessimisticFixpoint();
3130 // If a candicate was found in this update, return CHANGED.
3131 return HasValueBefore
== SimplifiedAssociatedValue
.hasValue()
3132 ? ChangeStatus::UNCHANGED
3133 : ChangeStatus ::CHANGED
;
3135 /// See AbstractAttribute::trackStatistics()
3136 void trackStatistics() const override
{
3137 STATS_DECLTRACK_FNRET_ATTR(value_simplify
)
3141 struct AAValueSimplifyFloating
: AAValueSimplifyImpl
{
3142 AAValueSimplifyFloating(const IRPosition
&IRP
) : AAValueSimplifyImpl(IRP
) {}
3144 /// See AbstractAttribute::initialize(...).
3145 void initialize(Attributor
&A
) override
{
3146 Value
&V
= getAnchorValue();
3148 // TODO: add other stuffs
3149 if (isa
<Constant
>(V
) || isa
<UndefValue
>(V
))
3150 indicatePessimisticFixpoint();
3153 /// See AbstractAttribute::updateImpl(...).
3154 ChangeStatus
updateImpl(Attributor
&A
) override
{
3155 bool HasValueBefore
= SimplifiedAssociatedValue
.hasValue();
3157 auto VisitValueCB
= [&](Value
&V
, BooleanState
, bool Stripped
) -> bool {
3158 auto &AA
= A
.getAAFor
<AAValueSimplify
>(*this, IRPosition::value(V
));
3159 if (!Stripped
&& this == &AA
) {
3160 // TODO: Look the instruction and check recursively.
3162 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3164 indicatePessimisticFixpoint();
3167 return checkAndUpdate(A
, *this, V
, SimplifiedAssociatedValue
);
3170 if (!genericValueTraversal
<AAValueSimplify
, BooleanState
>(
3171 A
, getIRPosition(), *this, static_cast<BooleanState
&>(*this),
3173 return indicatePessimisticFixpoint();
3175 // If a candicate was found in this update, return CHANGED.
3177 return HasValueBefore
== SimplifiedAssociatedValue
.hasValue()
3178 ? ChangeStatus::UNCHANGED
3179 : ChangeStatus ::CHANGED
;
3182 /// See AbstractAttribute::trackStatistics()
3183 void trackStatistics() const override
{
3184 STATS_DECLTRACK_FLOATING_ATTR(value_simplify
)
3188 struct AAValueSimplifyFunction
: AAValueSimplifyImpl
{
3189 AAValueSimplifyFunction(const IRPosition
&IRP
) : AAValueSimplifyImpl(IRP
) {}
3191 /// See AbstractAttribute::initialize(...).
3192 void initialize(Attributor
&A
) override
{
3193 SimplifiedAssociatedValue
= &getAnchorValue();
3194 indicateOptimisticFixpoint();
3196 /// See AbstractAttribute::initialize(...).
3197 ChangeStatus
updateImpl(Attributor
&A
) override
{
3199 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3201 /// See AbstractAttribute::trackStatistics()
3202 void trackStatistics() const override
{
3203 STATS_DECLTRACK_FN_ATTR(value_simplify
)
3207 struct AAValueSimplifyCallSite
: AAValueSimplifyFunction
{
3208 AAValueSimplifyCallSite(const IRPosition
&IRP
)
3209 : AAValueSimplifyFunction(IRP
) {}
3210 /// See AbstractAttribute::trackStatistics()
3211 void trackStatistics() const override
{
3212 STATS_DECLTRACK_CS_ATTR(value_simplify
)
3216 struct AAValueSimplifyCallSiteReturned
: AAValueSimplifyReturned
{
3217 AAValueSimplifyCallSiteReturned(const IRPosition
&IRP
)
3218 : AAValueSimplifyReturned(IRP
) {}
3220 void trackStatistics() const override
{
3221 STATS_DECLTRACK_CSRET_ATTR(value_simplify
)
3224 struct AAValueSimplifyCallSiteArgument
: AAValueSimplifyFloating
{
3225 AAValueSimplifyCallSiteArgument(const IRPosition
&IRP
)
3226 : AAValueSimplifyFloating(IRP
) {}
3228 void trackStatistics() const override
{
3229 STATS_DECLTRACK_CSARG_ATTR(value_simplify
)
3233 /// ----------------------- Heap-To-Stack Conversion ---------------------------
3234 struct AAHeapToStackImpl
: public AAHeapToStack
{
3235 AAHeapToStackImpl(const IRPosition
&IRP
) : AAHeapToStack(IRP
) {}
3237 const std::string
getAsStr() const override
{
3238 return "[H2S] Mallocs: " + std::to_string(MallocCalls
.size());
3241 ChangeStatus
manifest(Attributor
&A
) override
{
3242 assert(getState().isValidState() &&
3243 "Attempted to manifest an invalid state!");
3245 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
3246 Function
*F
= getAssociatedFunction();
3247 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
3249 for (Instruction
*MallocCall
: MallocCalls
) {
3250 // This malloc cannot be replaced.
3251 if (BadMallocCalls
.count(MallocCall
))
3254 for (Instruction
*FreeCall
: FreesForMalloc
[MallocCall
]) {
3255 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall
<< "\n");
3256 A
.deleteAfterManifest(*FreeCall
);
3257 HasChanged
= ChangeStatus::CHANGED
;
3260 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3264 if (isCallocLikeFn(MallocCall
, TLI
)) {
3265 auto *Num
= cast
<ConstantInt
>(MallocCall
->getOperand(0));
3266 auto *SizeT
= dyn_cast
<ConstantInt
>(MallocCall
->getOperand(1));
3267 APInt TotalSize
= SizeT
->getValue() * Num
->getValue();
3269 ConstantInt::get(MallocCall
->getOperand(0)->getType(), TotalSize
);
3271 Size
= cast
<ConstantInt
>(MallocCall
->getOperand(0));
3274 unsigned AS
= cast
<PointerType
>(MallocCall
->getType())->getAddressSpace();
3275 Instruction
*AI
= new AllocaInst(Type::getInt8Ty(F
->getContext()), AS
,
3276 Size
, "", MallocCall
->getNextNode());
3278 if (AI
->getType() != MallocCall
->getType())
3279 AI
= new BitCastInst(AI
, MallocCall
->getType(), "malloc_bc",
3282 MallocCall
->replaceAllUsesWith(AI
);
3284 if (auto *II
= dyn_cast
<InvokeInst
>(MallocCall
)) {
3285 auto *NBB
= II
->getNormalDest();
3286 BranchInst::Create(NBB
, MallocCall
->getParent());
3287 A
.deleteAfterManifest(*MallocCall
);
3289 A
.deleteAfterManifest(*MallocCall
);
3292 if (isCallocLikeFn(MallocCall
, TLI
)) {
3293 auto *BI
= new BitCastInst(AI
, MallocCall
->getType(), "calloc_bc",
3296 BI
, ConstantInt::get(F
->getContext(), APInt(8, 0, false)), Size
,
3297 ConstantInt::get(Type::getInt1Ty(F
->getContext()), false)};
3299 Type
*Tys
[] = {BI
->getType(), MallocCall
->getOperand(0)->getType()};
3300 Module
*M
= F
->getParent();
3301 Function
*Fn
= Intrinsic::getDeclaration(M
, Intrinsic::memset
, Tys
);
3302 CallInst::Create(Fn
, Ops
, "", BI
->getNextNode());
3304 HasChanged
= ChangeStatus::CHANGED
;
3310 /// Collection of all malloc calls in a function.
3311 SmallSetVector
<Instruction
*, 4> MallocCalls
;
3313 /// Collection of malloc calls that cannot be converted.
3314 DenseSet
<const Instruction
*> BadMallocCalls
;
3316 /// A map for each malloc call to the set of associated free calls.
3317 DenseMap
<Instruction
*, SmallPtrSet
<Instruction
*, 4>> FreesForMalloc
;
3319 ChangeStatus
updateImpl(Attributor
&A
) override
;
3322 ChangeStatus
AAHeapToStackImpl::updateImpl(Attributor
&A
) {
3323 const Function
*F
= getAssociatedFunction();
3324 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
3326 auto UsesCheck
= [&](Instruction
&I
) {
3327 SmallPtrSet
<const Use
*, 8> Visited
;
3328 SmallVector
<const Use
*, 8> Worklist
;
3330 for (Use
&U
: I
.uses())
3331 Worklist
.push_back(&U
);
3333 while (!Worklist
.empty()) {
3334 const Use
*U
= Worklist
.pop_back_val();
3335 if (!Visited
.insert(U
).second
)
3338 auto *UserI
= U
->getUser();
3340 if (isa
<LoadInst
>(UserI
) || isa
<StoreInst
>(UserI
))
3343 // NOTE: Right now, if a function that has malloc pointer as an argument
3344 // frees memory, we assume that the malloc pointer is freed.
3346 // TODO: Add nofree callsite argument attribute to indicate that pointer
3347 // argument is not freed.
3348 if (auto *CB
= dyn_cast
<CallBase
>(UserI
)) {
3349 if (!CB
->isArgOperand(U
))
3352 if (CB
->isLifetimeStartOrEnd())
3356 if (isFreeCall(UserI
, TLI
)) {
3357 FreesForMalloc
[&I
].insert(
3358 cast
<Instruction
>(const_cast<User
*>(UserI
)));
3362 // If a function does not free memory we are fine
3363 const auto &NoFreeAA
=
3364 A
.getAAFor
<AANoFree
>(*this, IRPosition::callsite_function(*CB
));
3366 unsigned ArgNo
= U
- CB
->arg_begin();
3367 const auto &NoCaptureAA
= A
.getAAFor
<AANoCapture
>(
3368 *this, IRPosition::callsite_argument(*CB
, ArgNo
));
3370 if (!NoCaptureAA
.isAssumedNoCapture() || !NoFreeAA
.isAssumedNoFree()) {
3371 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI
<< "\n");
3377 if (isa
<GetElementPtrInst
>(UserI
) || isa
<BitCastInst
>(UserI
)) {
3378 for (Use
&U
: UserI
->uses())
3379 Worklist
.push_back(&U
);
3384 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI
<< "\n");
3390 auto MallocCallocCheck
= [&](Instruction
&I
) {
3391 if (isMallocLikeFn(&I
, TLI
)) {
3392 if (auto *Size
= dyn_cast
<ConstantInt
>(I
.getOperand(0)))
3393 if (!Size
->getValue().sle(MaxHeapToStackSize
))
3395 } else if (isCallocLikeFn(&I
, TLI
)) {
3396 bool Overflow
= false;
3397 if (auto *Num
= dyn_cast
<ConstantInt
>(I
.getOperand(0)))
3398 if (auto *Size
= dyn_cast
<ConstantInt
>(I
.getOperand(1)))
3399 if (!(Size
->getValue().umul_ov(Num
->getValue(), Overflow
))
3400 .sle(MaxHeapToStackSize
))
3404 BadMallocCalls
.insert(&I
);
3408 if (BadMallocCalls
.count(&I
))
3412 MallocCalls
.insert(&I
);
3414 BadMallocCalls
.insert(&I
);
3418 size_t NumBadMallocs
= BadMallocCalls
.size();
3420 A
.checkForAllCallLikeInstructions(MallocCallocCheck
, *this);
3422 if (NumBadMallocs
!= BadMallocCalls
.size())
3423 return ChangeStatus::CHANGED
;
3425 return ChangeStatus::UNCHANGED
;
3428 struct AAHeapToStackFunction final
: public AAHeapToStackImpl
{
3429 AAHeapToStackFunction(const IRPosition
&IRP
) : AAHeapToStackImpl(IRP
) {}
3431 /// See AbstractAttribute::trackStatistics()
3432 void trackStatistics() const override
{
3433 STATS_DECL(MallocCalls
, Function
,
3434 "Number of MallocCalls converted to allocas");
3435 BUILD_STAT_NAME(MallocCalls
, Function
) += MallocCalls
.size();
3440 /// ----------------------------------------------------------------------------
3442 /// ----------------------------------------------------------------------------
3444 bool Attributor::isAssumedDead(const AbstractAttribute
&AA
,
3445 const AAIsDead
*LivenessAA
) {
3446 const Instruction
*CtxI
= AA
.getIRPosition().getCtxI();
3452 &getAAFor
<AAIsDead
>(AA
, IRPosition::function(*CtxI
->getFunction()),
3453 /* TrackDependence */ false);
3455 // Don't check liveness for AAIsDead.
3456 if (&AA
== LivenessAA
)
3459 if (!LivenessAA
->isAssumedDead(CtxI
))
3462 // We actually used liveness information so we have to record a dependence.
3463 recordDependence(*LivenessAA
, AA
);
3468 bool Attributor::checkForAllCallSites(const function_ref
<bool(CallSite
)> &Pred
,
3469 const AbstractAttribute
&QueryingAA
,
3470 bool RequireAllCallSites
) {
3471 // We can try to determine information from
3472 // the call sites. However, this is only possible all call sites are known,
3473 // hence the function has internal linkage.
3474 const IRPosition
&IRP
= QueryingAA
.getIRPosition();
3475 const Function
*AssociatedFunction
= IRP
.getAssociatedFunction();
3476 if (!AssociatedFunction
)
3479 if (RequireAllCallSites
&& !AssociatedFunction
->hasInternalLinkage()) {
3482 << "[Attributor] Function " << AssociatedFunction
->getName()
3483 << " has no internal linkage, hence not all call sites are known\n");
3487 for (const Use
&U
: AssociatedFunction
->uses()) {
3488 Instruction
*I
= dyn_cast
<Instruction
>(U
.getUser());
3489 // TODO: Deal with abstract call sites here.
3493 Function
*Caller
= I
->getFunction();
3495 const auto &LivenessAA
= getAAFor
<AAIsDead
>(
3496 QueryingAA
, IRPosition::function(*Caller
), /* TrackDependence */ false);
3499 if (LivenessAA
.isAssumedDead(I
)) {
3500 // We actually used liveness information so we have to record a
3502 recordDependence(LivenessAA
, QueryingAA
);
3506 CallSite
CS(U
.getUser());
3507 if (!CS
|| !CS
.isCallee(&U
)) {
3508 if (!RequireAllCallSites
)
3511 LLVM_DEBUG(dbgs() << "[Attributor] User " << *U
.getUser()
3512 << " is an invalid use of "
3513 << AssociatedFunction
->getName() << "\n");
3520 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
3521 << *CS
.getInstruction() << "\n");
3528 bool Attributor::checkForAllReturnedValuesAndReturnInsts(
3529 const function_ref
<bool(Value
&, const SmallSetVector
<ReturnInst
*, 4> &)>
3531 const AbstractAttribute
&QueryingAA
) {
3533 const IRPosition
&IRP
= QueryingAA
.getIRPosition();
3534 // Since we need to provide return instructions we have to have an exact
3536 const Function
*AssociatedFunction
= IRP
.getAssociatedFunction();
3537 if (!AssociatedFunction
)
3540 // If this is a call site query we use the call site specific return values
3541 // and liveness information.
3542 // TODO: use the function scope once we have call site AAReturnedValues.
3543 const IRPosition
&QueryIRP
= IRPosition::function(*AssociatedFunction
);
3544 const auto &AARetVal
= getAAFor
<AAReturnedValues
>(QueryingAA
, QueryIRP
);
3545 if (!AARetVal
.getState().isValidState())
3548 return AARetVal
.checkForAllReturnedValuesAndReturnInsts(Pred
);
3551 bool Attributor::checkForAllReturnedValues(
3552 const function_ref
<bool(Value
&)> &Pred
,
3553 const AbstractAttribute
&QueryingAA
) {
3555 const IRPosition
&IRP
= QueryingAA
.getIRPosition();
3556 const Function
*AssociatedFunction
= IRP
.getAssociatedFunction();
3557 if (!AssociatedFunction
)
3560 // TODO: use the function scope once we have call site AAReturnedValues.
3561 const IRPosition
&QueryIRP
= IRPosition::function(*AssociatedFunction
);
3562 const auto &AARetVal
= getAAFor
<AAReturnedValues
>(QueryingAA
, QueryIRP
);
3563 if (!AARetVal
.getState().isValidState())
3566 return AARetVal
.checkForAllReturnedValuesAndReturnInsts(
3567 [&](Value
&RV
, const SmallSetVector
<ReturnInst
*, 4> &) {
3573 checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy
&OpcodeInstMap
,
3574 const function_ref
<bool(Instruction
&)> &Pred
,
3575 const AAIsDead
*LivenessAA
, bool &AnyDead
,
3576 const ArrayRef
<unsigned> &Opcodes
) {
3577 for (unsigned Opcode
: Opcodes
) {
3578 for (Instruction
*I
: OpcodeInstMap
[Opcode
]) {
3579 // Skip dead instructions.
3580 if (LivenessAA
&& LivenessAA
->isAssumedDead(I
)) {
3592 bool Attributor::checkForAllInstructions(
3593 const llvm::function_ref
<bool(Instruction
&)> &Pred
,
3594 const AbstractAttribute
&QueryingAA
, const ArrayRef
<unsigned> &Opcodes
) {
3596 const IRPosition
&IRP
= QueryingAA
.getIRPosition();
3597 // Since we need to provide instructions we have to have an exact definition.
3598 const Function
*AssociatedFunction
= IRP
.getAssociatedFunction();
3599 if (!AssociatedFunction
)
3602 // TODO: use the function scope once we have call site AAReturnedValues.
3603 const IRPosition
&QueryIRP
= IRPosition::function(*AssociatedFunction
);
3604 const auto &LivenessAA
=
3605 getAAFor
<AAIsDead
>(QueryingAA
, QueryIRP
, /* TrackDependence */ false);
3606 bool AnyDead
= false;
3608 auto &OpcodeInstMap
=
3609 InfoCache
.getOpcodeInstMapForFunction(*AssociatedFunction
);
3610 if (!checkForAllInstructionsImpl(OpcodeInstMap
, Pred
, &LivenessAA
, AnyDead
, Opcodes
))
3613 // If we actually used liveness information so we have to record a dependence.
3615 recordDependence(LivenessAA
, QueryingAA
);
3620 bool Attributor::checkForAllReadWriteInstructions(
3621 const llvm::function_ref
<bool(Instruction
&)> &Pred
,
3622 AbstractAttribute
&QueryingAA
) {
3624 const Function
*AssociatedFunction
=
3625 QueryingAA
.getIRPosition().getAssociatedFunction();
3626 if (!AssociatedFunction
)
3629 // TODO: use the function scope once we have call site AAReturnedValues.
3630 const IRPosition
&QueryIRP
= IRPosition::function(*AssociatedFunction
);
3631 const auto &LivenessAA
=
3632 getAAFor
<AAIsDead
>(QueryingAA
, QueryIRP
, /* TrackDependence */ false);
3633 bool AnyDead
= false;
3635 for (Instruction
*I
:
3636 InfoCache
.getReadOrWriteInstsForFunction(*AssociatedFunction
)) {
3637 // Skip dead instructions.
3638 if (LivenessAA
.isAssumedDead(I
)) {
3647 // If we actually used liveness information so we have to record a dependence.
3649 recordDependence(LivenessAA
, QueryingAA
);
3654 ChangeStatus
Attributor::run(Module
&M
) {
3655 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
3656 << AllAbstractAttributes
.size()
3657 << " abstract attributes.\n");
3659 // Now that all abstract attributes are collected and initialized we start
3660 // the abstract analysis.
3662 unsigned IterationCounter
= 1;
3664 SmallVector
<AbstractAttribute
*, 64> ChangedAAs
;
3665 SetVector
<AbstractAttribute
*> Worklist
;
3666 Worklist
.insert(AllAbstractAttributes
.begin(), AllAbstractAttributes
.end());
3668 bool RecomputeDependences
= false;
3671 // Remember the size to determine new attributes.
3672 size_t NumAAs
= AllAbstractAttributes
.size();
3673 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
3674 << ", Worklist size: " << Worklist
.size() << "\n");
3676 // If dependences (=QueryMap) are recomputed we have to look at all abstract
3677 // attributes again, regardless of what changed in the last iteration.
3678 if (RecomputeDependences
) {
3680 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
3683 Worklist
.insert(AllAbstractAttributes
.begin(),
3684 AllAbstractAttributes
.end());
3687 // Add all abstract attributes that are potentially dependent on one that
3688 // changed to the work list.
3689 for (AbstractAttribute
*ChangedAA
: ChangedAAs
) {
3690 auto &QuerriedAAs
= QueryMap
[ChangedAA
];
3691 Worklist
.insert(QuerriedAAs
.begin(), QuerriedAAs
.end());
3694 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
3695 << ", Worklist+Dependent size: " << Worklist
.size()
3698 // Reset the changed set.
3701 // Update all abstract attribute in the work list and record the ones that
3703 for (AbstractAttribute
*AA
: Worklist
)
3704 if (!isAssumedDead(*AA
, nullptr))
3705 if (AA
->update(*this) == ChangeStatus::CHANGED
)
3706 ChangedAAs
.push_back(AA
);
3708 // Check if we recompute the dependences in the next iteration.
3709 RecomputeDependences
= (DepRecomputeInterval
> 0 &&
3710 IterationCounter
% DepRecomputeInterval
== 0);
3712 // Add attributes to the changed set if they have been created in the last
3714 ChangedAAs
.append(AllAbstractAttributes
.begin() + NumAAs
,
3715 AllAbstractAttributes
.end());
3717 // Reset the work list and repopulate with the changed abstract attributes.
3718 // Note that dependent ones are added above.
3720 Worklist
.insert(ChangedAAs
.begin(), ChangedAAs
.end());
3722 } while (!Worklist
.empty() && (IterationCounter
++ < MaxFixpointIterations
||
3723 VerifyMaxFixpointIterations
));
3725 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
3726 << IterationCounter
<< "/" << MaxFixpointIterations
3727 << " iterations\n");
3729 size_t NumFinalAAs
= AllAbstractAttributes
.size();
3731 bool FinishedAtFixpoint
= Worklist
.empty();
3733 // Reset abstract arguments not settled in a sound fixpoint by now. This
3734 // happens when we stopped the fixpoint iteration early. Note that only the
3735 // ones marked as "changed" *and* the ones transitively depending on them
3736 // need to be reverted to a pessimistic state. Others might not be in a
3737 // fixpoint state but we can use the optimistic results for them anyway.
3738 SmallPtrSet
<AbstractAttribute
*, 32> Visited
;
3739 for (unsigned u
= 0; u
< ChangedAAs
.size(); u
++) {
3740 AbstractAttribute
*ChangedAA
= ChangedAAs
[u
];
3741 if (!Visited
.insert(ChangedAA
).second
)
3744 AbstractState
&State
= ChangedAA
->getState();
3745 if (!State
.isAtFixpoint()) {
3746 State
.indicatePessimisticFixpoint();
3748 NumAttributesTimedOut
++;
3751 auto &QuerriedAAs
= QueryMap
[ChangedAA
];
3752 ChangedAAs
.append(QuerriedAAs
.begin(), QuerriedAAs
.end());
3756 if (!Visited
.empty())
3757 dbgs() << "\n[Attributor] Finalized " << Visited
.size()
3758 << " abstract attributes.\n";
3761 unsigned NumManifested
= 0;
3762 unsigned NumAtFixpoint
= 0;
3763 ChangeStatus ManifestChange
= ChangeStatus::UNCHANGED
;
3764 for (AbstractAttribute
*AA
: AllAbstractAttributes
) {
3765 AbstractState
&State
= AA
->getState();
3767 // If there is not already a fixpoint reached, we can now take the
3768 // optimistic state. This is correct because we enforced a pessimistic one
3769 // on abstract attributes that were transitively dependent on a changed one
3771 if (!State
.isAtFixpoint())
3772 State
.indicateOptimisticFixpoint();
3774 // If the state is invalid, we do not try to manifest it.
3775 if (!State
.isValidState())
3779 if (isAssumedDead(*AA
, nullptr))
3781 // Manifest the state and record if we changed the IR.
3782 ChangeStatus LocalChange
= AA
->manifest(*this);
3783 if (LocalChange
== ChangeStatus::CHANGED
&& AreStatisticsEnabled())
3784 AA
->trackStatistics();
3786 ManifestChange
= ManifestChange
| LocalChange
;
3789 NumManifested
+= (LocalChange
== ChangeStatus::CHANGED
);
3792 (void)NumManifested
;
3793 (void)NumAtFixpoint
;
3794 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
3795 << " arguments while " << NumAtFixpoint
3796 << " were in a valid fixpoint state\n");
3798 // If verification is requested, we finished this run at a fixpoint, and the
3799 // IR was changed, we re-run the whole fixpoint analysis, starting at
3800 // re-initialization of the arguments. This re-run should not result in an IR
3801 // change. Though, the (virtual) state of attributes at the end of the re-run
3802 // might be more optimistic than the known state or the IR state if the better
3803 // state cannot be manifested.
3804 if (VerifyAttributor
&& FinishedAtFixpoint
&&
3805 ManifestChange
== ChangeStatus::CHANGED
) {
3806 VerifyAttributor
= false;
3807 ChangeStatus VerifyStatus
= run(M
);
3808 if (VerifyStatus
!= ChangeStatus::UNCHANGED
)
3810 "Attributor verification failed, re-run did result in an IR change "
3811 "even after a fixpoint was reached in the original run. (False "
3812 "positives possible!)");
3813 VerifyAttributor
= true;
3816 NumAttributesManifested
+= NumManifested
;
3817 NumAttributesValidFixpoint
+= NumAtFixpoint
;
3821 NumFinalAAs
== AllAbstractAttributes
.size() &&
3822 "Expected the final number of abstract attributes to remain unchanged!");
3824 // Delete stuff at the end to avoid invalid references and a nice order.
3826 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
3827 << ToBeDeletedFunctions
.size() << " functions and "
3828 << ToBeDeletedBlocks
.size() << " blocks and "
3829 << ToBeDeletedInsts
.size() << " instructions\n");
3830 for (Instruction
*I
: ToBeDeletedInsts
) {
3831 if (!I
->use_empty())
3832 I
->replaceAllUsesWith(UndefValue::get(I
->getType()));
3833 I
->eraseFromParent();
3836 if (unsigned NumDeadBlocks
= ToBeDeletedBlocks
.size()) {
3837 SmallVector
<BasicBlock
*, 8> ToBeDeletedBBs
;
3838 ToBeDeletedBBs
.reserve(NumDeadBlocks
);
3839 ToBeDeletedBBs
.append(ToBeDeletedBlocks
.begin(), ToBeDeletedBlocks
.end());
3840 DeleteDeadBlocks(ToBeDeletedBBs
);
3841 STATS_DECLTRACK(AAIsDead
, BasicBlock
,
3842 "Number of dead basic blocks deleted.");
3845 STATS_DECL(AAIsDead
, Function
, "Number of dead functions deleted.");
3846 for (Function
*Fn
: ToBeDeletedFunctions
) {
3847 Fn
->replaceAllUsesWith(UndefValue::get(Fn
->getType()));
3848 Fn
->eraseFromParent();
3849 STATS_TRACK(AAIsDead
, Function
);
3852 // Identify dead internal functions and delete them. This happens outside
3853 // the other fixpoint analysis as we might treat potentially dead functions
3854 // as live to lower the number of iterations. If they happen to be dead, the
3855 // below fixpoint loop will identify and eliminate them.
3856 SmallVector
<Function
*, 8> InternalFns
;
3857 for (Function
&F
: M
)
3858 if (F
.hasInternalLinkage())
3859 InternalFns
.push_back(&F
);
3861 bool FoundDeadFn
= true;
3862 while (FoundDeadFn
) {
3863 FoundDeadFn
= false;
3864 for (unsigned u
= 0, e
= InternalFns
.size(); u
< e
; ++u
) {
3865 Function
*F
= InternalFns
[u
];
3869 const auto *LivenessAA
=
3870 lookupAAFor
<AAIsDead
>(IRPosition::function(*F
));
3872 !checkForAllCallSites([](CallSite CS
) { return false; },
3876 STATS_TRACK(AAIsDead
, Function
);
3877 F
->replaceAllUsesWith(UndefValue::get(F
->getType()));
3878 F
->eraseFromParent();
3879 InternalFns
[u
] = nullptr;
3885 if (VerifyMaxFixpointIterations
&&
3886 IterationCounter
!= MaxFixpointIterations
) {
3887 errs() << "\n[Attributor] Fixpoint iteration done after: "
3888 << IterationCounter
<< "/" << MaxFixpointIterations
3890 llvm_unreachable("The fixpoint was not reached with exactly the number of "
3891 "specified iterations!");
3894 return ManifestChange
;
3897 void Attributor::initializeInformationCache(Function
&F
) {
3899 // Walk all instructions to find interesting instructions that might be
3900 // queried by abstract attributes during their initialization or update.
3901 // This has to happen before we create attributes.
3902 auto &ReadOrWriteInsts
= InfoCache
.FuncRWInstsMap
[&F
];
3903 auto &InstOpcodeMap
= InfoCache
.FuncInstOpcodeMap
[&F
];
3905 for (Instruction
&I
: instructions(&F
)) {
3906 bool IsInterestingOpcode
= false;
3908 // To allow easy access to all instructions in a function with a given
3909 // opcode we store them in the InfoCache. As not all opcodes are interesting
3910 // to concrete attributes we only cache the ones that are as identified in
3911 // the following switch.
3912 // Note: There are no concrete attributes now so this is initially empty.
3913 switch (I
.getOpcode()) {
3915 assert((!ImmutableCallSite(&I
)) && (!isa
<CallBase
>(&I
)) &&
3916 "New call site/base instruction type needs to be known int the "
3919 case Instruction::Load
:
3920 // The alignment of a pointer is interesting for loads.
3921 case Instruction::Store
:
3922 // The alignment of a pointer is interesting for stores.
3923 case Instruction::Call
:
3924 case Instruction::CallBr
:
3925 case Instruction::Invoke
:
3926 case Instruction::CleanupRet
:
3927 case Instruction::CatchSwitch
:
3928 case Instruction::Resume
:
3929 case Instruction::Ret
:
3930 IsInterestingOpcode
= true;
3932 if (IsInterestingOpcode
)
3933 InstOpcodeMap
[I
.getOpcode()].push_back(&I
);
3934 if (I
.mayReadOrWriteMemory())
3935 ReadOrWriteInsts
.push_back(&I
);
3939 void Attributor::identifyDefaultAbstractAttributes(Function
&F
) {
3940 if (!VisitedFunctions
.insert(&F
).second
)
3943 IRPosition FPos
= IRPosition::function(F
);
3945 // Check for dead BasicBlocks in every function.
3946 // We need dead instruction detection because we do not want to deal with
3947 // broken IR in which SSA rules do not apply.
3948 getOrCreateAAFor
<AAIsDead
>(FPos
);
3950 // Every function might be "will-return".
3951 getOrCreateAAFor
<AAWillReturn
>(FPos
);
3953 // Every function can be nounwind.
3954 getOrCreateAAFor
<AANoUnwind
>(FPos
);
3956 // Every function might be marked "nosync"
3957 getOrCreateAAFor
<AANoSync
>(FPos
);
3959 // Every function might be "no-free".
3960 getOrCreateAAFor
<AANoFree
>(FPos
);
3962 // Every function might be "no-return".
3963 getOrCreateAAFor
<AANoReturn
>(FPos
);
3965 // Every function might be "no-recurse".
3966 getOrCreateAAFor
<AANoRecurse
>(FPos
);
3968 // Every function might be applicable for Heap-To-Stack conversion.
3969 if (EnableHeapToStack
)
3970 getOrCreateAAFor
<AAHeapToStack
>(FPos
);
3972 // Return attributes are only appropriate if the return type is non void.
3973 Type
*ReturnType
= F
.getReturnType();
3974 if (!ReturnType
->isVoidTy()) {
3975 // Argument attribute "returned" --- Create only one per function even
3976 // though it is an argument attribute.
3977 getOrCreateAAFor
<AAReturnedValues
>(FPos
);
3979 IRPosition RetPos
= IRPosition::returned(F
);
3981 // Every function might be simplified.
3982 getOrCreateAAFor
<AAValueSimplify
>(RetPos
);
3984 if (ReturnType
->isPointerTy()) {
3986 // Every function with pointer return type might be marked align.
3987 getOrCreateAAFor
<AAAlign
>(RetPos
);
3989 // Every function with pointer return type might be marked nonnull.
3990 getOrCreateAAFor
<AANonNull
>(RetPos
);
3992 // Every function with pointer return type might be marked noalias.
3993 getOrCreateAAFor
<AANoAlias
>(RetPos
);
3995 // Every function with pointer return type might be marked
3997 getOrCreateAAFor
<AADereferenceable
>(RetPos
);
4001 for (Argument
&Arg
: F
.args()) {
4002 IRPosition ArgPos
= IRPosition::argument(Arg
);
4004 // Every argument might be simplified.
4005 getOrCreateAAFor
<AAValueSimplify
>(ArgPos
);
4007 if (Arg
.getType()->isPointerTy()) {
4008 // Every argument with pointer type might be marked nonnull.
4009 getOrCreateAAFor
<AANonNull
>(ArgPos
);
4011 // Every argument with pointer type might be marked noalias.
4012 getOrCreateAAFor
<AANoAlias
>(ArgPos
);
4014 // Every argument with pointer type might be marked dereferenceable.
4015 getOrCreateAAFor
<AADereferenceable
>(ArgPos
);
4017 // Every argument with pointer type might be marked align.
4018 getOrCreateAAFor
<AAAlign
>(ArgPos
);
4020 // Every argument with pointer type might be marked nocapture.
4021 getOrCreateAAFor
<AANoCapture
>(ArgPos
);
4025 auto CallSitePred
= [&](Instruction
&I
) -> bool {
4027 if (CS
.getCalledFunction()) {
4028 for (int i
= 0, e
= CS
.getCalledFunction()->arg_size(); i
< e
; i
++) {
4030 IRPosition CSArgPos
= IRPosition::callsite_argument(CS
, i
);
4032 // Call site argument might be simplified.
4033 getOrCreateAAFor
<AAValueSimplify
>(CSArgPos
);
4035 if (!CS
.getArgument(i
)->getType()->isPointerTy())
4038 // Call site argument attribute "non-null".
4039 getOrCreateAAFor
<AANonNull
>(CSArgPos
);
4041 // Call site argument attribute "no-alias".
4042 getOrCreateAAFor
<AANoAlias
>(CSArgPos
);
4044 // Call site argument attribute "dereferenceable".
4045 getOrCreateAAFor
<AADereferenceable
>(CSArgPos
);
4047 // Call site argument attribute "align".
4048 getOrCreateAAFor
<AAAlign
>(CSArgPos
);
4054 auto &OpcodeInstMap
= InfoCache
.getOpcodeInstMapForFunction(F
);
4055 bool Success
, AnyDead
= false;
4056 Success
= checkForAllInstructionsImpl(
4057 OpcodeInstMap
, CallSitePred
, nullptr, AnyDead
,
4058 {(unsigned)Instruction::Invoke
, (unsigned)Instruction::CallBr
,
4059 (unsigned)Instruction::Call
});
4061 assert(Success
&& !AnyDead
&& "Expected the check call to be successful!");
4063 auto LoadStorePred
= [&](Instruction
&I
) -> bool {
4064 if (isa
<LoadInst
>(I
))
4065 getOrCreateAAFor
<AAAlign
>(
4066 IRPosition::value(*cast
<LoadInst
>(I
).getPointerOperand()));
4068 getOrCreateAAFor
<AAAlign
>(
4069 IRPosition::value(*cast
<StoreInst
>(I
).getPointerOperand()));
4072 Success
= checkForAllInstructionsImpl(
4073 OpcodeInstMap
, LoadStorePred
, nullptr, AnyDead
,
4074 {(unsigned)Instruction::Load
, (unsigned)Instruction::Store
});
4076 assert(Success
&& !AnyDead
&& "Expected the check call to be successful!");
4079 /// Helpers to ease debugging through output streams and print calls.
4082 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, ChangeStatus S
) {
4083 return OS
<< (S
== ChangeStatus::CHANGED
? "changed" : "unchanged");
4086 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, IRPosition::Kind AP
) {
4088 case IRPosition::IRP_INVALID
:
4090 case IRPosition::IRP_FLOAT
:
4092 case IRPosition::IRP_RETURNED
:
4093 return OS
<< "fn_ret";
4094 case IRPosition::IRP_CALL_SITE_RETURNED
:
4095 return OS
<< "cs_ret";
4096 case IRPosition::IRP_FUNCTION
:
4098 case IRPosition::IRP_CALL_SITE
:
4100 case IRPosition::IRP_ARGUMENT
:
4102 case IRPosition::IRP_CALL_SITE_ARGUMENT
:
4103 return OS
<< "cs_arg";
4105 llvm_unreachable("Unknown attribute position!");
4108 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, const IRPosition
&Pos
) {
4109 const Value
&AV
= Pos
.getAssociatedValue();
4110 return OS
<< "{" << Pos
.getPositionKind() << ":" << AV
.getName() << " ["
4111 << Pos
.getAnchorValue().getName() << "@" << Pos
.getArgNo() << "]}";
4114 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, const IntegerState
&S
) {
4115 return OS
<< "(" << S
.getKnown() << "-" << S
.getAssumed() << ")"
4116 << static_cast<const AbstractState
&>(S
);
4119 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, const AbstractState
&S
) {
4120 return OS
<< (!S
.isValidState() ? "top" : (S
.isAtFixpoint() ? "fix" : ""));
4123 raw_ostream
&llvm::operator<<(raw_ostream
&OS
, const AbstractAttribute
&AA
) {
4128 void AbstractAttribute::print(raw_ostream
&OS
) const {
4129 OS
<< "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
4134 /// ----------------------------------------------------------------------------
4135 /// Pass (Manager) Boilerplate
4136 /// ----------------------------------------------------------------------------
4138 static bool runAttributorOnModule(Module
&M
, AnalysisGetter
&AG
) {
4139 if (DisableAttributor
)
4142 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M
.size()
4143 << " functions.\n");
4145 // Create an Attributor and initially empty information cache that is filled
4146 // while we identify default attribute opportunities.
4147 InformationCache
InfoCache(M
, AG
);
4148 Attributor
A(InfoCache
, DepRecInterval
);
4150 for (Function
&F
: M
)
4151 A
.initializeInformationCache(F
);
4153 for (Function
&F
: M
) {
4154 if (F
.hasExactDefinition())
4155 NumFnWithExactDefinition
++;
4157 NumFnWithoutExactDefinition
++;
4159 // For now we ignore naked and optnone functions.
4160 if (F
.hasFnAttribute(Attribute::Naked
) ||
4161 F
.hasFnAttribute(Attribute::OptimizeNone
))
4164 // We look at internal functions only on-demand but if any use is not a
4165 // direct call, we have to do it eagerly.
4166 if (F
.hasInternalLinkage()) {
4167 if (llvm::all_of(F
.uses(), [](const Use
&U
) {
4168 return ImmutableCallSite(U
.getUser()) &&
4169 ImmutableCallSite(U
.getUser()).isCallee(&U
);
4174 // Populate the Attributor with abstract attribute opportunities in the
4175 // function and the information cache with IR information.
4176 A
.identifyDefaultAbstractAttributes(F
);
4179 return A
.run(M
) == ChangeStatus::CHANGED
;
4182 PreservedAnalyses
AttributorPass::run(Module
&M
, ModuleAnalysisManager
&AM
) {
4183 AnalysisGetter
AG(AM
);
4184 if (runAttributorOnModule(M
, AG
)) {
4185 // FIXME: Think about passes we will preserve and add them here.
4186 return PreservedAnalyses::none();
4188 return PreservedAnalyses::all();
4193 struct AttributorLegacyPass
: public ModulePass
{
4196 AttributorLegacyPass() : ModulePass(ID
) {
4197 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
4200 bool runOnModule(Module
&M
) override
{
4205 return runAttributorOnModule(M
, AG
);
4208 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
4209 // FIXME: Think about passes we will preserve and add them here.
4210 AU
.addRequired
<TargetLibraryInfoWrapperPass
>();
4214 } // end anonymous namespace
4216 Pass
*llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
4218 char AttributorLegacyPass::ID
= 0;
4220 const char AAReturnedValues::ID
= 0;
4221 const char AANoUnwind::ID
= 0;
4222 const char AANoSync::ID
= 0;
4223 const char AANoFree::ID
= 0;
4224 const char AANonNull::ID
= 0;
4225 const char AANoRecurse::ID
= 0;
4226 const char AAWillReturn::ID
= 0;
4227 const char AANoAlias::ID
= 0;
4228 const char AANoReturn::ID
= 0;
4229 const char AAIsDead::ID
= 0;
4230 const char AADereferenceable::ID
= 0;
4231 const char AAAlign::ID
= 0;
4232 const char AANoCapture::ID
= 0;
4233 const char AAValueSimplify::ID
= 0;
4234 const char AAHeapToStack::ID
= 0;
4236 // Macro magic to create the static generator function for attributes that
4237 // follow the naming scheme.
4239 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
4240 case IRPosition::PK: \
4241 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
4243 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
4244 case IRPosition::PK: \
4245 AA = new CLASS##SUFFIX(IRP); \
4248 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4249 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4250 CLASS *AA = nullptr; \
4251 switch (IRP.getPositionKind()) { \
4252 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4253 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4254 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4255 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4256 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4257 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4258 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4259 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4264 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4265 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4266 CLASS *AA = nullptr; \
4267 switch (IRP.getPositionKind()) { \
4268 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4269 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
4270 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4271 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4272 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4273 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4274 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4275 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4280 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4281 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4282 CLASS *AA = nullptr; \
4283 switch (IRP.getPositionKind()) { \
4284 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4285 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4286 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4287 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4288 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4289 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4290 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4291 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4296 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4297 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4298 CLASS *AA = nullptr; \
4299 switch (IRP.getPositionKind()) { \
4300 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4301 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4302 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4303 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4304 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4305 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4306 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4307 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4309 AA->initialize(A); \
4313 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind
)
4314 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync
)
4315 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree
)
4316 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse
)
4317 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn
)
4318 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn
)
4319 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead
)
4320 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues
)
4322 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull
)
4323 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias
)
4324 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable
)
4325 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign
)
4326 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture
)
4328 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify
)
4330 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack
)
4332 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
4333 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
4334 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
4335 #undef SWITCH_PK_CREATE
4336 #undef SWITCH_PK_INV
4338 INITIALIZE_PASS_BEGIN(AttributorLegacyPass
, "attributor",
4339 "Deduce and propagate attributes", false, false)
4340 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
4341 INITIALIZE_PASS_END(AttributorLegacyPass
, "attributor",
4342 "Deduce and propagate attributes", false, false)