1 //===- AttributorAttributes.cpp - Attributes for Attributor 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 // See the Attributor.h file comment and the class descriptions in that file for
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/IPO/Attributor.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/DenseMapInfo.h"
19 #include "llvm/ADT/MapVector.h"
20 #include "llvm/ADT/SCCIterator.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SetOperations.h"
23 #include "llvm/ADT/SetVector.h"
24 #include "llvm/ADT/SmallPtrSet.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/Statistic.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/Analysis/AliasAnalysis.h"
29 #include "llvm/Analysis/AssumeBundleQueries.h"
30 #include "llvm/Analysis/AssumptionCache.h"
31 #include "llvm/Analysis/CaptureTracking.h"
32 #include "llvm/Analysis/CycleAnalysis.h"
33 #include "llvm/Analysis/InstructionSimplify.h"
34 #include "llvm/Analysis/LazyValueInfo.h"
35 #include "llvm/Analysis/MemoryBuiltins.h"
36 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
37 #include "llvm/Analysis/ScalarEvolution.h"
38 #include "llvm/Analysis/TargetTransformInfo.h"
39 #include "llvm/Analysis/ValueTracking.h"
40 #include "llvm/IR/Argument.h"
41 #include "llvm/IR/Assumptions.h"
42 #include "llvm/IR/Attributes.h"
43 #include "llvm/IR/BasicBlock.h"
44 #include "llvm/IR/Constant.h"
45 #include "llvm/IR/Constants.h"
46 #include "llvm/IR/DataLayout.h"
47 #include "llvm/IR/DerivedTypes.h"
48 #include "llvm/IR/GlobalValue.h"
49 #include "llvm/IR/IRBuilder.h"
50 #include "llvm/IR/InlineAsm.h"
51 #include "llvm/IR/InstrTypes.h"
52 #include "llvm/IR/Instruction.h"
53 #include "llvm/IR/Instructions.h"
54 #include "llvm/IR/IntrinsicInst.h"
55 #include "llvm/IR/IntrinsicsAMDGPU.h"
56 #include "llvm/IR/IntrinsicsNVPTX.h"
57 #include "llvm/IR/LLVMContext.h"
58 #include "llvm/IR/MDBuilder.h"
59 #include "llvm/IR/NoFolder.h"
60 #include "llvm/IR/Value.h"
61 #include "llvm/IR/ValueHandle.h"
62 #include "llvm/Support/Alignment.h"
63 #include "llvm/Support/Casting.h"
64 #include "llvm/Support/CommandLine.h"
65 #include "llvm/Support/ErrorHandling.h"
66 #include "llvm/Support/GraphWriter.h"
67 #include "llvm/Support/MathExtras.h"
68 #include "llvm/Support/raw_ostream.h"
69 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
70 #include "llvm/Transforms/Utils/CallPromotionUtils.h"
71 #include "llvm/Transforms/Utils/Local.h"
72 #include "llvm/Transforms/Utils/ValueMapper.h"
80 #define DEBUG_TYPE "attributor"
82 static cl::opt
<bool> ManifestInternal(
83 "attributor-manifest-internal", cl::Hidden
,
84 cl::desc("Manifest Attributor internal string attributes."),
87 static cl::opt
<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues
= 0;
93 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues
= -1;
95 static cl::opt
<unsigned, true> MaxPotentialValues(
96 "attributor-max-potential-values", cl::Hidden
,
97 cl::desc("Maximum number of potential values to be "
98 "tracked for each position."),
99 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues
),
102 static cl::opt
<int> MaxPotentialValuesIterations(
103 "attributor-max-potential-values-iterations", cl::Hidden
,
105 "Maximum number of iterations we keep dismantling potential values."),
108 STATISTIC(NumAAs
, "Number of abstract attributes created");
110 // Some helper macros to deal with statistics tracking.
113 // For simple IR attribute tracking overload trackStatistics in the abstract
114 // attribute and choose the right STATS_DECLTRACK_********* macro,
116 // void trackStatistics() const override {
117 // STATS_DECLTRACK_ARG_ATTR(returned)
119 // If there is a single "increment" side one can use the macro
120 // STATS_DECLTRACK with a custom message. If there are multiple increment
121 // sides, STATS_DECL and STATS_TRACK can also be used separately.
123 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
124 ("Number of " #TYPE " marked '" #NAME "'")
125 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
126 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
127 #define STATS_DECL(NAME, TYPE, MSG) \
128 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
129 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
130 #define STATS_DECLTRACK(NAME, TYPE, MSG) \
132 STATS_DECL(NAME, TYPE, MSG) \
133 STATS_TRACK(NAME, TYPE) \
135 #define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140 #define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142 #define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
154 // Specialization of the operator<< for abstract attributes subclasses. This
155 // disambiguates situations where multiple operators are applicable.
157 #define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
162 PIPE_OPERATOR(AAIsDead
)
163 PIPE_OPERATOR(AANoUnwind
)
164 PIPE_OPERATOR(AANoSync
)
165 PIPE_OPERATOR(AANoRecurse
)
166 PIPE_OPERATOR(AANonConvergent
)
167 PIPE_OPERATOR(AAWillReturn
)
168 PIPE_OPERATOR(AANoReturn
)
169 PIPE_OPERATOR(AANonNull
)
170 PIPE_OPERATOR(AAMustProgress
)
171 PIPE_OPERATOR(AANoAlias
)
172 PIPE_OPERATOR(AADereferenceable
)
173 PIPE_OPERATOR(AAAlign
)
174 PIPE_OPERATOR(AAInstanceInfo
)
175 PIPE_OPERATOR(AANoCapture
)
176 PIPE_OPERATOR(AAValueSimplify
)
177 PIPE_OPERATOR(AANoFree
)
178 PIPE_OPERATOR(AAHeapToStack
)
179 PIPE_OPERATOR(AAIntraFnReachability
)
180 PIPE_OPERATOR(AAMemoryBehavior
)
181 PIPE_OPERATOR(AAMemoryLocation
)
182 PIPE_OPERATOR(AAValueConstantRange
)
183 PIPE_OPERATOR(AAPrivatizablePtr
)
184 PIPE_OPERATOR(AAUndefinedBehavior
)
185 PIPE_OPERATOR(AAPotentialConstantValues
)
186 PIPE_OPERATOR(AAPotentialValues
)
187 PIPE_OPERATOR(AANoUndef
)
188 PIPE_OPERATOR(AANoFPClass
)
189 PIPE_OPERATOR(AACallEdges
)
190 PIPE_OPERATOR(AAInterFnReachability
)
191 PIPE_OPERATOR(AAPointerInfo
)
192 PIPE_OPERATOR(AAAssumptionInfo
)
193 PIPE_OPERATOR(AAUnderlyingObjects
)
194 PIPE_OPERATOR(AAAddressSpace
)
195 PIPE_OPERATOR(AAIndirectCallInfo
)
196 PIPE_OPERATOR(AAGlobalValueInfo
)
197 PIPE_OPERATOR(AADenormalFPMath
)
202 ChangeStatus clampStateAndIndicateChange
<DerefState
>(DerefState
&S
,
203 const DerefState
&R
) {
205 clampStateAndIndicateChange(S
.DerefBytesState
, R
.DerefBytesState
);
206 ChangeStatus CS1
= clampStateAndIndicateChange(S
.GlobalState
, R
.GlobalState
);
212 static bool mayBeInCycle(const CycleInfo
*CI
, const Instruction
*I
,
213 bool HeaderOnly
, Cycle
**CPtr
= nullptr) {
216 auto *BB
= I
->getParent();
217 auto *C
= CI
->getCycle(BB
);
222 return !HeaderOnly
|| BB
== C
->getHeader();
225 /// Checks if a type could have padding bytes.
226 static bool isDenselyPacked(Type
*Ty
, const DataLayout
&DL
) {
227 // There is no size information, so be conservative.
231 // If the alloc size is not equal to the storage size, then there are padding
232 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
233 if (DL
.getTypeSizeInBits(Ty
) != DL
.getTypeAllocSizeInBits(Ty
))
236 // FIXME: This isn't the right way to check for padding in vectors with
237 // non-byte-size elements.
238 if (VectorType
*SeqTy
= dyn_cast
<VectorType
>(Ty
))
239 return isDenselyPacked(SeqTy
->getElementType(), DL
);
241 // For array types, check for padding within members.
242 if (ArrayType
*SeqTy
= dyn_cast
<ArrayType
>(Ty
))
243 return isDenselyPacked(SeqTy
->getElementType(), DL
);
245 if (!isa
<StructType
>(Ty
))
248 // Check for padding within and between elements of a struct.
249 StructType
*StructTy
= cast
<StructType
>(Ty
);
250 const StructLayout
*Layout
= DL
.getStructLayout(StructTy
);
251 uint64_t StartPos
= 0;
252 for (unsigned I
= 0, E
= StructTy
->getNumElements(); I
< E
; ++I
) {
253 Type
*ElTy
= StructTy
->getElementType(I
);
254 if (!isDenselyPacked(ElTy
, DL
))
256 if (StartPos
!= Layout
->getElementOffsetInBits(I
))
258 StartPos
+= DL
.getTypeAllocSizeInBits(ElTy
);
264 /// Get pointer operand of memory accessing instruction. If \p I is
265 /// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
266 /// is set to false and the instruction is volatile, return nullptr.
267 static const Value
*getPointerOperand(const Instruction
*I
,
268 bool AllowVolatile
) {
269 if (!AllowVolatile
&& I
->isVolatile())
272 if (auto *LI
= dyn_cast
<LoadInst
>(I
)) {
273 return LI
->getPointerOperand();
276 if (auto *SI
= dyn_cast
<StoreInst
>(I
)) {
277 return SI
->getPointerOperand();
280 if (auto *CXI
= dyn_cast
<AtomicCmpXchgInst
>(I
)) {
281 return CXI
->getPointerOperand();
284 if (auto *RMWI
= dyn_cast
<AtomicRMWInst
>(I
)) {
285 return RMWI
->getPointerOperand();
291 /// Helper function to create a pointer of type \p ResTy, based on \p Ptr, and
292 /// advanced by \p Offset bytes. To aid later analysis the method tries to build
293 /// getelement pointer instructions that traverse the natural type of \p Ptr if
294 /// possible. If that fails, the remaining offset is adjusted byte-wise, hence
295 /// through a cast to i8*.
297 /// TODO: This could probably live somewhere more prominantly if it doesn't
299 static Value
*constructPointer(Type
*ResTy
, Type
*PtrElemTy
, Value
*Ptr
,
300 int64_t Offset
, IRBuilder
<NoFolder
> &IRB
,
301 const DataLayout
&DL
) {
302 assert(Offset
>= 0 && "Negative offset not supported yet!");
303 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr
<< " + " << Offset
304 << "-bytes as " << *ResTy
<< "\n");
307 Type
*Ty
= PtrElemTy
;
308 APInt
IntOffset(DL
.getIndexTypeSizeInBits(Ptr
->getType()), Offset
);
309 SmallVector
<APInt
> IntIndices
= DL
.getGEPIndicesForOffset(Ty
, IntOffset
);
311 SmallVector
<Value
*, 4> ValIndices
;
312 std::string GEPName
= Ptr
->getName().str();
313 for (const APInt
&Index
: IntIndices
) {
314 ValIndices
.push_back(IRB
.getInt(Index
));
315 GEPName
+= "." + std::to_string(Index
.getZExtValue());
318 // Create a GEP for the indices collected above.
319 Ptr
= IRB
.CreateGEP(PtrElemTy
, Ptr
, ValIndices
, GEPName
);
321 // If an offset is left we use byte-wise adjustment.
322 if (IntOffset
!= 0) {
323 Ptr
= IRB
.CreateGEP(IRB
.getInt8Ty(), Ptr
, IRB
.getInt(IntOffset
),
324 GEPName
+ ".b" + Twine(IntOffset
.getZExtValue()));
328 // Ensure the result has the requested type.
329 Ptr
= IRB
.CreatePointerBitCastOrAddrSpaceCast(Ptr
, ResTy
,
330 Ptr
->getName() + ".cast");
332 LLVM_DEBUG(dbgs() << "Constructed pointer: " << *Ptr
<< "\n");
337 stripAndAccumulateOffsets(Attributor
&A
, const AbstractAttribute
&QueryingAA
,
338 const Value
*Val
, const DataLayout
&DL
, APInt
&Offset
,
339 bool GetMinOffset
, bool AllowNonInbounds
,
340 bool UseAssumed
= false) {
342 auto AttributorAnalysis
= [&](Value
&V
, APInt
&ROffset
) -> bool {
343 const IRPosition
&Pos
= IRPosition::value(V
);
344 // Only track dependence if we are going to use the assumed info.
345 const AAValueConstantRange
*ValueConstantRangeAA
=
346 A
.getAAFor
<AAValueConstantRange
>(QueryingAA
, Pos
,
347 UseAssumed
? DepClassTy::OPTIONAL
349 if (!ValueConstantRangeAA
)
351 ConstantRange Range
= UseAssumed
? ValueConstantRangeAA
->getAssumed()
352 : ValueConstantRangeAA
->getKnown();
353 if (Range
.isFullSet())
356 // We can only use the lower part of the range because the upper part can
357 // be higher than what the value can really be.
359 ROffset
= Range
.getSignedMin();
361 ROffset
= Range
.getSignedMax();
365 return Val
->stripAndAccumulateConstantOffsets(DL
, Offset
, AllowNonInbounds
,
366 /* AllowInvariant */ true,
371 getMinimalBaseOfPointer(Attributor
&A
, const AbstractAttribute
&QueryingAA
,
372 const Value
*Ptr
, int64_t &BytesOffset
,
373 const DataLayout
&DL
, bool AllowNonInbounds
= false) {
374 APInt
OffsetAPInt(DL
.getIndexTypeSizeInBits(Ptr
->getType()), 0);
376 stripAndAccumulateOffsets(A
, QueryingAA
, Ptr
, DL
, OffsetAPInt
,
377 /* GetMinOffset */ true, AllowNonInbounds
);
379 BytesOffset
= OffsetAPInt
.getSExtValue();
383 /// Clamp the information known for all returned values of a function
384 /// (identified by \p QueryingAA) into \p S.
385 template <typename AAType
, typename StateType
= typename
AAType::StateType
,
386 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
,
387 bool RecurseForSelectAndPHI
= true>
388 static void clampReturnedValueStates(
389 Attributor
&A
, const AAType
&QueryingAA
, StateType
&S
,
390 const IRPosition::CallBaseContext
*CBContext
= nullptr) {
391 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
392 << QueryingAA
<< " into " << S
<< "\n");
394 assert((QueryingAA
.getIRPosition().getPositionKind() ==
395 IRPosition::IRP_RETURNED
||
396 QueryingAA
.getIRPosition().getPositionKind() ==
397 IRPosition::IRP_CALL_SITE_RETURNED
) &&
398 "Can only clamp returned value states for a function returned or call "
399 "site returned position!");
401 // Use an optional state as there might not be any return values and we want
402 // to join (IntegerState::operator&) the state of all there are.
403 std::optional
<StateType
> T
;
405 // Callback for each possibly returned value.
406 auto CheckReturnValue
= [&](Value
&RV
) -> bool {
407 const IRPosition
&RVPos
= IRPosition::value(RV
, CBContext
);
408 // If possible, use the hasAssumedIRAttr interface.
409 if (Attribute::isEnumAttrKind(IRAttributeKind
)) {
411 return AA::hasAssumedIRAttr
<IRAttributeKind
>(
412 A
, &QueryingAA
, RVPos
, DepClassTy::REQUIRED
, IsKnown
);
416 A
.getAAFor
<AAType
>(QueryingAA
, RVPos
, DepClassTy::REQUIRED
);
419 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
420 << " AA: " << AA
->getAsStr(&A
) << " @ " << RVPos
<< "\n");
421 const StateType
&AAS
= AA
->getState();
423 T
= StateType::getBestState(AAS
);
425 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS
<< " RV State: " << T
427 return T
->isValidState();
430 if (!A
.checkForAllReturnedValues(CheckReturnValue
, QueryingAA
,
431 AA::ValueScope::Intraprocedural
,
432 RecurseForSelectAndPHI
))
433 S
.indicatePessimisticFixpoint();
439 /// Helper class for generic deduction: return value -> returned position.
440 template <typename AAType
, typename BaseType
,
441 typename StateType
= typename
BaseType::StateType
,
442 bool PropagateCallBaseContext
= false,
443 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
,
444 bool RecurseForSelectAndPHI
= true>
445 struct AAReturnedFromReturnedValues
: public BaseType
{
446 AAReturnedFromReturnedValues(const IRPosition
&IRP
, Attributor
&A
)
447 : BaseType(IRP
, A
) {}
449 /// See AbstractAttribute::updateImpl(...).
450 ChangeStatus
updateImpl(Attributor
&A
) override
{
451 StateType
S(StateType::getBestState(this->getState()));
452 clampReturnedValueStates
<AAType
, StateType
, IRAttributeKind
, RecurseForSelectAndPHI
>(
454 PropagateCallBaseContext
? this->getCallBaseContext() : nullptr);
455 // TODO: If we know we visited all returned values, thus no are assumed
456 // dead, we can take the known information from the state T.
457 return clampStateAndIndicateChange
<StateType
>(this->getState(), S
);
461 /// Clamp the information known at all call sites for a given argument
462 /// (identified by \p QueryingAA) into \p S.
463 template <typename AAType
, typename StateType
= typename
AAType::StateType
,
464 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
>
465 static void clampCallSiteArgumentStates(Attributor
&A
, const AAType
&QueryingAA
,
467 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
468 << QueryingAA
<< " into " << S
<< "\n");
470 assert(QueryingAA
.getIRPosition().getPositionKind() ==
471 IRPosition::IRP_ARGUMENT
&&
472 "Can only clamp call site argument states for an argument position!");
474 // Use an optional state as there might not be any return values and we want
475 // to join (IntegerState::operator&) the state of all there are.
476 std::optional
<StateType
> T
;
478 // The argument number which is also the call site argument number.
479 unsigned ArgNo
= QueryingAA
.getIRPosition().getCallSiteArgNo();
481 auto CallSiteCheck
= [&](AbstractCallSite ACS
) {
482 const IRPosition
&ACSArgPos
= IRPosition::callsite_argument(ACS
, ArgNo
);
483 // Check if a coresponding argument was found or if it is on not associated
484 // (which can happen for callback calls).
485 if (ACSArgPos
.getPositionKind() == IRPosition::IRP_INVALID
)
488 // If possible, use the hasAssumedIRAttr interface.
489 if (Attribute::isEnumAttrKind(IRAttributeKind
)) {
491 return AA::hasAssumedIRAttr
<IRAttributeKind
>(
492 A
, &QueryingAA
, ACSArgPos
, DepClassTy::REQUIRED
, IsKnown
);
496 A
.getAAFor
<AAType
>(QueryingAA
, ACSArgPos
, DepClassTy::REQUIRED
);
499 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS
.getInstruction()
500 << " AA: " << AA
->getAsStr(&A
) << " @" << ACSArgPos
502 const StateType
&AAS
= AA
->getState();
504 T
= StateType::getBestState(AAS
);
506 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS
<< " CSA State: " << T
508 return T
->isValidState();
511 bool UsedAssumedInformation
= false;
512 if (!A
.checkForAllCallSites(CallSiteCheck
, QueryingAA
, true,
513 UsedAssumedInformation
))
514 S
.indicatePessimisticFixpoint();
519 /// This function is the bridge between argument position and the call base
521 template <typename AAType
, typename BaseType
,
522 typename StateType
= typename
AAType::StateType
,
523 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
>
524 bool getArgumentStateFromCallBaseContext(Attributor
&A
,
525 BaseType
&QueryingAttribute
,
526 IRPosition
&Pos
, StateType
&State
) {
527 assert((Pos
.getPositionKind() == IRPosition::IRP_ARGUMENT
) &&
528 "Expected an 'argument' position !");
529 const CallBase
*CBContext
= Pos
.getCallBaseContext();
533 int ArgNo
= Pos
.getCallSiteArgNo();
534 assert(ArgNo
>= 0 && "Invalid Arg No!");
535 const IRPosition CBArgPos
= IRPosition::callsite_argument(*CBContext
, ArgNo
);
537 // If possible, use the hasAssumedIRAttr interface.
538 if (Attribute::isEnumAttrKind(IRAttributeKind
)) {
540 return AA::hasAssumedIRAttr
<IRAttributeKind
>(
541 A
, &QueryingAttribute
, CBArgPos
, DepClassTy::REQUIRED
, IsKnown
);
545 A
.getAAFor
<AAType
>(QueryingAttribute
, CBArgPos
, DepClassTy::REQUIRED
);
548 const StateType
&CBArgumentState
=
549 static_cast<const StateType
&>(AA
->getState());
551 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
552 << "Position:" << Pos
<< "CB Arg state:" << CBArgumentState
555 // NOTE: If we want to do call site grouping it should happen here.
556 State
^= CBArgumentState
;
560 /// Helper class for generic deduction: call site argument -> argument position.
561 template <typename AAType
, typename BaseType
,
562 typename StateType
= typename
AAType::StateType
,
563 bool BridgeCallBaseContext
= false,
564 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
>
565 struct AAArgumentFromCallSiteArguments
: public BaseType
{
566 AAArgumentFromCallSiteArguments(const IRPosition
&IRP
, Attributor
&A
)
567 : BaseType(IRP
, A
) {}
569 /// See AbstractAttribute::updateImpl(...).
570 ChangeStatus
updateImpl(Attributor
&A
) override
{
571 StateType S
= StateType::getBestState(this->getState());
573 if (BridgeCallBaseContext
) {
575 getArgumentStateFromCallBaseContext
<AAType
, BaseType
, StateType
,
577 A
, *this, this->getIRPosition(), S
);
579 return clampStateAndIndicateChange
<StateType
>(this->getState(), S
);
581 clampCallSiteArgumentStates
<AAType
, StateType
, IRAttributeKind
>(A
, *this,
584 // TODO: If we know we visited all incoming values, thus no are assumed
585 // dead, we can take the known information from the state T.
586 return clampStateAndIndicateChange
<StateType
>(this->getState(), S
);
590 /// Helper class for generic replication: function returned -> cs returned.
591 template <typename AAType
, typename BaseType
,
592 typename StateType
= typename
BaseType::StateType
,
593 bool IntroduceCallBaseContext
= false,
594 Attribute::AttrKind IRAttributeKind
= AAType::IRAttributeKind
>
595 struct AACalleeToCallSite
: public BaseType
{
596 AACalleeToCallSite(const IRPosition
&IRP
, Attributor
&A
) : BaseType(IRP
, A
) {}
598 /// See AbstractAttribute::updateImpl(...).
599 ChangeStatus
updateImpl(Attributor
&A
) override
{
600 auto IRPKind
= this->getIRPosition().getPositionKind();
601 assert((IRPKind
== IRPosition::IRP_CALL_SITE_RETURNED
||
602 IRPKind
== IRPosition::IRP_CALL_SITE
) &&
603 "Can only wrap function returned positions for call site "
604 "returned positions!");
605 auto &S
= this->getState();
607 CallBase
&CB
= cast
<CallBase
>(this->getAnchorValue());
608 if (IntroduceCallBaseContext
)
609 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
612 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
613 auto CalleePred
= [&](ArrayRef
<const Function
*> Callees
) {
614 for (const Function
*Callee
: Callees
) {
616 IRPKind
== llvm::IRPosition::IRP_CALL_SITE_RETURNED
617 ? IRPosition::returned(*Callee
,
618 IntroduceCallBaseContext
? &CB
: nullptr)
619 : IRPosition::function(
620 *Callee
, IntroduceCallBaseContext
? &CB
: nullptr);
621 // If possible, use the hasAssumedIRAttr interface.
622 if (Attribute::isEnumAttrKind(IRAttributeKind
)) {
624 if (!AA::hasAssumedIRAttr
<IRAttributeKind
>(
625 A
, this, FnPos
, DepClassTy::REQUIRED
, IsKnown
))
631 A
.getAAFor
<AAType
>(*this, FnPos
, DepClassTy::REQUIRED
);
634 Changed
|= clampStateAndIndicateChange(S
, AA
->getState());
635 if (S
.isAtFixpoint())
636 return S
.isValidState();
640 if (!A
.checkForAllCallees(CalleePred
, *this, CB
))
641 return S
.indicatePessimisticFixpoint();
646 /// Helper function to accumulate uses.
647 template <class AAType
, typename StateType
= typename
AAType::StateType
>
648 static void followUsesInContext(AAType
&AA
, Attributor
&A
,
649 MustBeExecutedContextExplorer
&Explorer
,
650 const Instruction
*CtxI
,
651 SetVector
<const Use
*> &Uses
,
653 auto EIt
= Explorer
.begin(CtxI
), EEnd
= Explorer
.end(CtxI
);
654 for (unsigned u
= 0; u
< Uses
.size(); ++u
) {
655 const Use
*U
= Uses
[u
];
656 if (const Instruction
*UserI
= dyn_cast
<Instruction
>(U
->getUser())) {
657 bool Found
= Explorer
.findInContextOf(UserI
, EIt
, EEnd
);
658 if (Found
&& AA
.followUseInMBEC(A
, U
, UserI
, State
))
659 for (const Use
&Us
: UserI
->uses())
665 /// Use the must-be-executed-context around \p I to add information into \p S.
666 /// The AAType class is required to have `followUseInMBEC` method with the
667 /// following signature and behaviour:
669 /// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
670 /// U - Underlying use.
671 /// I - The user of the \p U.
672 /// Returns true if the value should be tracked transitively.
674 template <class AAType
, typename StateType
= typename
AAType::StateType
>
675 static void followUsesInMBEC(AAType
&AA
, Attributor
&A
, StateType
&S
,
677 MustBeExecutedContextExplorer
*Explorer
=
678 A
.getInfoCache().getMustBeExecutedContextExplorer();
682 // Container for (transitive) uses of the associated value.
683 SetVector
<const Use
*> Uses
;
684 for (const Use
&U
: AA
.getIRPosition().getAssociatedValue().uses())
687 followUsesInContext
<AAType
>(AA
, A
, *Explorer
, &CtxI
, Uses
, S
);
689 if (S
.isAtFixpoint())
692 SmallVector
<const BranchInst
*, 4> BrInsts
;
693 auto Pred
= [&](const Instruction
*I
) {
694 if (const BranchInst
*Br
= dyn_cast
<BranchInst
>(I
))
695 if (Br
->isConditional())
696 BrInsts
.push_back(Br
);
700 // Here, accumulate conditional branch instructions in the context. We
701 // explore the child paths and collect the known states. The disjunction of
702 // those states can be merged to its own state. Let ParentState_i be a state
703 // to indicate the known information for an i-th branch instruction in the
704 // context. ChildStates are created for its successors respectively.
706 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
707 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
709 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
711 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
713 // FIXME: Currently, recursive branches are not handled. For example, we
714 // can't deduce that ptr must be dereferenced in below function.
716 // void f(int a, int c, int *ptr) {
732 Explorer
->checkForAllContext(&CtxI
, Pred
);
733 for (const BranchInst
*Br
: BrInsts
) {
734 StateType ParentState
;
736 // The known state of the parent state is a conjunction of children's
737 // known states so it is initialized with a best state.
738 ParentState
.indicateOptimisticFixpoint();
740 for (const BasicBlock
*BB
: Br
->successors()) {
741 StateType ChildState
;
743 size_t BeforeSize
= Uses
.size();
744 followUsesInContext(AA
, A
, *Explorer
, &BB
->front(), Uses
, ChildState
);
746 // Erase uses which only appear in the child.
747 for (auto It
= Uses
.begin() + BeforeSize
; It
!= Uses
.end();)
750 ParentState
&= ChildState
;
753 // Use only known state.
759 /// ------------------------ PointerInfo ---------------------------------------
763 namespace PointerInfo
{
767 } // namespace PointerInfo
770 /// Helper for AA::PointerInfo::Access DenseMap/Set usage.
772 struct DenseMapInfo
<AAPointerInfo::Access
> : DenseMapInfo
<Instruction
*> {
773 using Access
= AAPointerInfo::Access
;
774 static inline Access
getEmptyKey();
775 static inline Access
getTombstoneKey();
776 static unsigned getHashValue(const Access
&A
);
777 static bool isEqual(const Access
&LHS
, const Access
&RHS
);
780 /// Helper that allows RangeTy as a key in a DenseMap.
781 template <> struct DenseMapInfo
<AA::RangeTy
> {
782 static inline AA::RangeTy
getEmptyKey() {
783 auto EmptyKey
= DenseMapInfo
<int64_t>::getEmptyKey();
784 return AA::RangeTy
{EmptyKey
, EmptyKey
};
787 static inline AA::RangeTy
getTombstoneKey() {
788 auto TombstoneKey
= DenseMapInfo
<int64_t>::getTombstoneKey();
789 return AA::RangeTy
{TombstoneKey
, TombstoneKey
};
792 static unsigned getHashValue(const AA::RangeTy
&Range
) {
793 return detail::combineHashValue(
794 DenseMapInfo
<int64_t>::getHashValue(Range
.Offset
),
795 DenseMapInfo
<int64_t>::getHashValue(Range
.Size
));
798 static bool isEqual(const AA::RangeTy
&A
, const AA::RangeTy B
) {
803 /// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
804 /// but the instruction
805 struct AccessAsInstructionInfo
: DenseMapInfo
<Instruction
*> {
806 using Base
= DenseMapInfo
<Instruction
*>;
807 using Access
= AAPointerInfo::Access
;
808 static inline Access
getEmptyKey();
809 static inline Access
getTombstoneKey();
810 static unsigned getHashValue(const Access
&A
);
811 static bool isEqual(const Access
&LHS
, const Access
&RHS
);
816 /// A type to track pointer/struct usage and accesses for AAPointerInfo.
817 struct AA::PointerInfo::State
: public AbstractState
{
818 /// Return the best possible representable state.
819 static State
getBestState(const State
&SIS
) { return State(); }
821 /// Return the worst possible representable state.
822 static State
getWorstState(const State
&SIS
) {
824 R
.indicatePessimisticFixpoint();
829 State(State
&&SIS
) = default;
831 const State
&getAssumed() const { return *this; }
833 /// See AbstractState::isValidState().
834 bool isValidState() const override
{ return BS
.isValidState(); }
836 /// See AbstractState::isAtFixpoint().
837 bool isAtFixpoint() const override
{ return BS
.isAtFixpoint(); }
839 /// See AbstractState::indicateOptimisticFixpoint().
840 ChangeStatus
indicateOptimisticFixpoint() override
{
841 BS
.indicateOptimisticFixpoint();
842 return ChangeStatus::UNCHANGED
;
845 /// See AbstractState::indicatePessimisticFixpoint().
846 ChangeStatus
indicatePessimisticFixpoint() override
{
847 BS
.indicatePessimisticFixpoint();
848 return ChangeStatus::CHANGED
;
851 State
&operator=(const State
&R
) {
855 AccessList
= R
.AccessList
;
856 OffsetBins
= R
.OffsetBins
;
857 RemoteIMap
= R
.RemoteIMap
;
861 State
&operator=(State
&&R
) {
865 std::swap(AccessList
, R
.AccessList
);
866 std::swap(OffsetBins
, R
.OffsetBins
);
867 std::swap(RemoteIMap
, R
.RemoteIMap
);
871 /// Add a new Access to the state at offset \p Offset and with size \p Size.
872 /// The access is associated with \p I, writes \p Content (if anything), and
873 /// is of kind \p Kind. If an Access already exists for the same \p I and same
874 /// \p RemoteI, the two are combined, potentially losing information about
875 /// offset and size. The resulting access must now be moved from its original
876 /// OffsetBin to the bin for its new offset.
878 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
879 ChangeStatus
addAccess(Attributor
&A
, const AAPointerInfo::RangeList
&Ranges
,
880 Instruction
&I
, std::optional
<Value
*> Content
,
881 AAPointerInfo::AccessKind Kind
, Type
*Ty
,
882 Instruction
*RemoteI
= nullptr);
884 using OffsetBinsTy
= DenseMap
<RangeTy
, SmallSet
<unsigned, 4>>;
886 using const_bin_iterator
= OffsetBinsTy::const_iterator
;
887 const_bin_iterator
begin() const { return OffsetBins
.begin(); }
888 const_bin_iterator
end() const { return OffsetBins
.end(); }
890 const AAPointerInfo::Access
&getAccess(unsigned Index
) const {
891 return AccessList
[Index
];
895 // Every memory instruction results in an Access object. We maintain a list of
896 // all Access objects that we own, along with the following maps:
898 // - OffsetBins: RangeTy -> { Access }
899 // - RemoteIMap: RemoteI x LocalI -> Access
901 // A RemoteI is any instruction that accesses memory. RemoteI is different
902 // from LocalI if and only if LocalI is a call; then RemoteI is some
903 // instruction in the callgraph starting from LocalI. Multiple paths in the
904 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
905 // are all combined into a single Access object. This may result in loss of
906 // information in RangeTy in the Access object.
907 SmallVector
<AAPointerInfo::Access
> AccessList
;
908 OffsetBinsTy OffsetBins
;
909 DenseMap
<const Instruction
*, SmallVector
<unsigned>> RemoteIMap
;
911 /// See AAPointerInfo::forallInterferingAccesses.
912 bool forallInterferingAccesses(
914 function_ref
<bool(const AAPointerInfo::Access
&, bool)> CB
) const {
918 for (const auto &It
: OffsetBins
) {
919 AA::RangeTy ItRange
= It
.getFirst();
920 if (!Range
.mayOverlap(ItRange
))
922 bool IsExact
= Range
== ItRange
&& !Range
.offsetOrSizeAreUnknown();
923 for (auto Index
: It
.getSecond()) {
924 auto &Access
= AccessList
[Index
];
925 if (!CB(Access
, IsExact
))
932 /// See AAPointerInfo::forallInterferingAccesses.
933 bool forallInterferingAccesses(
935 function_ref
<bool(const AAPointerInfo::Access
&, bool)> CB
,
936 AA::RangeTy
&Range
) const {
940 auto LocalList
= RemoteIMap
.find(&I
);
941 if (LocalList
== RemoteIMap
.end()) {
945 for (unsigned Index
: LocalList
->getSecond()) {
946 for (auto &R
: AccessList
[Index
]) {
948 if (Range
.offsetAndSizeAreUnknown())
952 return forallInterferingAccesses(Range
, CB
);
956 /// State to track fixpoint and validity.
960 ChangeStatus
AA::PointerInfo::State::addAccess(
961 Attributor
&A
, const AAPointerInfo::RangeList
&Ranges
, Instruction
&I
,
962 std::optional
<Value
*> Content
, AAPointerInfo::AccessKind Kind
, Type
*Ty
,
963 Instruction
*RemoteI
) {
964 RemoteI
= RemoteI
? RemoteI
: &I
;
966 // Check if we have an access for this instruction, if not, simply add it.
967 auto &LocalList
= RemoteIMap
[RemoteI
];
968 bool AccExists
= false;
969 unsigned AccIndex
= AccessList
.size();
970 for (auto Index
: LocalList
) {
971 auto &A
= AccessList
[Index
];
972 if (A
.getLocalInst() == &I
) {
979 auto AddToBins
= [&](const AAPointerInfo::RangeList
&ToAdd
) {
980 LLVM_DEBUG(if (ToAdd
.size()) dbgs()
981 << "[AAPointerInfo] Inserting access in new offset bins\n";);
983 for (auto Key
: ToAdd
) {
984 LLVM_DEBUG(dbgs() << " key " << Key
<< "\n");
985 OffsetBins
[Key
].insert(AccIndex
);
990 AccessList
.emplace_back(&I
, RemoteI
, Ranges
, Content
, Kind
, Ty
);
991 assert((AccessList
.size() == AccIndex
+ 1) &&
992 "New Access should have been at AccIndex");
993 LocalList
.push_back(AccIndex
);
994 AddToBins(AccessList
[AccIndex
].getRanges());
995 return ChangeStatus::CHANGED
;
998 // Combine the new Access with the existing Access, and then update the
999 // mapping in the offset bins.
1000 AAPointerInfo::Access
Acc(&I
, RemoteI
, Ranges
, Content
, Kind
, Ty
);
1001 auto &Current
= AccessList
[AccIndex
];
1002 auto Before
= Current
;
1004 if (Current
== Before
)
1005 return ChangeStatus::UNCHANGED
;
1007 auto &ExistingRanges
= Before
.getRanges();
1008 auto &NewRanges
= Current
.getRanges();
1010 // Ranges that are in the old access but not the new access need to be removed
1011 // from the offset bins.
1012 AAPointerInfo::RangeList ToRemove
;
1013 AAPointerInfo::RangeList::set_difference(ExistingRanges
, NewRanges
, ToRemove
);
1014 LLVM_DEBUG(if (ToRemove
.size()) dbgs()
1015 << "[AAPointerInfo] Removing access from old offset bins\n";);
1017 for (auto Key
: ToRemove
) {
1018 LLVM_DEBUG(dbgs() << " key " << Key
<< "\n");
1019 assert(OffsetBins
.count(Key
) && "Existing Access must be in some bin.");
1020 auto &Bin
= OffsetBins
[Key
];
1021 assert(Bin
.count(AccIndex
) &&
1022 "Expected bin to actually contain the Access.");
1023 Bin
.erase(AccIndex
);
1026 // Ranges that are in the new access but not the old access need to be added
1027 // to the offset bins.
1028 AAPointerInfo::RangeList ToAdd
;
1029 AAPointerInfo::RangeList::set_difference(NewRanges
, ExistingRanges
, ToAdd
);
1031 return ChangeStatus::CHANGED
;
1036 /// A helper containing a list of offsets computed for a Use. Ideally this
1037 /// list should be strictly ascending, but we ensure that only when we
1038 /// actually translate the list of offsets to a RangeList.
1040 using VecTy
= SmallVector
<int64_t>;
1041 using const_iterator
= VecTy::const_iterator
;
1044 const_iterator
begin() const { return Offsets
.begin(); }
1045 const_iterator
end() const { return Offsets
.end(); }
1047 bool operator==(const OffsetInfo
&RHS
) const {
1048 return Offsets
== RHS
.Offsets
;
1051 bool operator!=(const OffsetInfo
&RHS
) const { return !(*this == RHS
); }
1053 void insert(int64_t Offset
) { Offsets
.push_back(Offset
); }
1054 bool isUnassigned() const { return Offsets
.size() == 0; }
1056 bool isUnknown() const {
1059 if (Offsets
.size() == 1)
1060 return Offsets
.front() == AA::RangeTy::Unknown
;
1066 Offsets
.push_back(AA::RangeTy::Unknown
);
1069 void addToAll(int64_t Inc
) {
1070 for (auto &Offset
: Offsets
) {
1075 /// Copy offsets from \p R into the current list.
1077 /// Ideally all lists should be strictly ascending, but we defer that to the
1078 /// actual use of the list. So we just blindly append here.
1079 void merge(const OffsetInfo
&R
) { Offsets
.append(R
.Offsets
); }
1083 static raw_ostream
&operator<<(raw_ostream
&OS
, const OffsetInfo
&OI
) {
1086 for (auto Offset
: OI
) {
1094 struct AAPointerInfoImpl
1095 : public StateWrapper
<AA::PointerInfo::State
, AAPointerInfo
> {
1096 using BaseTy
= StateWrapper
<AA::PointerInfo::State
, AAPointerInfo
>;
1097 AAPointerInfoImpl(const IRPosition
&IRP
, Attributor
&A
) : BaseTy(IRP
) {}
1099 /// See AbstractAttribute::getAsStr().
1100 const std::string
getAsStr(Attributor
*A
) const override
{
1101 return std::string("PointerInfo ") +
1102 (isValidState() ? (std::string("#") +
1103 std::to_string(OffsetBins
.size()) + " bins")
1107 /// See AbstractAttribute::manifest(...).
1108 ChangeStatus
manifest(Attributor
&A
) override
{
1109 return AAPointerInfo::manifest(A
);
1112 bool forallInterferingAccesses(
1114 function_ref
<bool(const AAPointerInfo::Access
&, bool)> CB
)
1116 return State::forallInterferingAccesses(Range
, CB
);
1119 bool forallInterferingAccesses(
1120 Attributor
&A
, const AbstractAttribute
&QueryingAA
, Instruction
&I
,
1121 bool FindInterferingWrites
, bool FindInterferingReads
,
1122 function_ref
<bool(const Access
&, bool)> UserCB
, bool &HasBeenWrittenTo
,
1124 function_ref
<bool(const Access
&)> SkipCB
) const override
{
1125 HasBeenWrittenTo
= false;
1127 SmallPtrSet
<const Access
*, 8> DominatingWrites
;
1128 SmallVector
<std::pair
<const Access
*, bool>, 8> InterferingAccesses
;
1130 Function
&Scope
= *I
.getFunction();
1132 bool IsAssumedNoSync
= AA::hasAssumedIRAttr
<Attribute::NoSync
>(
1133 A
, &QueryingAA
, IRPosition::function(Scope
), DepClassTy::OPTIONAL
,
1135 const auto *ExecDomainAA
= A
.lookupAAFor
<AAExecutionDomain
>(
1136 IRPosition::function(Scope
), &QueryingAA
, DepClassTy::NONE
);
1137 bool AllInSameNoSyncFn
= IsAssumedNoSync
;
1138 bool InstIsExecutedByInitialThreadOnly
=
1139 ExecDomainAA
&& ExecDomainAA
->isExecutedByInitialThreadOnly(I
);
1141 // If the function is not ending in aligned barriers, we need the stores to
1142 // be in aligned barriers. The load being in one is not sufficient since the
1143 // store might be executed by a thread that disappears after, causing the
1144 // aligned barrier guarding the load to unblock and the load to read a value
1145 // that has no CFG path to the load.
1146 bool InstIsExecutedInAlignedRegion
=
1147 FindInterferingReads
&& ExecDomainAA
&&
1148 ExecDomainAA
->isExecutedInAlignedRegion(A
, I
);
1150 if (InstIsExecutedInAlignedRegion
|| InstIsExecutedByInitialThreadOnly
)
1151 A
.recordDependence(*ExecDomainAA
, QueryingAA
, DepClassTy::OPTIONAL
);
1153 InformationCache
&InfoCache
= A
.getInfoCache();
1154 bool IsThreadLocalObj
=
1155 AA::isAssumedThreadLocalObject(A
, getAssociatedValue(), *this);
1157 // Helper to determine if we need to consider threading, which we cannot
1158 // right now. However, if the function is (assumed) nosync or the thread
1159 // executing all instructions is the main thread only we can ignore
1160 // threading. Also, thread-local objects do not require threading reasoning.
1161 // Finally, we can ignore threading if either access is executed in an
1163 auto CanIgnoreThreadingForInst
= [&](const Instruction
&I
) -> bool {
1164 if (IsThreadLocalObj
|| AllInSameNoSyncFn
)
1166 const auto *FnExecDomainAA
=
1167 I
.getFunction() == &Scope
1169 : A
.lookupAAFor
<AAExecutionDomain
>(
1170 IRPosition::function(*I
.getFunction()), &QueryingAA
,
1172 if (!FnExecDomainAA
)
1174 if (InstIsExecutedInAlignedRegion
||
1175 (FindInterferingWrites
&&
1176 FnExecDomainAA
->isExecutedInAlignedRegion(A
, I
))) {
1177 A
.recordDependence(*FnExecDomainAA
, QueryingAA
, DepClassTy::OPTIONAL
);
1180 if (InstIsExecutedByInitialThreadOnly
&&
1181 FnExecDomainAA
->isExecutedByInitialThreadOnly(I
)) {
1182 A
.recordDependence(*FnExecDomainAA
, QueryingAA
, DepClassTy::OPTIONAL
);
1188 // Helper to determine if the access is executed by the same thread as the
1189 // given instruction, for now it is sufficient to avoid any potential
1190 // threading effects as we cannot deal with them anyway.
1191 auto CanIgnoreThreading
= [&](const Access
&Acc
) -> bool {
1192 return CanIgnoreThreadingForInst(*Acc
.getRemoteInst()) ||
1193 (Acc
.getRemoteInst() != Acc
.getLocalInst() &&
1194 CanIgnoreThreadingForInst(*Acc
.getLocalInst()));
1197 // TODO: Use inter-procedural reachability and dominance.
1198 bool IsKnownNoRecurse
;
1199 AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
1200 A
, this, IRPosition::function(Scope
), DepClassTy::OPTIONAL
,
1203 const bool UseDominanceReasoning
=
1204 FindInterferingWrites
&& IsKnownNoRecurse
;
1205 const DominatorTree
*DT
=
1206 InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(Scope
);
1208 // Helper to check if a value has "kernel lifetime", that is it will not
1209 // outlive a GPU kernel. This is true for shared, constant, and local
1210 // globals on AMD and NVIDIA GPUs.
1211 auto HasKernelLifetime
= [&](Value
*V
, Module
&M
) {
1214 switch (AA::GPUAddressSpace(V
->getType()->getPointerAddressSpace())) {
1215 case AA::GPUAddressSpace::Shared
:
1216 case AA::GPUAddressSpace::Constant
:
1217 case AA::GPUAddressSpace::Local
:
1224 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1225 // to determine if we should look at reachability from the callee. For
1226 // certain pointers we know the lifetime and we do not have to step into the
1227 // callee to determine reachability as the pointer would be dead in the
1228 // callee. See the conditional initialization below.
1229 std::function
<bool(const Function
&)> IsLiveInCalleeCB
;
1231 if (auto *AI
= dyn_cast
<AllocaInst
>(&getAssociatedValue())) {
1232 // If the alloca containing function is not recursive the alloca
1233 // must be dead in the callee.
1234 const Function
*AIFn
= AI
->getFunction();
1235 bool IsKnownNoRecurse
;
1236 if (AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
1237 A
, this, IRPosition::function(*AIFn
), DepClassTy::OPTIONAL
,
1238 IsKnownNoRecurse
)) {
1239 IsLiveInCalleeCB
= [AIFn
](const Function
&Fn
) { return AIFn
!= &Fn
; };
1241 } else if (auto *GV
= dyn_cast
<GlobalValue
>(&getAssociatedValue())) {
1242 // If the global has kernel lifetime we can stop if we reach a kernel
1243 // as it is "dead" in the (unknown) callees.
1244 if (HasKernelLifetime(GV
, *GV
->getParent()))
1245 IsLiveInCalleeCB
= [](const Function
&Fn
) {
1246 return !Fn
.hasFnAttribute("kernel");
1250 // Set of accesses/instructions that will overwrite the result and are
1251 // therefore blockers in the reachability traversal.
1252 AA::InstExclusionSetTy ExclusionSet
;
1254 auto AccessCB
= [&](const Access
&Acc
, bool Exact
) {
1255 if (Exact
&& Acc
.isMustAccess() && Acc
.getRemoteInst() != &I
) {
1256 if (Acc
.isWrite() || (isa
<LoadInst
>(I
) && Acc
.isWriteOrAssumption()))
1257 ExclusionSet
.insert(Acc
.getRemoteInst());
1260 if ((!FindInterferingWrites
|| !Acc
.isWriteOrAssumption()) &&
1261 (!FindInterferingReads
|| !Acc
.isRead()))
1264 bool Dominates
= FindInterferingWrites
&& DT
&& Exact
&&
1265 Acc
.isMustAccess() &&
1266 (Acc
.getRemoteInst()->getFunction() == &Scope
) &&
1267 DT
->dominates(Acc
.getRemoteInst(), &I
);
1269 DominatingWrites
.insert(&Acc
);
1271 // Track if all interesting accesses are in the same `nosync` function as
1272 // the given instruction.
1273 AllInSameNoSyncFn
&= Acc
.getRemoteInst()->getFunction() == &Scope
;
1275 InterferingAccesses
.push_back({&Acc
, Exact
});
1278 if (!State::forallInterferingAccesses(I
, AccessCB
, Range
))
1281 HasBeenWrittenTo
= !DominatingWrites
.empty();
1283 // Dominating writes form a chain, find the least/lowest member.
1284 Instruction
*LeastDominatingWriteInst
= nullptr;
1285 for (const Access
*Acc
: DominatingWrites
) {
1286 if (!LeastDominatingWriteInst
) {
1287 LeastDominatingWriteInst
= Acc
->getRemoteInst();
1288 } else if (DT
->dominates(LeastDominatingWriteInst
,
1289 Acc
->getRemoteInst())) {
1290 LeastDominatingWriteInst
= Acc
->getRemoteInst();
1294 // Helper to determine if we can skip a specific write access.
1295 auto CanSkipAccess
= [&](const Access
&Acc
, bool Exact
) {
1296 if (SkipCB
&& SkipCB(Acc
))
1298 if (!CanIgnoreThreading(Acc
))
1301 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1302 // If we successfully excluded all effects we are interested in, the
1303 // access can be skipped.
1304 bool ReadChecked
= !FindInterferingReads
;
1305 bool WriteChecked
= !FindInterferingWrites
;
1307 // If the instruction cannot reach the access, the former does not
1308 // interfere with what the access reads.
1310 if (!AA::isPotentiallyReachable(A
, I
, *Acc
.getRemoteInst(), QueryingAA
,
1311 &ExclusionSet
, IsLiveInCalleeCB
))
1314 // If the instruction cannot be reach from the access, the latter does not
1315 // interfere with what the instruction reads.
1316 if (!WriteChecked
) {
1317 if (!AA::isPotentiallyReachable(A
, *Acc
.getRemoteInst(), I
, QueryingAA
,
1318 &ExclusionSet
, IsLiveInCalleeCB
))
1319 WriteChecked
= true;
1322 // If we still might be affected by the write of the access but there are
1323 // dominating writes in the function of the instruction
1324 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1325 // by them. This would have happend above if they are all in the same
1326 // function, so we only check the inter-procedural case. Effectively, we
1327 // want to show that there is no call after the dominting write that might
1328 // reach the access, and when it returns reach the instruction with the
1329 // updated value. To this end, we iterate all call sites, check if they
1330 // might reach the instruction without going through another access
1331 // (ExclusionSet) and at the same time might reach the access. However,
1332 // that is all part of AAInterFnReachability.
1333 if (!WriteChecked
&& HasBeenWrittenTo
&&
1334 Acc
.getRemoteInst()->getFunction() != &Scope
) {
1336 const auto *FnReachabilityAA
= A
.getAAFor
<AAInterFnReachability
>(
1337 QueryingAA
, IRPosition::function(Scope
), DepClassTy::OPTIONAL
);
1339 // Without going backwards in the call tree, can we reach the access
1340 // from the least dominating write. Do not allow to pass the instruction
1342 bool Inserted
= ExclusionSet
.insert(&I
).second
;
1344 if (!FnReachabilityAA
||
1345 !FnReachabilityAA
->instructionCanReach(
1346 A
, *LeastDominatingWriteInst
,
1347 *Acc
.getRemoteInst()->getFunction(), &ExclusionSet
))
1348 WriteChecked
= true;
1351 ExclusionSet
.erase(&I
);
1354 if (ReadChecked
&& WriteChecked
)
1357 if (!DT
|| !UseDominanceReasoning
)
1359 if (!DominatingWrites
.count(&Acc
))
1361 return LeastDominatingWriteInst
!= Acc
.getRemoteInst();
1364 // Run the user callback on all accesses we cannot skip and return if
1365 // that succeeded for all or not.
1366 for (auto &It
: InterferingAccesses
) {
1367 if ((!AllInSameNoSyncFn
&& !IsThreadLocalObj
&& !ExecDomainAA
) ||
1368 !CanSkipAccess(*It
.first
, It
.second
)) {
1369 if (!UserCB(*It
.first
, It
.second
))
1376 ChangeStatus
translateAndAddStateFromCallee(Attributor
&A
,
1377 const AAPointerInfo
&OtherAA
,
1379 using namespace AA::PointerInfo
;
1380 if (!OtherAA
.getState().isValidState() || !isValidState())
1381 return indicatePessimisticFixpoint();
1383 const auto &OtherAAImpl
= static_cast<const AAPointerInfoImpl
&>(OtherAA
);
1384 bool IsByval
= OtherAAImpl
.getAssociatedArgument()->hasByValAttr();
1386 // Combine the accesses bin by bin.
1387 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
1388 const auto &State
= OtherAAImpl
.getState();
1389 for (const auto &It
: State
) {
1390 for (auto Index
: It
.getSecond()) {
1391 const auto &RAcc
= State
.getAccess(Index
);
1392 if (IsByval
&& !RAcc
.isRead())
1394 bool UsedAssumedInformation
= false;
1395 AccessKind AK
= RAcc
.getKind();
1396 auto Content
= A
.translateArgumentToCallSiteContent(
1397 RAcc
.getContent(), CB
, *this, UsedAssumedInformation
);
1398 AK
= AccessKind(AK
& (IsByval
? AccessKind::AK_R
: AccessKind::AK_RW
));
1399 AK
= AccessKind(AK
| (RAcc
.isMayAccess() ? AK_MAY
: AK_MUST
));
1401 Changed
|= addAccess(A
, RAcc
.getRanges(), CB
, Content
, AK
,
1402 RAcc
.getType(), RAcc
.getRemoteInst());
1408 ChangeStatus
translateAndAddState(Attributor
&A
, const AAPointerInfo
&OtherAA
,
1409 const OffsetInfo
&Offsets
, CallBase
&CB
) {
1410 using namespace AA::PointerInfo
;
1411 if (!OtherAA
.getState().isValidState() || !isValidState())
1412 return indicatePessimisticFixpoint();
1414 const auto &OtherAAImpl
= static_cast<const AAPointerInfoImpl
&>(OtherAA
);
1416 // Combine the accesses bin by bin.
1417 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
1418 const auto &State
= OtherAAImpl
.getState();
1419 for (const auto &It
: State
) {
1420 for (auto Index
: It
.getSecond()) {
1421 const auto &RAcc
= State
.getAccess(Index
);
1422 for (auto Offset
: Offsets
) {
1423 auto NewRanges
= Offset
== AA::RangeTy::Unknown
1424 ? AA::RangeTy::getUnknown()
1426 if (!NewRanges
.isUnknown()) {
1427 NewRanges
.addToAllOffsets(Offset
);
1430 addAccess(A
, NewRanges
, CB
, RAcc
.getContent(), RAcc
.getKind(),
1431 RAcc
.getType(), RAcc
.getRemoteInst());
1438 /// Statistic tracking for all AAPointerInfo implementations.
1439 /// See AbstractAttribute::trackStatistics().
1440 void trackPointerInfoStatistics(const IRPosition
&IRP
) const {}
1442 /// Dump the state into \p O.
1443 void dumpState(raw_ostream
&O
) {
1444 for (auto &It
: OffsetBins
) {
1445 O
<< "[" << It
.first
.Offset
<< "-" << It
.first
.Offset
+ It
.first
.Size
1446 << "] : " << It
.getSecond().size() << "\n";
1447 for (auto AccIndex
: It
.getSecond()) {
1448 auto &Acc
= AccessList
[AccIndex
];
1449 O
<< " - " << Acc
.getKind() << " - " << *Acc
.getLocalInst() << "\n";
1450 if (Acc
.getLocalInst() != Acc
.getRemoteInst())
1451 O
<< " --> " << *Acc
.getRemoteInst()
1453 if (!Acc
.isWrittenValueYetUndetermined()) {
1454 if (isa_and_nonnull
<Function
>(Acc
.getWrittenValue()))
1455 O
<< " - c: func " << Acc
.getWrittenValue()->getName()
1457 else if (Acc
.getWrittenValue())
1458 O
<< " - c: " << *Acc
.getWrittenValue() << "\n";
1460 O
<< " - c: <unknown>\n";
1467 struct AAPointerInfoFloating
: public AAPointerInfoImpl
{
1468 using AccessKind
= AAPointerInfo::AccessKind
;
1469 AAPointerInfoFloating(const IRPosition
&IRP
, Attributor
&A
)
1470 : AAPointerInfoImpl(IRP
, A
) {}
1472 /// Deal with an access and signal if it was handled successfully.
1473 bool handleAccess(Attributor
&A
, Instruction
&I
,
1474 std::optional
<Value
*> Content
, AccessKind Kind
,
1475 SmallVectorImpl
<int64_t> &Offsets
, ChangeStatus
&Changed
,
1477 using namespace AA::PointerInfo
;
1478 auto Size
= AA::RangeTy::Unknown
;
1479 const DataLayout
&DL
= A
.getDataLayout();
1480 TypeSize AccessSize
= DL
.getTypeStoreSize(&Ty
);
1481 if (!AccessSize
.isScalable())
1482 Size
= AccessSize
.getFixedValue();
1484 // Make a strictly ascending list of offsets as required by addAccess()
1485 llvm::sort(Offsets
);
1486 auto *Last
= std::unique(Offsets
.begin(), Offsets
.end());
1487 Offsets
.erase(Last
, Offsets
.end());
1489 VectorType
*VT
= dyn_cast
<VectorType
>(&Ty
);
1490 if (!VT
|| VT
->getElementCount().isScalable() ||
1491 !Content
.value_or(nullptr) || !isa
<Constant
>(*Content
) ||
1492 (*Content
)->getType() != VT
||
1493 DL
.getTypeStoreSize(VT
->getElementType()).isScalable()) {
1494 Changed
= Changed
| addAccess(A
, {Offsets
, Size
}, I
, Content
, Kind
, &Ty
);
1496 // Handle vector stores with constant content element-wise.
1497 // TODO: We could look for the elements or create instructions
1498 // representing them.
1499 // TODO: We need to push the Content into the range abstraction
1500 // (AA::RangeTy) to allow different content values for different
1501 // ranges. ranges. Hence, support vectors storing different values.
1502 Type
*ElementType
= VT
->getElementType();
1503 int64_t ElementSize
= DL
.getTypeStoreSize(ElementType
).getFixedValue();
1504 auto *ConstContent
= cast
<Constant
>(*Content
);
1505 Type
*Int32Ty
= Type::getInt32Ty(ElementType
->getContext());
1506 SmallVector
<int64_t> ElementOffsets(Offsets
.begin(), Offsets
.end());
1508 for (int i
= 0, e
= VT
->getElementCount().getFixedValue(); i
!= e
; ++i
) {
1509 Value
*ElementContent
= ConstantExpr::getExtractElement(
1510 ConstContent
, ConstantInt::get(Int32Ty
, i
));
1512 // Add the element access.
1513 Changed
= Changed
| addAccess(A
, {ElementOffsets
, ElementSize
}, I
,
1514 ElementContent
, Kind
, ElementType
);
1516 // Advance the offsets for the next element.
1517 for (auto &ElementOffset
: ElementOffsets
)
1518 ElementOffset
+= ElementSize
;
1524 /// See AbstractAttribute::updateImpl(...).
1525 ChangeStatus
updateImpl(Attributor
&A
) override
;
1527 /// If the indices to \p GEP can be traced to constants, incorporate all
1528 /// of these into \p UsrOI.
1530 /// \return true iff \p UsrOI is updated.
1531 bool collectConstantsForGEP(Attributor
&A
, const DataLayout
&DL
,
1532 OffsetInfo
&UsrOI
, const OffsetInfo
&PtrOI
,
1533 const GEPOperator
*GEP
);
1535 /// See AbstractAttribute::trackStatistics()
1536 void trackStatistics() const override
{
1537 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1541 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor
&A
,
1542 const DataLayout
&DL
,
1544 const OffsetInfo
&PtrOI
,
1545 const GEPOperator
*GEP
) {
1546 unsigned BitWidth
= DL
.getIndexTypeSizeInBits(GEP
->getType());
1547 MapVector
<Value
*, APInt
> VariableOffsets
;
1548 APInt
ConstantOffset(BitWidth
, 0);
1550 assert(!UsrOI
.isUnknown() && !PtrOI
.isUnknown() &&
1551 "Don't look for constant values if the offset has already been "
1552 "determined to be unknown.");
1554 if (!GEP
->collectOffset(DL
, BitWidth
, VariableOffsets
, ConstantOffset
)) {
1559 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1560 << (VariableOffsets
.empty() ? "" : "not") << " constant "
1564 Union
.addToAll(ConstantOffset
.getSExtValue());
1566 // Each VI in VariableOffsets has a set of potential constant values. Every
1567 // combination of elements, picked one each from these sets, is separately
1568 // added to the original set of offsets, thus resulting in more offsets.
1569 for (const auto &VI
: VariableOffsets
) {
1570 auto *PotentialConstantsAA
= A
.getAAFor
<AAPotentialConstantValues
>(
1571 *this, IRPosition::value(*VI
.first
), DepClassTy::OPTIONAL
);
1572 if (!PotentialConstantsAA
|| !PotentialConstantsAA
->isValidState()) {
1577 // UndefValue is treated as a zero, which leaves Union as is.
1578 if (PotentialConstantsAA
->undefIsContained())
1581 // We need at least one constant in every set to compute an actual offset.
1582 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1583 // don't actually exist. In other words, the absence of constant values
1584 // implies that the operation can be assumed dead for now.
1585 auto &AssumedSet
= PotentialConstantsAA
->getAssumedSet();
1586 if (AssumedSet
.empty())
1590 for (const auto &ConstOffset
: AssumedSet
) {
1591 auto CopyPerOffset
= Union
;
1592 CopyPerOffset
.addToAll(ConstOffset
.getSExtValue() *
1593 VI
.second
.getZExtValue());
1594 Product
.merge(CopyPerOffset
);
1599 UsrOI
= std::move(Union
);
1603 ChangeStatus
AAPointerInfoFloating::updateImpl(Attributor
&A
) {
1604 using namespace AA::PointerInfo
;
1605 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
1606 const DataLayout
&DL
= A
.getDataLayout();
1607 Value
&AssociatedValue
= getAssociatedValue();
1609 DenseMap
<Value
*, OffsetInfo
> OffsetInfoMap
;
1610 OffsetInfoMap
[&AssociatedValue
].insert(0);
1612 auto HandlePassthroughUser
= [&](Value
*Usr
, Value
*CurPtr
, bool &Follow
) {
1613 // One does not simply walk into a map and assign a reference to a possibly
1614 // new location. That can cause an invalidation before the assignment
1615 // happens, like so:
1617 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1619 // The RHS is a reference that may be invalidated by an insertion caused by
1620 // the LHS. So we ensure that the side-effect of the LHS happens first.
1621 auto &UsrOI
= OffsetInfoMap
[Usr
];
1622 auto &PtrOI
= OffsetInfoMap
[CurPtr
];
1623 assert(!PtrOI
.isUnassigned() &&
1624 "Cannot pass through if the input Ptr was not visited!");
1630 const auto *F
= getAnchorScope();
1632 F
? A
.getInfoCache().getAnalysisResultForFunction
<CycleAnalysis
>(*F
)
1635 F
? A
.getInfoCache().getTargetLibraryInfoForFunction(*F
) : nullptr;
1637 auto UsePred
= [&](const Use
&U
, bool &Follow
) -> bool {
1638 Value
*CurPtr
= U
.get();
1639 User
*Usr
= U
.getUser();
1640 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr
<< " in " << *Usr
1642 assert(OffsetInfoMap
.count(CurPtr
) &&
1643 "The current pointer offset should have been seeded!");
1645 if (ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(Usr
)) {
1647 return HandlePassthroughUser(Usr
, CurPtr
, Follow
);
1648 if (CE
->isCompare())
1650 if (!isa
<GEPOperator
>(CE
)) {
1651 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1656 if (auto *GEP
= dyn_cast
<GEPOperator
>(Usr
)) {
1657 // Note the order here, the Usr access might change the map, CurPtr is
1658 // already in it though.
1659 auto &UsrOI
= OffsetInfoMap
[Usr
];
1660 auto &PtrOI
= OffsetInfoMap
[CurPtr
];
1662 if (UsrOI
.isUnknown())
1665 if (PtrOI
.isUnknown()) {
1671 Follow
= collectConstantsForGEP(A
, DL
, UsrOI
, PtrOI
, GEP
);
1674 if (isa
<PtrToIntInst
>(Usr
))
1676 if (isa
<CastInst
>(Usr
) || isa
<SelectInst
>(Usr
) || isa
<ReturnInst
>(Usr
))
1677 return HandlePassthroughUser(Usr
, CurPtr
, Follow
);
1679 // For PHIs we need to take care of the recurrence explicitly as the value
1680 // might change while we iterate through a loop. For now, we give up if
1681 // the PHI is not invariant.
1682 if (isa
<PHINode
>(Usr
)) {
1683 // Note the order here, the Usr access might change the map, CurPtr is
1684 // already in it though.
1685 bool IsFirstPHIUser
= !OffsetInfoMap
.count(Usr
);
1686 auto &UsrOI
= OffsetInfoMap
[Usr
];
1687 auto &PtrOI
= OffsetInfoMap
[CurPtr
];
1689 // Check if the PHI operand has already an unknown offset as we can't
1690 // improve on that anymore.
1691 if (PtrOI
.isUnknown()) {
1692 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1693 << *CurPtr
<< " in " << *Usr
<< "\n");
1694 Follow
= !UsrOI
.isUnknown();
1699 // Check if the PHI is invariant (so far).
1700 if (UsrOI
== PtrOI
) {
1701 assert(!PtrOI
.isUnassigned() &&
1702 "Cannot assign if the current Ptr was not visited!");
1703 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1707 // Check if the PHI operand can be traced back to AssociatedValue.
1709 DL
.getIndexSizeInBits(CurPtr
->getType()->getPointerAddressSpace()),
1711 Value
*CurPtrBase
= CurPtr
->stripAndAccumulateConstantOffsets(
1712 DL
, Offset
, /* AllowNonInbounds */ true);
1713 auto It
= OffsetInfoMap
.find(CurPtrBase
);
1714 if (It
== OffsetInfoMap
.end()) {
1715 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1716 << *CurPtr
<< " in " << *Usr
<< "\n");
1722 // Check if the PHI operand is not dependent on the PHI itself. Every
1723 // recurrence is a cyclic net of PHIs in the data flow, and has an
1724 // equivalent Cycle in the control flow. One of those PHIs must be in the
1725 // header of that control flow Cycle. This is independent of the choice of
1726 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1727 // every Cycle header; if such a node is marked unknown, this will
1728 // eventually propagate through the whole net of PHIs in the recurrence.
1729 if (mayBeInCycle(CI
, cast
<Instruction
>(Usr
), /* HeaderOnly */ true)) {
1730 auto BaseOI
= It
->getSecond();
1731 BaseOI
.addToAll(Offset
.getZExtValue());
1732 if (IsFirstPHIUser
|| BaseOI
== UsrOI
) {
1733 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1734 << " in " << *Usr
<< "\n");
1735 return HandlePassthroughUser(Usr
, CurPtr
, Follow
);
1739 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1740 << *CurPtr
<< " in " << *Usr
<< "\n");
1751 if (auto *LoadI
= dyn_cast
<LoadInst
>(Usr
)) {
1752 // If the access is to a pointer that may or may not be the associated
1753 // value, e.g. due to a PHI, we cannot assume it will be read.
1754 AccessKind AK
= AccessKind::AK_R
;
1755 if (getUnderlyingObject(CurPtr
) == &AssociatedValue
)
1756 AK
= AccessKind(AK
| AccessKind::AK_MUST
);
1758 AK
= AccessKind(AK
| AccessKind::AK_MAY
);
1759 if (!handleAccess(A
, *LoadI
, /* Content */ nullptr, AK
,
1760 OffsetInfoMap
[CurPtr
].Offsets
, Changed
,
1764 auto IsAssumption
= [](Instruction
&I
) {
1765 if (auto *II
= dyn_cast
<IntrinsicInst
>(&I
))
1766 return II
->isAssumeLikeIntrinsic();
1770 auto IsImpactedInRange
= [&](Instruction
*FromI
, Instruction
*ToI
) {
1771 // Check if the assumption and the load are executed together without
1772 // memory modification.
1774 if (FromI
->mayWriteToMemory() && !IsAssumption(*FromI
))
1776 FromI
= FromI
->getNextNonDebugInstruction();
1777 } while (FromI
&& FromI
!= ToI
);
1781 BasicBlock
*BB
= LoadI
->getParent();
1782 auto IsValidAssume
= [&](IntrinsicInst
&IntrI
) {
1783 if (IntrI
.getIntrinsicID() != Intrinsic::assume
)
1785 BasicBlock
*IntrBB
= IntrI
.getParent();
1786 if (IntrI
.getParent() == BB
) {
1787 if (IsImpactedInRange(LoadI
->getNextNonDebugInstruction(), &IntrI
))
1790 auto PredIt
= pred_begin(IntrBB
);
1791 if (PredIt
== pred_end(IntrBB
))
1793 if ((*PredIt
) != BB
)
1795 if (++PredIt
!= pred_end(IntrBB
))
1797 for (auto *SuccBB
: successors(BB
)) {
1798 if (SuccBB
== IntrBB
)
1800 if (isa
<UnreachableInst
>(SuccBB
->getTerminator()))
1804 if (IsImpactedInRange(LoadI
->getNextNonDebugInstruction(),
1805 BB
->getTerminator()))
1807 if (IsImpactedInRange(&IntrBB
->front(), &IntrI
))
1813 std::pair
<Value
*, IntrinsicInst
*> Assumption
;
1814 for (const Use
&LoadU
: LoadI
->uses()) {
1815 if (auto *CmpI
= dyn_cast
<CmpInst
>(LoadU
.getUser())) {
1816 if (!CmpI
->isEquality() || !CmpI
->isTrueWhenEqual())
1818 for (const Use
&CmpU
: CmpI
->uses()) {
1819 if (auto *IntrI
= dyn_cast
<IntrinsicInst
>(CmpU
.getUser())) {
1820 if (!IsValidAssume(*IntrI
))
1822 int Idx
= CmpI
->getOperandUse(0) == LoadU
;
1823 Assumption
= {CmpI
->getOperand(Idx
), IntrI
};
1828 if (Assumption
.first
)
1832 // Check if we found an assumption associated with this load.
1833 if (!Assumption
.first
|| !Assumption
.second
)
1836 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1837 << *Assumption
.second
<< ": " << *LoadI
1838 << " == " << *Assumption
.first
<< "\n");
1839 bool UsedAssumedInformation
= false;
1840 std::optional
<Value
*> Content
= nullptr;
1841 if (Assumption
.first
)
1843 A
.getAssumedSimplified(*Assumption
.first
, *this,
1844 UsedAssumedInformation
, AA::Interprocedural
);
1845 return handleAccess(
1846 A
, *Assumption
.second
, Content
, AccessKind::AK_ASSUMPTION
,
1847 OffsetInfoMap
[CurPtr
].Offsets
, Changed
, *LoadI
->getType());
1850 auto HandleStoreLike
= [&](Instruction
&I
, Value
*ValueOp
, Type
&ValueTy
,
1851 ArrayRef
<Value
*> OtherOps
, AccessKind AK
) {
1852 for (auto *OtherOp
: OtherOps
) {
1853 if (OtherOp
== CurPtr
) {
1856 << "[AAPointerInfo] Escaping use in store like instruction " << I
1862 // If the access is to a pointer that may or may not be the associated
1863 // value, e.g. due to a PHI, we cannot assume it will be written.
1864 if (getUnderlyingObject(CurPtr
) == &AssociatedValue
)
1865 AK
= AccessKind(AK
| AccessKind::AK_MUST
);
1867 AK
= AccessKind(AK
| AccessKind::AK_MAY
);
1868 bool UsedAssumedInformation
= false;
1869 std::optional
<Value
*> Content
= nullptr;
1871 Content
= A
.getAssumedSimplified(
1872 *ValueOp
, *this, UsedAssumedInformation
, AA::Interprocedural
);
1873 return handleAccess(A
, I
, Content
, AK
, OffsetInfoMap
[CurPtr
].Offsets
,
1877 if (auto *StoreI
= dyn_cast
<StoreInst
>(Usr
))
1878 return HandleStoreLike(*StoreI
, StoreI
->getValueOperand(),
1879 *StoreI
->getValueOperand()->getType(),
1880 {StoreI
->getValueOperand()}, AccessKind::AK_W
);
1881 if (auto *RMWI
= dyn_cast
<AtomicRMWInst
>(Usr
))
1882 return HandleStoreLike(*RMWI
, nullptr, *RMWI
->getValOperand()->getType(),
1883 {RMWI
->getValOperand()}, AccessKind::AK_RW
);
1884 if (auto *CXI
= dyn_cast
<AtomicCmpXchgInst
>(Usr
))
1885 return HandleStoreLike(
1886 *CXI
, nullptr, *CXI
->getNewValOperand()->getType(),
1887 {CXI
->getCompareOperand(), CXI
->getNewValOperand()},
1890 if (auto *CB
= dyn_cast
<CallBase
>(Usr
)) {
1891 if (CB
->isLifetimeStartOrEnd())
1893 if (getFreedOperand(CB
, TLI
) == U
)
1895 if (CB
->isArgOperand(&U
)) {
1896 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
1897 const auto *CSArgPI
= A
.getAAFor
<AAPointerInfo
>(
1898 *this, IRPosition::callsite_argument(*CB
, ArgNo
),
1899 DepClassTy::REQUIRED
);
1903 translateAndAddState(A
, *CSArgPI
, OffsetInfoMap
[CurPtr
], *CB
) |
1905 return isValidState();
1907 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1909 // TODO: Allow some call uses
1913 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr
<< "\n");
1916 auto EquivalentUseCB
= [&](const Use
&OldU
, const Use
&NewU
) {
1917 assert(OffsetInfoMap
.count(OldU
) && "Old use should be known already!");
1918 if (OffsetInfoMap
.count(NewU
)) {
1920 if (!(OffsetInfoMap
[NewU
] == OffsetInfoMap
[OldU
])) {
1921 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1922 << OffsetInfoMap
[NewU
] << " vs " << OffsetInfoMap
[OldU
]
1926 return OffsetInfoMap
[NewU
] == OffsetInfoMap
[OldU
];
1928 OffsetInfoMap
[NewU
] = OffsetInfoMap
[OldU
];
1931 if (!A
.checkForAllUses(UsePred
, *this, AssociatedValue
,
1932 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL
,
1933 /* IgnoreDroppableUses */ true, EquivalentUseCB
)) {
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1935 return indicatePessimisticFixpoint();
1939 dbgs() << "Accesses by bin after update:\n";
1946 struct AAPointerInfoReturned final
: AAPointerInfoImpl
{
1947 AAPointerInfoReturned(const IRPosition
&IRP
, Attributor
&A
)
1948 : AAPointerInfoImpl(IRP
, A
) {}
1950 /// See AbstractAttribute::updateImpl(...).
1951 ChangeStatus
updateImpl(Attributor
&A
) override
{
1952 return indicatePessimisticFixpoint();
1955 /// See AbstractAttribute::trackStatistics()
1956 void trackStatistics() const override
{
1957 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1961 struct AAPointerInfoArgument final
: AAPointerInfoFloating
{
1962 AAPointerInfoArgument(const IRPosition
&IRP
, Attributor
&A
)
1963 : AAPointerInfoFloating(IRP
, A
) {}
1965 /// See AbstractAttribute::trackStatistics()
1966 void trackStatistics() const override
{
1967 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1971 struct AAPointerInfoCallSiteArgument final
: AAPointerInfoFloating
{
1972 AAPointerInfoCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
1973 : AAPointerInfoFloating(IRP
, A
) {}
1975 /// See AbstractAttribute::updateImpl(...).
1976 ChangeStatus
updateImpl(Attributor
&A
) override
{
1977 using namespace AA::PointerInfo
;
1978 // We handle memory intrinsics explicitly, at least the first (=
1979 // destination) and second (=source) arguments as we know how they are
1981 if (auto *MI
= dyn_cast_or_null
<MemIntrinsic
>(getCtxI())) {
1982 ConstantInt
*Length
= dyn_cast
<ConstantInt
>(MI
->getLength());
1983 int64_t LengthVal
= AA::RangeTy::Unknown
;
1985 LengthVal
= Length
->getSExtValue();
1986 unsigned ArgNo
= getIRPosition().getCallSiteArgNo();
1987 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
1989 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1991 return indicatePessimisticFixpoint();
1994 ArgNo
== 0 ? AccessKind::AK_MUST_WRITE
: AccessKind::AK_MUST_READ
;
1996 Changed
| addAccess(A
, {0, LengthVal
}, *MI
, nullptr, Kind
, nullptr);
1999 dbgs() << "Accesses by bin after update:\n";
2006 // TODO: Once we have call site specific value information we can provide
2007 // call site specific liveness information and then it makes
2008 // sense to specialize attributes for call sites arguments instead of
2009 // redirecting requests to the callee argument.
2010 Argument
*Arg
= getAssociatedArgument();
2012 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
2014 A
.getAAFor
<AAPointerInfo
>(*this, ArgPos
, DepClassTy::REQUIRED
);
2015 if (ArgAA
&& ArgAA
->getState().isValidState())
2016 return translateAndAddStateFromCallee(A
, *ArgAA
,
2017 *cast
<CallBase
>(getCtxI()));
2018 if (!Arg
->getParent()->isDeclaration())
2019 return indicatePessimisticFixpoint();
2022 bool IsKnownNoCapture
;
2023 if (!AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
2024 A
, this, getIRPosition(), DepClassTy::OPTIONAL
, IsKnownNoCapture
))
2025 return indicatePessimisticFixpoint();
2027 bool IsKnown
= false;
2028 if (AA::isAssumedReadNone(A
, getIRPosition(), *this, IsKnown
))
2029 return ChangeStatus::UNCHANGED
;
2030 bool ReadOnly
= AA::isAssumedReadOnly(A
, getIRPosition(), *this, IsKnown
);
2032 ReadOnly
? AccessKind::AK_MAY_READ
: AccessKind::AK_MAY_READ_WRITE
;
2033 return addAccess(A
, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind
,
2037 /// See AbstractAttribute::trackStatistics()
2038 void trackStatistics() const override
{
2039 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2043 struct AAPointerInfoCallSiteReturned final
: AAPointerInfoFloating
{
2044 AAPointerInfoCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
2045 : AAPointerInfoFloating(IRP
, A
) {}
2047 /// See AbstractAttribute::trackStatistics()
2048 void trackStatistics() const override
{
2049 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2054 /// -----------------------NoUnwind Function Attribute--------------------------
2057 struct AANoUnwindImpl
: AANoUnwind
{
2058 AANoUnwindImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoUnwind(IRP
, A
) {}
2060 /// See AbstractAttribute::initialize(...).
2061 void initialize(Attributor
&A
) override
{
2063 assert(!AA::hasAssumedIRAttr
<Attribute::NoUnwind
>(
2064 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
2068 const std::string
getAsStr(Attributor
*A
) const override
{
2069 return getAssumed() ? "nounwind" : "may-unwind";
2072 /// See AbstractAttribute::updateImpl(...).
2073 ChangeStatus
updateImpl(Attributor
&A
) override
{
2075 (unsigned)Instruction::Invoke
, (unsigned)Instruction::CallBr
,
2076 (unsigned)Instruction::Call
, (unsigned)Instruction::CleanupRet
,
2077 (unsigned)Instruction::CatchSwitch
, (unsigned)Instruction::Resume
};
2079 auto CheckForNoUnwind
= [&](Instruction
&I
) {
2080 if (!I
.mayThrow(/* IncludePhaseOneUnwind */ true))
2083 if (const auto *CB
= dyn_cast
<CallBase
>(&I
)) {
2084 bool IsKnownNoUnwind
;
2085 return AA::hasAssumedIRAttr
<Attribute::NoUnwind
>(
2086 A
, this, IRPosition::callsite_function(*CB
), DepClassTy::REQUIRED
,
2092 bool UsedAssumedInformation
= false;
2093 if (!A
.checkForAllInstructions(CheckForNoUnwind
, *this, Opcodes
,
2094 UsedAssumedInformation
))
2095 return indicatePessimisticFixpoint();
2097 return ChangeStatus::UNCHANGED
;
2101 struct AANoUnwindFunction final
: public AANoUnwindImpl
{
2102 AANoUnwindFunction(const IRPosition
&IRP
, Attributor
&A
)
2103 : AANoUnwindImpl(IRP
, A
) {}
2105 /// See AbstractAttribute::trackStatistics()
2106 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nounwind
) }
2109 /// NoUnwind attribute deduction for a call sites.
2110 struct AANoUnwindCallSite final
2111 : AACalleeToCallSite
<AANoUnwind
, AANoUnwindImpl
> {
2112 AANoUnwindCallSite(const IRPosition
&IRP
, Attributor
&A
)
2113 : AACalleeToCallSite
<AANoUnwind
, AANoUnwindImpl
>(IRP
, A
) {}
2115 /// See AbstractAttribute::trackStatistics()
2116 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nounwind
); }
2120 /// ------------------------ NoSync Function Attribute -------------------------
2122 bool AANoSync::isAlignedBarrier(const CallBase
&CB
, bool ExecutedAligned
) {
2123 switch (CB
.getIntrinsicID()) {
2124 case Intrinsic::nvvm_barrier0
:
2125 case Intrinsic::nvvm_barrier0_and
:
2126 case Intrinsic::nvvm_barrier0_or
:
2127 case Intrinsic::nvvm_barrier0_popc
:
2129 case Intrinsic::amdgcn_s_barrier
:
2130 if (ExecutedAligned
)
2136 return hasAssumption(CB
, KnownAssumptionString("ompx_aligned_barrier"));
2139 bool AANoSync::isNonRelaxedAtomic(const Instruction
*I
) {
2143 if (auto *FI
= dyn_cast
<FenceInst
>(I
))
2144 // All legal orderings for fence are stronger than monotonic.
2145 return FI
->getSyncScopeID() != SyncScope::SingleThread
;
2146 if (auto *AI
= dyn_cast
<AtomicCmpXchgInst
>(I
)) {
2147 // Unordered is not a legal ordering for cmpxchg.
2148 return (AI
->getSuccessOrdering() != AtomicOrdering::Monotonic
||
2149 AI
->getFailureOrdering() != AtomicOrdering::Monotonic
);
2152 AtomicOrdering Ordering
;
2153 switch (I
->getOpcode()) {
2154 case Instruction::AtomicRMW
:
2155 Ordering
= cast
<AtomicRMWInst
>(I
)->getOrdering();
2157 case Instruction::Store
:
2158 Ordering
= cast
<StoreInst
>(I
)->getOrdering();
2160 case Instruction::Load
:
2161 Ordering
= cast
<LoadInst
>(I
)->getOrdering();
2165 "New atomic operations need to be known in the attributor.");
2168 return (Ordering
!= AtomicOrdering::Unordered
&&
2169 Ordering
!= AtomicOrdering::Monotonic
);
2172 /// Return true if this intrinsic is nosync. This is only used for intrinsics
2173 /// which would be nosync except that they have a volatile flag. All other
2174 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2175 bool AANoSync::isNoSyncIntrinsic(const Instruction
*I
) {
2176 if (auto *MI
= dyn_cast
<MemIntrinsic
>(I
))
2177 return !MI
->isVolatile();
2182 struct AANoSyncImpl
: AANoSync
{
2183 AANoSyncImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoSync(IRP
, A
) {}
2185 /// See AbstractAttribute::initialize(...).
2186 void initialize(Attributor
&A
) override
{
2188 assert(!AA::hasAssumedIRAttr
<Attribute::NoSync
>(A
, nullptr, getIRPosition(),
2189 DepClassTy::NONE
, IsKnown
));
2193 const std::string
getAsStr(Attributor
*A
) const override
{
2194 return getAssumed() ? "nosync" : "may-sync";
2197 /// See AbstractAttribute::updateImpl(...).
2198 ChangeStatus
updateImpl(Attributor
&A
) override
;
2201 ChangeStatus
AANoSyncImpl::updateImpl(Attributor
&A
) {
2203 auto CheckRWInstForNoSync
= [&](Instruction
&I
) {
2204 return AA::isNoSyncInst(A
, I
, *this);
2207 auto CheckForNoSync
= [&](Instruction
&I
) {
2208 // At this point we handled all read/write effects and they are all
2209 // nosync, so they can be skipped.
2210 if (I
.mayReadOrWriteMemory())
2214 CallBase
&CB
= cast
<CallBase
>(I
);
2215 if (AA::hasAssumedIRAttr
<Attribute::NoSync
>(
2216 A
, this, IRPosition::callsite_function(CB
), DepClassTy::OPTIONAL
,
2220 // non-convergent and readnone imply nosync.
2221 return !CB
.isConvergent();
2224 bool UsedAssumedInformation
= false;
2225 if (!A
.checkForAllReadWriteInstructions(CheckRWInstForNoSync
, *this,
2226 UsedAssumedInformation
) ||
2227 !A
.checkForAllCallLikeInstructions(CheckForNoSync
, *this,
2228 UsedAssumedInformation
))
2229 return indicatePessimisticFixpoint();
2231 return ChangeStatus::UNCHANGED
;
2234 struct AANoSyncFunction final
: public AANoSyncImpl
{
2235 AANoSyncFunction(const IRPosition
&IRP
, Attributor
&A
)
2236 : AANoSyncImpl(IRP
, A
) {}
2238 /// See AbstractAttribute::trackStatistics()
2239 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nosync
) }
2242 /// NoSync attribute deduction for a call sites.
2243 struct AANoSyncCallSite final
: AACalleeToCallSite
<AANoSync
, AANoSyncImpl
> {
2244 AANoSyncCallSite(const IRPosition
&IRP
, Attributor
&A
)
2245 : AACalleeToCallSite
<AANoSync
, AANoSyncImpl
>(IRP
, A
) {}
2247 /// See AbstractAttribute::trackStatistics()
2248 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nosync
); }
2252 /// ------------------------ No-Free Attributes ----------------------------
2255 struct AANoFreeImpl
: public AANoFree
{
2256 AANoFreeImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoFree(IRP
, A
) {}
2258 /// See AbstractAttribute::initialize(...).
2259 void initialize(Attributor
&A
) override
{
2261 assert(!AA::hasAssumedIRAttr
<Attribute::NoFree
>(A
, nullptr, getIRPosition(),
2262 DepClassTy::NONE
, IsKnown
));
2266 /// See AbstractAttribute::updateImpl(...).
2267 ChangeStatus
updateImpl(Attributor
&A
) override
{
2268 auto CheckForNoFree
= [&](Instruction
&I
) {
2270 return AA::hasAssumedIRAttr
<Attribute::NoFree
>(
2271 A
, this, IRPosition::callsite_function(cast
<CallBase
>(I
)),
2272 DepClassTy::REQUIRED
, IsKnown
);
2275 bool UsedAssumedInformation
= false;
2276 if (!A
.checkForAllCallLikeInstructions(CheckForNoFree
, *this,
2277 UsedAssumedInformation
))
2278 return indicatePessimisticFixpoint();
2279 return ChangeStatus::UNCHANGED
;
2282 /// See AbstractAttribute::getAsStr().
2283 const std::string
getAsStr(Attributor
*A
) const override
{
2284 return getAssumed() ? "nofree" : "may-free";
2288 struct AANoFreeFunction final
: public AANoFreeImpl
{
2289 AANoFreeFunction(const IRPosition
&IRP
, Attributor
&A
)
2290 : AANoFreeImpl(IRP
, A
) {}
2292 /// See AbstractAttribute::trackStatistics()
2293 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(nofree
) }
2296 /// NoFree attribute deduction for a call sites.
2297 struct AANoFreeCallSite final
: AACalleeToCallSite
<AANoFree
, AANoFreeImpl
> {
2298 AANoFreeCallSite(const IRPosition
&IRP
, Attributor
&A
)
2299 : AACalleeToCallSite
<AANoFree
, AANoFreeImpl
>(IRP
, A
) {}
2301 /// See AbstractAttribute::trackStatistics()
2302 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(nofree
); }
2305 /// NoFree attribute for floating values.
2306 struct AANoFreeFloating
: AANoFreeImpl
{
2307 AANoFreeFloating(const IRPosition
&IRP
, Attributor
&A
)
2308 : AANoFreeImpl(IRP
, A
) {}
2310 /// See AbstractAttribute::trackStatistics()
2311 void trackStatistics() const override
{STATS_DECLTRACK_FLOATING_ATTR(nofree
)}
2313 /// See Abstract Attribute::updateImpl(...).
2314 ChangeStatus
updateImpl(Attributor
&A
) override
{
2315 const IRPosition
&IRP
= getIRPosition();
2318 if (AA::hasAssumedIRAttr
<Attribute::NoFree
>(A
, this,
2319 IRPosition::function_scope(IRP
),
2320 DepClassTy::OPTIONAL
, IsKnown
))
2321 return ChangeStatus::UNCHANGED
;
2323 Value
&AssociatedValue
= getIRPosition().getAssociatedValue();
2324 auto Pred
= [&](const Use
&U
, bool &Follow
) -> bool {
2325 Instruction
*UserI
= cast
<Instruction
>(U
.getUser());
2326 if (auto *CB
= dyn_cast
<CallBase
>(UserI
)) {
2327 if (CB
->isBundleOperand(&U
))
2329 if (!CB
->isArgOperand(&U
))
2331 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
2334 return AA::hasAssumedIRAttr
<Attribute::NoFree
>(
2335 A
, this, IRPosition::callsite_argument(*CB
, ArgNo
),
2336 DepClassTy::REQUIRED
, IsKnown
);
2339 if (isa
<GetElementPtrInst
>(UserI
) || isa
<BitCastInst
>(UserI
) ||
2340 isa
<PHINode
>(UserI
) || isa
<SelectInst
>(UserI
)) {
2344 if (isa
<StoreInst
>(UserI
) || isa
<LoadInst
>(UserI
) ||
2345 isa
<ReturnInst
>(UserI
))
2351 if (!A
.checkForAllUses(Pred
, *this, AssociatedValue
))
2352 return indicatePessimisticFixpoint();
2354 return ChangeStatus::UNCHANGED
;
2358 /// NoFree attribute for a call site argument.
2359 struct AANoFreeArgument final
: AANoFreeFloating
{
2360 AANoFreeArgument(const IRPosition
&IRP
, Attributor
&A
)
2361 : AANoFreeFloating(IRP
, A
) {}
2363 /// See AbstractAttribute::trackStatistics()
2364 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nofree
) }
2367 /// NoFree attribute for call site arguments.
2368 struct AANoFreeCallSiteArgument final
: AANoFreeFloating
{
2369 AANoFreeCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
2370 : AANoFreeFloating(IRP
, A
) {}
2372 /// See AbstractAttribute::updateImpl(...).
2373 ChangeStatus
updateImpl(Attributor
&A
) override
{
2374 // TODO: Once we have call site specific value information we can provide
2375 // call site specific liveness information and then it makes
2376 // sense to specialize attributes for call sites arguments instead of
2377 // redirecting requests to the callee argument.
2378 Argument
*Arg
= getAssociatedArgument();
2380 return indicatePessimisticFixpoint();
2381 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
2383 if (AA::hasAssumedIRAttr
<Attribute::NoFree
>(A
, this, ArgPos
,
2384 DepClassTy::REQUIRED
, IsKnown
))
2385 return ChangeStatus::UNCHANGED
;
2386 return indicatePessimisticFixpoint();
2389 /// See AbstractAttribute::trackStatistics()
2390 void trackStatistics() const override
{STATS_DECLTRACK_CSARG_ATTR(nofree
)};
2393 /// NoFree attribute for function return value.
2394 struct AANoFreeReturned final
: AANoFreeFloating
{
2395 AANoFreeReturned(const IRPosition
&IRP
, Attributor
&A
)
2396 : AANoFreeFloating(IRP
, A
) {
2397 llvm_unreachable("NoFree is not applicable to function returns!");
2400 /// See AbstractAttribute::initialize(...).
2401 void initialize(Attributor
&A
) override
{
2402 llvm_unreachable("NoFree is not applicable to function returns!");
2405 /// See AbstractAttribute::updateImpl(...).
2406 ChangeStatus
updateImpl(Attributor
&A
) override
{
2407 llvm_unreachable("NoFree is not applicable to function returns!");
2410 /// See AbstractAttribute::trackStatistics()
2411 void trackStatistics() const override
{}
2414 /// NoFree attribute deduction for a call site return value.
2415 struct AANoFreeCallSiteReturned final
: AANoFreeFloating
{
2416 AANoFreeCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
2417 : AANoFreeFloating(IRP
, A
) {}
2419 ChangeStatus
manifest(Attributor
&A
) override
{
2420 return ChangeStatus::UNCHANGED
;
2422 /// See AbstractAttribute::trackStatistics()
2423 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(nofree
) }
2427 /// ------------------------ NonNull Argument Attribute ------------------------
2429 bool AANonNull::isImpliedByIR(Attributor
&A
, const IRPosition
&IRP
,
2430 Attribute::AttrKind ImpliedAttributeKind
,
2431 bool IgnoreSubsumingPositions
) {
2432 SmallVector
<Attribute::AttrKind
, 2> AttrKinds
;
2433 AttrKinds
.push_back(Attribute::NonNull
);
2434 if (!NullPointerIsDefined(IRP
.getAnchorScope(),
2435 IRP
.getAssociatedType()->getPointerAddressSpace()))
2436 AttrKinds
.push_back(Attribute::Dereferenceable
);
2437 if (A
.hasAttr(IRP
, AttrKinds
, IgnoreSubsumingPositions
, Attribute::NonNull
))
2440 DominatorTree
*DT
= nullptr;
2441 AssumptionCache
*AC
= nullptr;
2442 InformationCache
&InfoCache
= A
.getInfoCache();
2443 if (const Function
*Fn
= IRP
.getAnchorScope()) {
2444 if (!Fn
->isDeclaration()) {
2445 DT
= InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(*Fn
);
2446 AC
= InfoCache
.getAnalysisResultForFunction
<AssumptionAnalysis
>(*Fn
);
2450 SmallVector
<AA::ValueAndContext
> Worklist
;
2451 if (IRP
.getPositionKind() != IRP_RETURNED
) {
2452 Worklist
.push_back({IRP
.getAssociatedValue(), IRP
.getCtxI()});
2454 bool UsedAssumedInformation
= false;
2455 if (!A
.checkForAllInstructions(
2456 [&](Instruction
&I
) {
2457 Worklist
.push_back({*cast
<ReturnInst
>(I
).getReturnValue(), &I
});
2460 IRP
.getAssociatedFunction(), nullptr, {Instruction::Ret
},
2461 UsedAssumedInformation
))
2465 if (llvm::any_of(Worklist
, [&](AA::ValueAndContext VAC
) {
2466 return !isKnownNonZero(VAC
.getValue(), A
.getDataLayout(), 0, AC
,
2471 A
.manifestAttrs(IRP
, {Attribute::get(IRP
.getAnchorValue().getContext(),
2472 Attribute::NonNull
)});
2477 static int64_t getKnownNonNullAndDerefBytesForUse(
2478 Attributor
&A
, const AbstractAttribute
&QueryingAA
, Value
&AssociatedValue
,
2479 const Use
*U
, const Instruction
*I
, bool &IsNonNull
, bool &TrackUse
) {
2482 const Value
*UseV
= U
->get();
2483 if (!UseV
->getType()->isPointerTy())
2486 // We need to follow common pointer manipulation uses to the accesses they
2487 // feed into. We can try to be smart to avoid looking through things we do not
2488 // like for now, e.g., non-inbounds GEPs.
2489 if (isa
<CastInst
>(I
)) {
2494 if (isa
<GetElementPtrInst
>(I
)) {
2499 Type
*PtrTy
= UseV
->getType();
2500 const Function
*F
= I
->getFunction();
2501 bool NullPointerIsDefined
=
2502 F
? llvm::NullPointerIsDefined(F
, PtrTy
->getPointerAddressSpace()) : true;
2503 const DataLayout
&DL
= A
.getInfoCache().getDL();
2504 if (const auto *CB
= dyn_cast
<CallBase
>(I
)) {
2505 if (CB
->isBundleOperand(U
)) {
2506 if (RetainedKnowledge RK
= getKnowledgeFromUse(
2507 U
, {Attribute::NonNull
, Attribute::Dereferenceable
})) {
2509 (RK
.AttrKind
== Attribute::NonNull
|| !NullPointerIsDefined
);
2515 if (CB
->isCallee(U
)) {
2516 IsNonNull
|= !NullPointerIsDefined
;
2520 unsigned ArgNo
= CB
->getArgOperandNo(U
);
2521 IRPosition IRP
= IRPosition::callsite_argument(*CB
, ArgNo
);
2522 // As long as we only use known information there is no need to track
2523 // dependences here.
2524 bool IsKnownNonNull
;
2525 AA::hasAssumedIRAttr
<Attribute::NonNull
>(A
, &QueryingAA
, IRP
,
2526 DepClassTy::NONE
, IsKnownNonNull
);
2527 IsNonNull
|= IsKnownNonNull
;
2529 A
.getAAFor
<AADereferenceable
>(QueryingAA
, IRP
, DepClassTy::NONE
);
2530 return DerefAA
? DerefAA
->getKnownDereferenceableBytes() : 0;
2533 std::optional
<MemoryLocation
> Loc
= MemoryLocation::getOrNone(I
);
2534 if (!Loc
|| Loc
->Ptr
!= UseV
|| !Loc
->Size
.isPrecise() || I
->isVolatile())
2539 getMinimalBaseOfPointer(A
, QueryingAA
, Loc
->Ptr
, Offset
, DL
);
2540 if (Base
&& Base
== &AssociatedValue
) {
2541 int64_t DerefBytes
= Loc
->Size
.getValue() + Offset
;
2542 IsNonNull
|= !NullPointerIsDefined
;
2543 return std::max(int64_t(0), DerefBytes
);
2546 /// Corner case when an offset is 0.
2547 Base
= GetPointerBaseWithConstantOffset(Loc
->Ptr
, Offset
, DL
,
2548 /*AllowNonInbounds*/ true);
2549 if (Base
&& Base
== &AssociatedValue
&& Offset
== 0) {
2550 int64_t DerefBytes
= Loc
->Size
.getValue();
2551 IsNonNull
|= !NullPointerIsDefined
;
2552 return std::max(int64_t(0), DerefBytes
);
2558 struct AANonNullImpl
: AANonNull
{
2559 AANonNullImpl(const IRPosition
&IRP
, Attributor
&A
) : AANonNull(IRP
, A
) {}
2561 /// See AbstractAttribute::initialize(...).
2562 void initialize(Attributor
&A
) override
{
2563 Value
&V
= *getAssociatedValue().stripPointerCasts();
2564 if (isa
<ConstantPointerNull
>(V
)) {
2565 indicatePessimisticFixpoint();
2569 if (Instruction
*CtxI
= getCtxI())
2570 followUsesInMBEC(*this, A
, getState(), *CtxI
);
2573 /// See followUsesInMBEC
2574 bool followUseInMBEC(Attributor
&A
, const Use
*U
, const Instruction
*I
,
2575 AANonNull::StateType
&State
) {
2576 bool IsNonNull
= false;
2577 bool TrackUse
= false;
2578 getKnownNonNullAndDerefBytesForUse(A
, *this, getAssociatedValue(), U
, I
,
2579 IsNonNull
, TrackUse
);
2580 State
.setKnown(IsNonNull
);
2584 /// See AbstractAttribute::getAsStr().
2585 const std::string
getAsStr(Attributor
*A
) const override
{
2586 return getAssumed() ? "nonnull" : "may-null";
2590 /// NonNull attribute for a floating value.
2591 struct AANonNullFloating
: public AANonNullImpl
{
2592 AANonNullFloating(const IRPosition
&IRP
, Attributor
&A
)
2593 : AANonNullImpl(IRP
, A
) {}
2595 /// See AbstractAttribute::updateImpl(...).
2596 ChangeStatus
updateImpl(Attributor
&A
) override
{
2597 auto CheckIRP
= [&](const IRPosition
&IRP
) {
2598 bool IsKnownNonNull
;
2599 return AA::hasAssumedIRAttr
<Attribute::NonNull
>(
2600 A
, *this, IRP
, DepClassTy::OPTIONAL
, IsKnownNonNull
);
2604 bool UsedAssumedInformation
= false;
2605 Value
*AssociatedValue
= &getAssociatedValue();
2606 SmallVector
<AA::ValueAndContext
> Values
;
2607 if (!A
.getAssumedSimplifiedValues(getIRPosition(), *this, Values
,
2608 AA::AnyScope
, UsedAssumedInformation
))
2612 Values
.size() != 1 || Values
.front().getValue() != AssociatedValue
;
2616 if (auto *PHI
= dyn_cast
<PHINode
>(AssociatedValue
))
2617 if (llvm::all_of(PHI
->incoming_values(), [&](Value
*Op
) {
2618 return AA::hasAssumedIRAttr
<Attribute::NonNull
>(
2619 A
, this, IRPosition::value(*Op
), DepClassTy::OPTIONAL
,
2622 return ChangeStatus::UNCHANGED
;
2623 if (auto *Select
= dyn_cast
<SelectInst
>(AssociatedValue
))
2624 if (AA::hasAssumedIRAttr
<Attribute::NonNull
>(
2625 A
, this, IRPosition::value(*Select
->getFalseValue()),
2626 DepClassTy::OPTIONAL
, IsKnown
) &&
2627 AA::hasAssumedIRAttr
<Attribute::NonNull
>(
2628 A
, this, IRPosition::value(*Select
->getTrueValue()),
2629 DepClassTy::OPTIONAL
, IsKnown
))
2630 return ChangeStatus::UNCHANGED
;
2632 // If we haven't stripped anything we might still be able to use a
2633 // different AA, but only if the IRP changes. Effectively when we
2634 // interpret this not as a call site value but as a floating/argument
2636 const IRPosition AVIRP
= IRPosition::value(*AssociatedValue
);
2637 if (AVIRP
== getIRPosition() || !CheckIRP(AVIRP
))
2638 return indicatePessimisticFixpoint();
2639 return ChangeStatus::UNCHANGED
;
2642 for (const auto &VAC
: Values
)
2643 if (!CheckIRP(IRPosition::value(*VAC
.getValue())))
2644 return indicatePessimisticFixpoint();
2646 return ChangeStatus::UNCHANGED
;
2649 /// See AbstractAttribute::trackStatistics()
2650 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(nonnull
) }
2653 /// NonNull attribute for function return value.
2654 struct AANonNullReturned final
2655 : AAReturnedFromReturnedValues
<AANonNull
, AANonNull
, AANonNull::StateType
,
2656 false, AANonNull::IRAttributeKind
, false> {
2657 AANonNullReturned(const IRPosition
&IRP
, Attributor
&A
)
2658 : AAReturnedFromReturnedValues
<AANonNull
, AANonNull
, AANonNull::StateType
,
2659 false, Attribute::NonNull
, false>(IRP
, A
) {
2662 /// See AbstractAttribute::getAsStr().
2663 const std::string
getAsStr(Attributor
*A
) const override
{
2664 return getAssumed() ? "nonnull" : "may-null";
2667 /// See AbstractAttribute::trackStatistics()
2668 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(nonnull
) }
2671 /// NonNull attribute for function argument.
2672 struct AANonNullArgument final
2673 : AAArgumentFromCallSiteArguments
<AANonNull
, AANonNullImpl
> {
2674 AANonNullArgument(const IRPosition
&IRP
, Attributor
&A
)
2675 : AAArgumentFromCallSiteArguments
<AANonNull
, AANonNullImpl
>(IRP
, A
) {}
2677 /// See AbstractAttribute::trackStatistics()
2678 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nonnull
) }
2681 struct AANonNullCallSiteArgument final
: AANonNullFloating
{
2682 AANonNullCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
2683 : AANonNullFloating(IRP
, A
) {}
2685 /// See AbstractAttribute::trackStatistics()
2686 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(nonnull
) }
2689 /// NonNull attribute for a call site return position.
2690 struct AANonNullCallSiteReturned final
2691 : AACalleeToCallSite
<AANonNull
, AANonNullImpl
> {
2692 AANonNullCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
2693 : AACalleeToCallSite
<AANonNull
, AANonNullImpl
>(IRP
, A
) {}
2695 /// See AbstractAttribute::trackStatistics()
2696 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(nonnull
) }
2700 /// ------------------------ Must-Progress Attributes --------------------------
2702 struct AAMustProgressImpl
: public AAMustProgress
{
2703 AAMustProgressImpl(const IRPosition
&IRP
, Attributor
&A
)
2704 : AAMustProgress(IRP
, A
) {}
2706 /// See AbstractAttribute::initialize(...).
2707 void initialize(Attributor
&A
) override
{
2709 assert(!AA::hasAssumedIRAttr
<Attribute::MustProgress
>(
2710 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
2714 /// See AbstractAttribute::getAsStr()
2715 const std::string
getAsStr(Attributor
*A
) const override
{
2716 return getAssumed() ? "mustprogress" : "may-not-progress";
2720 struct AAMustProgressFunction final
: AAMustProgressImpl
{
2721 AAMustProgressFunction(const IRPosition
&IRP
, Attributor
&A
)
2722 : AAMustProgressImpl(IRP
, A
) {}
2724 /// See AbstractAttribute::updateImpl(...).
2725 ChangeStatus
updateImpl(Attributor
&A
) override
{
2727 if (AA::hasAssumedIRAttr
<Attribute::WillReturn
>(
2728 A
, this, getIRPosition(), DepClassTy::OPTIONAL
, IsKnown
)) {
2730 return indicateOptimisticFixpoint();
2731 return ChangeStatus::UNCHANGED
;
2734 auto CheckForMustProgress
= [&](AbstractCallSite ACS
) {
2735 IRPosition IPos
= IRPosition::callsite_function(*ACS
.getInstruction());
2736 bool IsKnownMustProgress
;
2737 return AA::hasAssumedIRAttr
<Attribute::MustProgress
>(
2738 A
, this, IPos
, DepClassTy::REQUIRED
, IsKnownMustProgress
,
2739 /* IgnoreSubsumingPositions */ true);
2742 bool AllCallSitesKnown
= true;
2743 if (!A
.checkForAllCallSites(CheckForMustProgress
, *this,
2744 /* RequireAllCallSites */ true,
2746 return indicatePessimisticFixpoint();
2748 return ChangeStatus::UNCHANGED
;
2751 /// See AbstractAttribute::trackStatistics()
2752 void trackStatistics() const override
{
2753 STATS_DECLTRACK_FN_ATTR(mustprogress
)
2757 /// MustProgress attribute deduction for a call sites.
2758 struct AAMustProgressCallSite final
: AAMustProgressImpl
{
2759 AAMustProgressCallSite(const IRPosition
&IRP
, Attributor
&A
)
2760 : AAMustProgressImpl(IRP
, A
) {}
2762 /// See AbstractAttribute::updateImpl(...).
2763 ChangeStatus
updateImpl(Attributor
&A
) override
{
2764 // TODO: Once we have call site specific value information we can provide
2765 // call site specific liveness information and then it makes
2766 // sense to specialize attributes for call sites arguments instead of
2767 // redirecting requests to the callee argument.
2768 const IRPosition
&FnPos
= IRPosition::function(*getAnchorScope());
2769 bool IsKnownMustProgress
;
2770 if (!AA::hasAssumedIRAttr
<Attribute::MustProgress
>(
2771 A
, this, FnPos
, DepClassTy::REQUIRED
, IsKnownMustProgress
))
2772 return indicatePessimisticFixpoint();
2773 return ChangeStatus::UNCHANGED
;
2776 /// See AbstractAttribute::trackStatistics()
2777 void trackStatistics() const override
{
2778 STATS_DECLTRACK_CS_ATTR(mustprogress
);
2783 /// ------------------------ No-Recurse Attributes ----------------------------
2786 struct AANoRecurseImpl
: public AANoRecurse
{
2787 AANoRecurseImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoRecurse(IRP
, A
) {}
2789 /// See AbstractAttribute::initialize(...).
2790 void initialize(Attributor
&A
) override
{
2792 assert(!AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
2793 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
2797 /// See AbstractAttribute::getAsStr()
2798 const std::string
getAsStr(Attributor
*A
) const override
{
2799 return getAssumed() ? "norecurse" : "may-recurse";
2803 struct AANoRecurseFunction final
: AANoRecurseImpl
{
2804 AANoRecurseFunction(const IRPosition
&IRP
, Attributor
&A
)
2805 : AANoRecurseImpl(IRP
, A
) {}
2807 /// See AbstractAttribute::updateImpl(...).
2808 ChangeStatus
updateImpl(Attributor
&A
) override
{
2810 // If all live call sites are known to be no-recurse, we are as well.
2811 auto CallSitePred
= [&](AbstractCallSite ACS
) {
2812 bool IsKnownNoRecurse
;
2813 if (!AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
2815 IRPosition::function(*ACS
.getInstruction()->getFunction()),
2816 DepClassTy::NONE
, IsKnownNoRecurse
))
2818 return IsKnownNoRecurse
;
2820 bool UsedAssumedInformation
= false;
2821 if (A
.checkForAllCallSites(CallSitePred
, *this, true,
2822 UsedAssumedInformation
)) {
2823 // If we know all call sites and all are known no-recurse, we are done.
2824 // If all known call sites, which might not be all that exist, are known
2825 // to be no-recurse, we are not done but we can continue to assume
2826 // no-recurse. If one of the call sites we have not visited will become
2827 // live, another update is triggered.
2828 if (!UsedAssumedInformation
)
2829 indicateOptimisticFixpoint();
2830 return ChangeStatus::UNCHANGED
;
2833 const AAInterFnReachability
*EdgeReachability
=
2834 A
.getAAFor
<AAInterFnReachability
>(*this, getIRPosition(),
2835 DepClassTy::REQUIRED
);
2836 if (EdgeReachability
&& EdgeReachability
->canReach(A
, *getAnchorScope()))
2837 return indicatePessimisticFixpoint();
2838 return ChangeStatus::UNCHANGED
;
2841 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(norecurse
) }
2844 /// NoRecurse attribute deduction for a call sites.
2845 struct AANoRecurseCallSite final
2846 : AACalleeToCallSite
<AANoRecurse
, AANoRecurseImpl
> {
2847 AANoRecurseCallSite(const IRPosition
&IRP
, Attributor
&A
)
2848 : AACalleeToCallSite
<AANoRecurse
, AANoRecurseImpl
>(IRP
, A
) {}
2850 /// See AbstractAttribute::trackStatistics()
2851 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(norecurse
); }
2855 /// ------------------------ No-Convergent Attribute --------------------------
2858 struct AANonConvergentImpl
: public AANonConvergent
{
2859 AANonConvergentImpl(const IRPosition
&IRP
, Attributor
&A
)
2860 : AANonConvergent(IRP
, A
) {}
2862 /// See AbstractAttribute::getAsStr()
2863 const std::string
getAsStr(Attributor
*A
) const override
{
2864 return getAssumed() ? "non-convergent" : "may-be-convergent";
2868 struct AANonConvergentFunction final
: AANonConvergentImpl
{
2869 AANonConvergentFunction(const IRPosition
&IRP
, Attributor
&A
)
2870 : AANonConvergentImpl(IRP
, A
) {}
2872 /// See AbstractAttribute::updateImpl(...).
2873 ChangeStatus
updateImpl(Attributor
&A
) override
{
2874 // If all function calls are known to not be convergent, we are not
2876 auto CalleeIsNotConvergent
= [&](Instruction
&Inst
) {
2877 CallBase
&CB
= cast
<CallBase
>(Inst
);
2878 auto *Callee
= dyn_cast_if_present
<Function
>(CB
.getCalledOperand());
2879 if (!Callee
|| Callee
->isIntrinsic()) {
2882 if (Callee
->isDeclaration()) {
2883 return !Callee
->hasFnAttribute(Attribute::Convergent
);
2885 const auto *ConvergentAA
= A
.getAAFor
<AANonConvergent
>(
2886 *this, IRPosition::function(*Callee
), DepClassTy::REQUIRED
);
2887 return ConvergentAA
&& ConvergentAA
->isAssumedNotConvergent();
2890 bool UsedAssumedInformation
= false;
2891 if (!A
.checkForAllCallLikeInstructions(CalleeIsNotConvergent
, *this,
2892 UsedAssumedInformation
)) {
2893 return indicatePessimisticFixpoint();
2895 return ChangeStatus::UNCHANGED
;
2898 ChangeStatus
manifest(Attributor
&A
) override
{
2899 if (isKnownNotConvergent() &&
2900 A
.hasAttr(getIRPosition(), Attribute::Convergent
)) {
2901 A
.removeAttrs(getIRPosition(), {Attribute::Convergent
});
2902 return ChangeStatus::CHANGED
;
2904 return ChangeStatus::UNCHANGED
;
2907 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(convergent
) }
2911 /// -------------------- Undefined-Behavior Attributes ------------------------
2914 struct AAUndefinedBehaviorImpl
: public AAUndefinedBehavior
{
2915 AAUndefinedBehaviorImpl(const IRPosition
&IRP
, Attributor
&A
)
2916 : AAUndefinedBehavior(IRP
, A
) {}
2918 /// See AbstractAttribute::updateImpl(...).
2919 // through a pointer (i.e. also branches etc.)
2920 ChangeStatus
updateImpl(Attributor
&A
) override
{
2921 const size_t UBPrevSize
= KnownUBInsts
.size();
2922 const size_t NoUBPrevSize
= AssumedNoUBInsts
.size();
2924 auto InspectMemAccessInstForUB
= [&](Instruction
&I
) {
2925 // Lang ref now states volatile store is not UB, let's skip them.
2926 if (I
.isVolatile() && I
.mayWriteToMemory())
2929 // Skip instructions that are already saved.
2930 if (AssumedNoUBInsts
.count(&I
) || KnownUBInsts
.count(&I
))
2933 // If we reach here, we know we have an instruction
2934 // that accesses memory through a pointer operand,
2935 // for which getPointerOperand() should give it to us.
2937 const_cast<Value
*>(getPointerOperand(&I
, /* AllowVolatile */ true));
2939 "Expected pointer operand of memory accessing instruction");
2941 // Either we stopped and the appropriate action was taken,
2942 // or we got back a simplified value to continue.
2943 std::optional
<Value
*> SimplifiedPtrOp
=
2944 stopOnUndefOrAssumed(A
, PtrOp
, &I
);
2945 if (!SimplifiedPtrOp
|| !*SimplifiedPtrOp
)
2947 const Value
*PtrOpVal
= *SimplifiedPtrOp
;
2949 // A memory access through a pointer is considered UB
2950 // only if the pointer has constant null value.
2951 // TODO: Expand it to not only check constant values.
2952 if (!isa
<ConstantPointerNull
>(PtrOpVal
)) {
2953 AssumedNoUBInsts
.insert(&I
);
2956 const Type
*PtrTy
= PtrOpVal
->getType();
2958 // Because we only consider instructions inside functions,
2959 // assume that a parent function exists.
2960 const Function
*F
= I
.getFunction();
2962 // A memory access using constant null pointer is only considered UB
2963 // if null pointer is _not_ defined for the target platform.
2964 if (llvm::NullPointerIsDefined(F
, PtrTy
->getPointerAddressSpace()))
2965 AssumedNoUBInsts
.insert(&I
);
2967 KnownUBInsts
.insert(&I
);
2971 auto InspectBrInstForUB
= [&](Instruction
&I
) {
2972 // A conditional branch instruction is considered UB if it has `undef`
2975 // Skip instructions that are already saved.
2976 if (AssumedNoUBInsts
.count(&I
) || KnownUBInsts
.count(&I
))
2979 // We know we have a branch instruction.
2980 auto *BrInst
= cast
<BranchInst
>(&I
);
2982 // Unconditional branches are never considered UB.
2983 if (BrInst
->isUnconditional())
2986 // Either we stopped and the appropriate action was taken,
2987 // or we got back a simplified value to continue.
2988 std::optional
<Value
*> SimplifiedCond
=
2989 stopOnUndefOrAssumed(A
, BrInst
->getCondition(), BrInst
);
2990 if (!SimplifiedCond
|| !*SimplifiedCond
)
2992 AssumedNoUBInsts
.insert(&I
);
2996 auto InspectCallSiteForUB
= [&](Instruction
&I
) {
2997 // Check whether a callsite always cause UB or not
2999 // Skip instructions that are already saved.
3000 if (AssumedNoUBInsts
.count(&I
) || KnownUBInsts
.count(&I
))
3003 // Check nonnull and noundef argument attribute violation for each
3005 CallBase
&CB
= cast
<CallBase
>(I
);
3006 auto *Callee
= dyn_cast_if_present
<Function
>(CB
.getCalledOperand());
3009 for (unsigned idx
= 0; idx
< CB
.arg_size(); idx
++) {
3010 // If current argument is known to be simplified to null pointer and the
3011 // corresponding argument position is known to have nonnull attribute,
3012 // the argument is poison. Furthermore, if the argument is poison and
3013 // the position is known to have noundef attriubte, this callsite is
3015 if (idx
>= Callee
->arg_size())
3017 Value
*ArgVal
= CB
.getArgOperand(idx
);
3020 // Here, we handle three cases.
3021 // (1) Not having a value means it is dead. (we can replace the value
3023 // (2) Simplified to undef. The argument violate noundef attriubte.
3024 // (3) Simplified to null pointer where known to be nonnull.
3025 // The argument is a poison value and violate noundef attribute.
3026 IRPosition CalleeArgumentIRP
= IRPosition::callsite_argument(CB
, idx
);
3027 bool IsKnownNoUndef
;
3028 AA::hasAssumedIRAttr
<Attribute::NoUndef
>(
3029 A
, this, CalleeArgumentIRP
, DepClassTy::NONE
, IsKnownNoUndef
);
3030 if (!IsKnownNoUndef
)
3032 bool UsedAssumedInformation
= false;
3033 std::optional
<Value
*> SimplifiedVal
=
3034 A
.getAssumedSimplified(IRPosition::value(*ArgVal
), *this,
3035 UsedAssumedInformation
, AA::Interprocedural
);
3036 if (UsedAssumedInformation
)
3038 if (SimplifiedVal
&& !*SimplifiedVal
)
3040 if (!SimplifiedVal
|| isa
<UndefValue
>(**SimplifiedVal
)) {
3041 KnownUBInsts
.insert(&I
);
3044 if (!ArgVal
->getType()->isPointerTy() ||
3045 !isa
<ConstantPointerNull
>(**SimplifiedVal
))
3047 bool IsKnownNonNull
;
3048 AA::hasAssumedIRAttr
<Attribute::NonNull
>(
3049 A
, this, CalleeArgumentIRP
, DepClassTy::NONE
, IsKnownNonNull
);
3051 KnownUBInsts
.insert(&I
);
3056 auto InspectReturnInstForUB
= [&](Instruction
&I
) {
3057 auto &RI
= cast
<ReturnInst
>(I
);
3058 // Either we stopped and the appropriate action was taken,
3059 // or we got back a simplified return value to continue.
3060 std::optional
<Value
*> SimplifiedRetValue
=
3061 stopOnUndefOrAssumed(A
, RI
.getReturnValue(), &I
);
3062 if (!SimplifiedRetValue
|| !*SimplifiedRetValue
)
3065 // Check if a return instruction always cause UB or not
3066 // Note: It is guaranteed that the returned position of the anchor
3067 // scope has noundef attribute when this is called.
3068 // We also ensure the return position is not "assumed dead"
3069 // because the returned value was then potentially simplified to
3070 // `undef` in AAReturnedValues without removing the `noundef`
3073 // When the returned position has noundef attriubte, UB occurs in the
3075 // (1) Returned value is known to be undef.
3076 // (2) The value is known to be a null pointer and the returned
3077 // position has nonnull attribute (because the returned value is
3079 if (isa
<ConstantPointerNull
>(*SimplifiedRetValue
)) {
3080 bool IsKnownNonNull
;
3081 AA::hasAssumedIRAttr
<Attribute::NonNull
>(
3082 A
, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE
,
3085 KnownUBInsts
.insert(&I
);
3091 bool UsedAssumedInformation
= false;
3092 A
.checkForAllInstructions(InspectMemAccessInstForUB
, *this,
3093 {Instruction::Load
, Instruction::Store
,
3094 Instruction::AtomicCmpXchg
,
3095 Instruction::AtomicRMW
},
3096 UsedAssumedInformation
,
3097 /* CheckBBLivenessOnly */ true);
3098 A
.checkForAllInstructions(InspectBrInstForUB
, *this, {Instruction::Br
},
3099 UsedAssumedInformation
,
3100 /* CheckBBLivenessOnly */ true);
3101 A
.checkForAllCallLikeInstructions(InspectCallSiteForUB
, *this,
3102 UsedAssumedInformation
);
3104 // If the returned position of the anchor scope has noundef attriubte, check
3105 // all returned instructions.
3106 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3107 const IRPosition
&ReturnIRP
= IRPosition::returned(*getAnchorScope());
3108 if (!A
.isAssumedDead(ReturnIRP
, this, nullptr, UsedAssumedInformation
)) {
3109 bool IsKnownNoUndef
;
3110 AA::hasAssumedIRAttr
<Attribute::NoUndef
>(
3111 A
, this, ReturnIRP
, DepClassTy::NONE
, IsKnownNoUndef
);
3113 A
.checkForAllInstructions(InspectReturnInstForUB
, *this,
3114 {Instruction::Ret
}, UsedAssumedInformation
,
3115 /* CheckBBLivenessOnly */ true);
3119 if (NoUBPrevSize
!= AssumedNoUBInsts
.size() ||
3120 UBPrevSize
!= KnownUBInsts
.size())
3121 return ChangeStatus::CHANGED
;
3122 return ChangeStatus::UNCHANGED
;
3125 bool isKnownToCauseUB(Instruction
*I
) const override
{
3126 return KnownUBInsts
.count(I
);
3129 bool isAssumedToCauseUB(Instruction
*I
) const override
{
3130 // In simple words, if an instruction is not in the assumed to _not_
3131 // cause UB, then it is assumed UB (that includes those
3132 // in the KnownUBInsts set). The rest is boilerplate
3133 // is to ensure that it is one of the instructions we test
3136 switch (I
->getOpcode()) {
3137 case Instruction::Load
:
3138 case Instruction::Store
:
3139 case Instruction::AtomicCmpXchg
:
3140 case Instruction::AtomicRMW
:
3141 return !AssumedNoUBInsts
.count(I
);
3142 case Instruction::Br
: {
3143 auto *BrInst
= cast
<BranchInst
>(I
);
3144 if (BrInst
->isUnconditional())
3146 return !AssumedNoUBInsts
.count(I
);
3154 ChangeStatus
manifest(Attributor
&A
) override
{
3155 if (KnownUBInsts
.empty())
3156 return ChangeStatus::UNCHANGED
;
3157 for (Instruction
*I
: KnownUBInsts
)
3158 A
.changeToUnreachableAfterManifest(I
);
3159 return ChangeStatus::CHANGED
;
3162 /// See AbstractAttribute::getAsStr()
3163 const std::string
getAsStr(Attributor
*A
) const override
{
3164 return getAssumed() ? "undefined-behavior" : "no-ub";
3167 /// Note: The correctness of this analysis depends on the fact that the
3168 /// following 2 sets will stop changing after some point.
3169 /// "Change" here means that their size changes.
3170 /// The size of each set is monotonically increasing
3171 /// (we only add items to them) and it is upper bounded by the number of
3172 /// instructions in the processed function (we can never save more
3173 /// elements in either set than this number). Hence, at some point,
3174 /// they will stop increasing.
3175 /// Consequently, at some point, both sets will have stopped
3176 /// changing, effectively making the analysis reach a fixpoint.
3178 /// Note: These 2 sets are disjoint and an instruction can be considered
3179 /// one of 3 things:
3180 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3181 /// the KnownUBInsts set.
3182 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3183 /// has a reason to assume it).
3184 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3185 /// could not find a reason to assume or prove that it can cause UB,
3186 /// hence it assumes it doesn't. We have a set for these instructions
3187 /// so that we don't reprocess them in every update.
3188 /// Note however that instructions in this set may cause UB.
3191 /// A set of all live instructions _known_ to cause UB.
3192 SmallPtrSet
<Instruction
*, 8> KnownUBInsts
;
3195 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3196 SmallPtrSet
<Instruction
*, 8> AssumedNoUBInsts
;
3198 // Should be called on updates in which if we're processing an instruction
3199 // \p I that depends on a value \p V, one of the following has to happen:
3200 // - If the value is assumed, then stop.
3201 // - If the value is known but undef, then consider it UB.
3202 // - Otherwise, do specific processing with the simplified value.
3203 // We return std::nullopt in the first 2 cases to signify that an appropriate
3204 // action was taken and the caller should stop.
3205 // Otherwise, we return the simplified value that the caller should
3206 // use for specific processing.
3207 std::optional
<Value
*> stopOnUndefOrAssumed(Attributor
&A
, Value
*V
,
3209 bool UsedAssumedInformation
= false;
3210 std::optional
<Value
*> SimplifiedV
=
3211 A
.getAssumedSimplified(IRPosition::value(*V
), *this,
3212 UsedAssumedInformation
, AA::Interprocedural
);
3213 if (!UsedAssumedInformation
) {
3214 // Don't depend on assumed values.
3216 // If it is known (which we tested above) but it doesn't have a value,
3217 // then we can assume `undef` and hence the instruction is UB.
3218 KnownUBInsts
.insert(I
);
3219 return std::nullopt
;
3225 if (isa
<UndefValue
>(V
)) {
3226 KnownUBInsts
.insert(I
);
3227 return std::nullopt
;
3233 struct AAUndefinedBehaviorFunction final
: AAUndefinedBehaviorImpl
{
3234 AAUndefinedBehaviorFunction(const IRPosition
&IRP
, Attributor
&A
)
3235 : AAUndefinedBehaviorImpl(IRP
, A
) {}
3237 /// See AbstractAttribute::trackStatistics()
3238 void trackStatistics() const override
{
3239 STATS_DECL(UndefinedBehaviorInstruction
, Instruction
,
3240 "Number of instructions known to have UB");
3241 BUILD_STAT_NAME(UndefinedBehaviorInstruction
, Instruction
) +=
3242 KnownUBInsts
.size();
3247 /// ------------------------ Will-Return Attributes ----------------------------
3250 // Helper function that checks whether a function has any cycle which we don't
3251 // know if it is bounded or not.
3252 // Loops with maximum trip count are considered bounded, any other cycle not.
3253 static bool mayContainUnboundedCycle(Function
&F
, Attributor
&A
) {
3254 ScalarEvolution
*SE
=
3255 A
.getInfoCache().getAnalysisResultForFunction
<ScalarEvolutionAnalysis
>(F
);
3256 LoopInfo
*LI
= A
.getInfoCache().getAnalysisResultForFunction
<LoopAnalysis
>(F
);
3257 // If either SCEV or LoopInfo is not available for the function then we assume
3258 // any cycle to be unbounded cycle.
3259 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3260 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3262 for (scc_iterator
<Function
*> SCCI
= scc_begin(&F
); !SCCI
.isAtEnd(); ++SCCI
)
3263 if (SCCI
.hasCycle())
3268 // If there's irreducible control, the function may contain non-loop cycles.
3269 if (mayContainIrreducibleControl(F
, LI
))
3272 // Any loop that does not have a max trip count is considered unbounded cycle.
3273 for (auto *L
: LI
->getLoopsInPreorder()) {
3274 if (!SE
->getSmallConstantMaxTripCount(L
))
3280 struct AAWillReturnImpl
: public AAWillReturn
{
3281 AAWillReturnImpl(const IRPosition
&IRP
, Attributor
&A
)
3282 : AAWillReturn(IRP
, A
) {}
3284 /// See AbstractAttribute::initialize(...).
3285 void initialize(Attributor
&A
) override
{
3287 assert(!AA::hasAssumedIRAttr
<Attribute::WillReturn
>(
3288 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
3292 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3293 bool isImpliedByMustprogressAndReadonly(Attributor
&A
, bool KnownOnly
) {
3294 if (!A
.hasAttr(getIRPosition(), {Attribute::MustProgress
}))
3298 if (AA::isAssumedReadOnly(A
, getIRPosition(), *this, IsKnown
))
3299 return IsKnown
|| !KnownOnly
;
3303 /// See AbstractAttribute::updateImpl(...).
3304 ChangeStatus
updateImpl(Attributor
&A
) override
{
3305 if (isImpliedByMustprogressAndReadonly(A
, /* KnownOnly */ false))
3306 return ChangeStatus::UNCHANGED
;
3308 auto CheckForWillReturn
= [&](Instruction
&I
) {
3309 IRPosition IPos
= IRPosition::callsite_function(cast
<CallBase
>(I
));
3311 if (AA::hasAssumedIRAttr
<Attribute::WillReturn
>(
3312 A
, this, IPos
, DepClassTy::REQUIRED
, IsKnown
)) {
3318 bool IsKnownNoRecurse
;
3319 return AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
3320 A
, this, IPos
, DepClassTy::REQUIRED
, IsKnownNoRecurse
);
3323 bool UsedAssumedInformation
= false;
3324 if (!A
.checkForAllCallLikeInstructions(CheckForWillReturn
, *this,
3325 UsedAssumedInformation
))
3326 return indicatePessimisticFixpoint();
3328 return ChangeStatus::UNCHANGED
;
3331 /// See AbstractAttribute::getAsStr()
3332 const std::string
getAsStr(Attributor
*A
) const override
{
3333 return getAssumed() ? "willreturn" : "may-noreturn";
3337 struct AAWillReturnFunction final
: AAWillReturnImpl
{
3338 AAWillReturnFunction(const IRPosition
&IRP
, Attributor
&A
)
3339 : AAWillReturnImpl(IRP
, A
) {}
3341 /// See AbstractAttribute::initialize(...).
3342 void initialize(Attributor
&A
) override
{
3343 AAWillReturnImpl::initialize(A
);
3345 Function
*F
= getAnchorScope();
3346 assert(F
&& "Did expect an anchor function");
3347 if (F
->isDeclaration() || mayContainUnboundedCycle(*F
, A
))
3348 indicatePessimisticFixpoint();
3351 /// See AbstractAttribute::trackStatistics()
3352 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(willreturn
) }
3355 /// WillReturn attribute deduction for a call sites.
3356 struct AAWillReturnCallSite final
3357 : AACalleeToCallSite
<AAWillReturn
, AAWillReturnImpl
> {
3358 AAWillReturnCallSite(const IRPosition
&IRP
, Attributor
&A
)
3359 : AACalleeToCallSite
<AAWillReturn
, AAWillReturnImpl
>(IRP
, A
) {}
3361 /// See AbstractAttribute::updateImpl(...).
3362 ChangeStatus
updateImpl(Attributor
&A
) override
{
3363 if (isImpliedByMustprogressAndReadonly(A
, /* KnownOnly */ false))
3364 return ChangeStatus::UNCHANGED
;
3366 return AACalleeToCallSite::updateImpl(A
);
3369 /// See AbstractAttribute::trackStatistics()
3370 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(willreturn
); }
3374 /// -------------------AAIntraFnReachability Attribute--------------------------
3376 /// All information associated with a reachability query. This boilerplate code
3377 /// is used by both AAIntraFnReachability and AAInterFnReachability, with
3378 /// different \p ToTy values.
3379 template <typename ToTy
> struct ReachabilityQueryInfo
{
3380 enum class Reachable
{
3386 const Instruction
*From
= nullptr;
3387 /// reach this place,
3388 const ToTy
*To
= nullptr;
3389 /// without going through any of these instructions,
3390 const AA::InstExclusionSetTy
*ExclusionSet
= nullptr;
3391 /// and remember if it worked:
3392 Reachable Result
= Reachable::No
;
3394 /// Precomputed hash for this RQI.
3397 unsigned computeHashValue() const {
3398 assert(Hash
== 0 && "Computed hash twice!");
3399 using InstSetDMI
= DenseMapInfo
<const AA::InstExclusionSetTy
*>;
3400 using PairDMI
= DenseMapInfo
<std::pair
<const Instruction
*, const ToTy
*>>;
3401 return const_cast<ReachabilityQueryInfo
<ToTy
> *>(this)->Hash
=
3402 detail::combineHashValue(PairDMI ::getHashValue({From
, To
}),
3403 InstSetDMI::getHashValue(ExclusionSet
));
3406 ReachabilityQueryInfo(const Instruction
*From
, const ToTy
*To
)
3407 : From(From
), To(To
) {}
3409 /// Constructor replacement to ensure unique and stable sets are used for the
3411 ReachabilityQueryInfo(Attributor
&A
, const Instruction
&From
, const ToTy
&To
,
3412 const AA::InstExclusionSetTy
*ES
, bool MakeUnique
)
3413 : From(&From
), To(&To
), ExclusionSet(ES
) {
3415 if (!ES
|| ES
->empty()) {
3416 ExclusionSet
= nullptr;
3417 } else if (MakeUnique
) {
3418 ExclusionSet
= A
.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES
);
3422 ReachabilityQueryInfo(const ReachabilityQueryInfo
&RQI
)
3423 : From(RQI
.From
), To(RQI
.To
), ExclusionSet(RQI
.ExclusionSet
) {}
3427 template <typename ToTy
> struct DenseMapInfo
<ReachabilityQueryInfo
<ToTy
> *> {
3428 using InstSetDMI
= DenseMapInfo
<const AA::InstExclusionSetTy
*>;
3429 using PairDMI
= DenseMapInfo
<std::pair
<const Instruction
*, const ToTy
*>>;
3431 static ReachabilityQueryInfo
<ToTy
> EmptyKey
;
3432 static ReachabilityQueryInfo
<ToTy
> TombstoneKey
;
3434 static inline ReachabilityQueryInfo
<ToTy
> *getEmptyKey() { return &EmptyKey
; }
3435 static inline ReachabilityQueryInfo
<ToTy
> *getTombstoneKey() {
3436 return &TombstoneKey
;
3438 static unsigned getHashValue(const ReachabilityQueryInfo
<ToTy
> *RQI
) {
3439 return RQI
->Hash
? RQI
->Hash
: RQI
->computeHashValue();
3441 static bool isEqual(const ReachabilityQueryInfo
<ToTy
> *LHS
,
3442 const ReachabilityQueryInfo
<ToTy
> *RHS
) {
3443 if (!PairDMI::isEqual({LHS
->From
, LHS
->To
}, {RHS
->From
, RHS
->To
}))
3445 return InstSetDMI::isEqual(LHS
->ExclusionSet
, RHS
->ExclusionSet
);
3449 #define DefineKeys(ToTy) \
3451 ReachabilityQueryInfo<ToTy> \
3452 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3453 ReachabilityQueryInfo<ToTy>( \
3454 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3455 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3457 ReachabilityQueryInfo<ToTy> \
3458 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3459 ReachabilityQueryInfo<ToTy>( \
3460 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3461 DenseMapInfo<const ToTy *>::getTombstoneKey());
3463 DefineKeys(Instruction
) DefineKeys(Function
)
3470 template <typename BaseTy
, typename ToTy
>
3471 struct CachedReachabilityAA
: public BaseTy
{
3472 using RQITy
= ReachabilityQueryInfo
<ToTy
>;
3474 CachedReachabilityAA(const IRPosition
&IRP
, Attributor
&A
) : BaseTy(IRP
, A
) {}
3476 /// See AbstractAttribute::isQueryAA.
3477 bool isQueryAA() const override
{ return true; }
3479 /// See AbstractAttribute::updateImpl(...).
3480 ChangeStatus
updateImpl(Attributor
&A
) override
{
3481 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
3482 for (unsigned u
= 0, e
= QueryVector
.size(); u
< e
; ++u
) {
3483 RQITy
*RQI
= QueryVector
[u
];
3484 if (RQI
->Result
== RQITy::Reachable::No
&&
3485 isReachableImpl(A
, *RQI
, /*IsTemporaryRQI=*/false))
3486 Changed
= ChangeStatus::CHANGED
;
3491 virtual bool isReachableImpl(Attributor
&A
, RQITy
&RQI
,
3492 bool IsTemporaryRQI
) = 0;
3494 bool rememberResult(Attributor
&A
, typename
RQITy::Reachable Result
,
3495 RQITy
&RQI
, bool UsedExclusionSet
, bool IsTemporaryRQI
) {
3496 RQI
.Result
= Result
;
3498 // Remove the temporary RQI from the cache.
3500 QueryCache
.erase(&RQI
);
3502 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3503 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3504 // this query. 2) We did not use the exclusion set, potentially because
3506 if (Result
== RQITy::Reachable::Yes
|| !UsedExclusionSet
) {
3507 RQITy
PlainRQI(RQI
.From
, RQI
.To
);
3508 if (!QueryCache
.count(&PlainRQI
)) {
3509 RQITy
*RQIPtr
= new (A
.Allocator
) RQITy(RQI
.From
, RQI
.To
);
3510 RQIPtr
->Result
= Result
;
3511 QueryVector
.push_back(RQIPtr
);
3512 QueryCache
.insert(RQIPtr
);
3516 // Check if we need to insert a new permanent RQI with the exclusion set.
3517 if (IsTemporaryRQI
&& Result
!= RQITy::Reachable::Yes
&& UsedExclusionSet
) {
3518 assert((!RQI
.ExclusionSet
|| !RQI
.ExclusionSet
->empty()) &&
3519 "Did not expect empty set!");
3520 RQITy
*RQIPtr
= new (A
.Allocator
)
3521 RQITy(A
, *RQI
.From
, *RQI
.To
, RQI
.ExclusionSet
, true);
3522 assert(RQIPtr
->Result
== RQITy::Reachable::No
&& "Already reachable?");
3523 RQIPtr
->Result
= Result
;
3524 assert(!QueryCache
.count(RQIPtr
));
3525 QueryVector
.push_back(RQIPtr
);
3526 QueryCache
.insert(RQIPtr
);
3529 if (Result
== RQITy::Reachable::No
&& IsTemporaryRQI
)
3530 A
.registerForUpdate(*this);
3531 return Result
== RQITy::Reachable::Yes
;
3534 const std::string
getAsStr(Attributor
*A
) const override
{
3535 // TODO: Return the number of reachable queries.
3536 return "#queries(" + std::to_string(QueryVector
.size()) + ")";
3539 bool checkQueryCache(Attributor
&A
, RQITy
&StackRQI
,
3540 typename
RQITy::Reachable
&Result
) {
3541 if (!this->getState().isValidState()) {
3542 Result
= RQITy::Reachable::Yes
;
3546 // If we have an exclusion set we might be able to find our answer by
3547 // ignoring it first.
3548 if (StackRQI
.ExclusionSet
) {
3549 RQITy
PlainRQI(StackRQI
.From
, StackRQI
.To
);
3550 auto It
= QueryCache
.find(&PlainRQI
);
3551 if (It
!= QueryCache
.end() && (*It
)->Result
== RQITy::Reachable::No
) {
3552 Result
= RQITy::Reachable::No
;
3557 auto It
= QueryCache
.find(&StackRQI
);
3558 if (It
!= QueryCache
.end()) {
3559 Result
= (*It
)->Result
;
3563 // Insert a temporary for recursive queries. We will replace it with a
3564 // permanent entry later.
3565 QueryCache
.insert(&StackRQI
);
3570 SmallVector
<RQITy
*> QueryVector
;
3571 DenseSet
<RQITy
*> QueryCache
;
3574 struct AAIntraFnReachabilityFunction final
3575 : public CachedReachabilityAA
<AAIntraFnReachability
, Instruction
> {
3576 using Base
= CachedReachabilityAA
<AAIntraFnReachability
, Instruction
>;
3577 AAIntraFnReachabilityFunction(const IRPosition
&IRP
, Attributor
&A
)
3579 DT
= A
.getInfoCache().getAnalysisResultForFunction
<DominatorTreeAnalysis
>(
3580 *IRP
.getAssociatedFunction());
3583 bool isAssumedReachable(
3584 Attributor
&A
, const Instruction
&From
, const Instruction
&To
,
3585 const AA::InstExclusionSetTy
*ExclusionSet
) const override
{
3586 auto *NonConstThis
= const_cast<AAIntraFnReachabilityFunction
*>(this);
3590 RQITy
StackRQI(A
, From
, To
, ExclusionSet
, false);
3591 typename
RQITy::Reachable Result
;
3592 if (!NonConstThis
->checkQueryCache(A
, StackRQI
, Result
))
3593 return NonConstThis
->isReachableImpl(A
, StackRQI
,
3594 /*IsTemporaryRQI=*/true);
3595 return Result
== RQITy::Reachable::Yes
;
3598 ChangeStatus
updateImpl(Attributor
&A
) override
{
3599 // We only depend on liveness. DeadEdges is all we care about, check if any
3602 A
.getAAFor
<AAIsDead
>(*this, getIRPosition(), DepClassTy::OPTIONAL
);
3604 llvm::all_of(DeadEdges
,
3605 [&](const auto &DeadEdge
) {
3606 return LivenessAA
->isEdgeDead(DeadEdge
.first
,
3609 llvm::all_of(DeadBlocks
, [&](const BasicBlock
*BB
) {
3610 return LivenessAA
->isAssumedDead(BB
);
3612 return ChangeStatus::UNCHANGED
;
3616 return Base::updateImpl(A
);
3619 bool isReachableImpl(Attributor
&A
, RQITy
&RQI
,
3620 bool IsTemporaryRQI
) override
{
3621 const Instruction
*Origin
= RQI
.From
;
3622 bool UsedExclusionSet
= false;
3624 auto WillReachInBlock
= [&](const Instruction
&From
, const Instruction
&To
,
3625 const AA::InstExclusionSetTy
*ExclusionSet
) {
3626 const Instruction
*IP
= &From
;
3627 while (IP
&& IP
!= &To
) {
3628 if (ExclusionSet
&& IP
!= Origin
&& ExclusionSet
->count(IP
)) {
3629 UsedExclusionSet
= true;
3632 IP
= IP
->getNextNode();
3637 const BasicBlock
*FromBB
= RQI
.From
->getParent();
3638 const BasicBlock
*ToBB
= RQI
.To
->getParent();
3639 assert(FromBB
->getParent() == ToBB
->getParent() &&
3640 "Not an intra-procedural query!");
3642 // Check intra-block reachability, however, other reaching paths are still
3644 if (FromBB
== ToBB
&&
3645 WillReachInBlock(*RQI
.From
, *RQI
.To
, RQI
.ExclusionSet
))
3646 return rememberResult(A
, RQITy::Reachable::Yes
, RQI
, UsedExclusionSet
,
3649 // Check if reaching the ToBB block is sufficient or if even that would not
3650 // ensure reaching the target. In the latter case we are done.
3651 if (!WillReachInBlock(ToBB
->front(), *RQI
.To
, RQI
.ExclusionSet
))
3652 return rememberResult(A
, RQITy::Reachable::No
, RQI
, UsedExclusionSet
,
3655 const Function
*Fn
= FromBB
->getParent();
3656 SmallPtrSet
<const BasicBlock
*, 16> ExclusionBlocks
;
3657 if (RQI
.ExclusionSet
)
3658 for (auto *I
: *RQI
.ExclusionSet
)
3659 if (I
->getFunction() == Fn
)
3660 ExclusionBlocks
.insert(I
->getParent());
3662 // Check if we make it out of the FromBB block at all.
3663 if (ExclusionBlocks
.count(FromBB
) &&
3664 !WillReachInBlock(*RQI
.From
, *FromBB
->getTerminator(),
3666 return rememberResult(A
, RQITy::Reachable::No
, RQI
, true, IsTemporaryRQI
);
3669 A
.getAAFor
<AAIsDead
>(*this, getIRPosition(), DepClassTy::OPTIONAL
);
3670 if (LivenessAA
&& LivenessAA
->isAssumedDead(ToBB
)) {
3671 DeadBlocks
.insert(ToBB
);
3672 return rememberResult(A
, RQITy::Reachable::No
, RQI
, UsedExclusionSet
,
3676 SmallPtrSet
<const BasicBlock
*, 16> Visited
;
3677 SmallVector
<const BasicBlock
*, 16> Worklist
;
3678 Worklist
.push_back(FromBB
);
3680 DenseSet
<std::pair
<const BasicBlock
*, const BasicBlock
*>> LocalDeadEdges
;
3681 while (!Worklist
.empty()) {
3682 const BasicBlock
*BB
= Worklist
.pop_back_val();
3683 if (!Visited
.insert(BB
).second
)
3685 for (const BasicBlock
*SuccBB
: successors(BB
)) {
3686 if (LivenessAA
&& LivenessAA
->isEdgeDead(BB
, SuccBB
)) {
3687 LocalDeadEdges
.insert({BB
, SuccBB
});
3690 // We checked before if we just need to reach the ToBB block.
3692 return rememberResult(A
, RQITy::Reachable::Yes
, RQI
, UsedExclusionSet
,
3694 if (DT
&& ExclusionBlocks
.empty() && DT
->dominates(BB
, ToBB
))
3695 return rememberResult(A
, RQITy::Reachable::Yes
, RQI
, UsedExclusionSet
,
3698 if (ExclusionBlocks
.count(SuccBB
)) {
3699 UsedExclusionSet
= true;
3702 Worklist
.push_back(SuccBB
);
3706 DeadEdges
.insert(LocalDeadEdges
.begin(), LocalDeadEdges
.end());
3707 return rememberResult(A
, RQITy::Reachable::No
, RQI
, UsedExclusionSet
,
3711 /// See AbstractAttribute::trackStatistics()
3712 void trackStatistics() const override
{}
3715 // Set of assumed dead blocks we used in the last query. If any changes we
3716 // update the state.
3717 DenseSet
<const BasicBlock
*> DeadBlocks
;
3719 // Set of assumed dead edges we used in the last query. If any changes we
3720 // update the state.
3721 DenseSet
<std::pair
<const BasicBlock
*, const BasicBlock
*>> DeadEdges
;
3723 /// The dominator tree of the function to short-circuit reasoning.
3724 const DominatorTree
*DT
= nullptr;
3728 /// ------------------------ NoAlias Argument Attribute ------------------------
3730 bool AANoAlias::isImpliedByIR(Attributor
&A
, const IRPosition
&IRP
,
3731 Attribute::AttrKind ImpliedAttributeKind
,
3732 bool IgnoreSubsumingPositions
) {
3733 assert(ImpliedAttributeKind
== Attribute::NoAlias
&&
3734 "Unexpected attribute kind");
3735 Value
*Val
= &IRP
.getAssociatedValue();
3736 if (IRP
.getPositionKind() != IRP_CALL_SITE_ARGUMENT
) {
3737 if (isa
<AllocaInst
>(Val
))
3740 IgnoreSubsumingPositions
= true;
3743 if (isa
<UndefValue
>(Val
))
3746 if (isa
<ConstantPointerNull
>(Val
) &&
3747 !NullPointerIsDefined(IRP
.getAnchorScope(),
3748 Val
->getType()->getPointerAddressSpace()))
3751 if (A
.hasAttr(IRP
, {Attribute::ByVal
, Attribute::NoAlias
},
3752 IgnoreSubsumingPositions
, Attribute::NoAlias
))
3759 struct AANoAliasImpl
: AANoAlias
{
3760 AANoAliasImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoAlias(IRP
, A
) {
3761 assert(getAssociatedType()->isPointerTy() &&
3762 "Noalias is a pointer attribute");
3765 const std::string
getAsStr(Attributor
*A
) const override
{
3766 return getAssumed() ? "noalias" : "may-alias";
3770 /// NoAlias attribute for a floating value.
3771 struct AANoAliasFloating final
: AANoAliasImpl
{
3772 AANoAliasFloating(const IRPosition
&IRP
, Attributor
&A
)
3773 : AANoAliasImpl(IRP
, A
) {}
3775 /// See AbstractAttribute::updateImpl(...).
3776 ChangeStatus
updateImpl(Attributor
&A
) override
{
3777 // TODO: Implement this.
3778 return indicatePessimisticFixpoint();
3781 /// See AbstractAttribute::trackStatistics()
3782 void trackStatistics() const override
{
3783 STATS_DECLTRACK_FLOATING_ATTR(noalias
)
3787 /// NoAlias attribute for an argument.
3788 struct AANoAliasArgument final
3789 : AAArgumentFromCallSiteArguments
<AANoAlias
, AANoAliasImpl
> {
3790 using Base
= AAArgumentFromCallSiteArguments
<AANoAlias
, AANoAliasImpl
>;
3791 AANoAliasArgument(const IRPosition
&IRP
, Attributor
&A
) : Base(IRP
, A
) {}
3793 /// See AbstractAttribute::update(...).
3794 ChangeStatus
updateImpl(Attributor
&A
) override
{
3795 // We have to make sure no-alias on the argument does not break
3796 // synchronization when this is a callback argument, see also [1] below.
3797 // If synchronization cannot be affected, we delegate to the base updateImpl
3798 // function, otherwise we give up for now.
3800 // If the function is no-sync, no-alias cannot break synchronization.
3802 if (AA::hasAssumedIRAttr
<Attribute::NoSync
>(
3803 A
, this, IRPosition::function_scope(getIRPosition()),
3804 DepClassTy::OPTIONAL
, IsKnownNoSycn
))
3805 return Base::updateImpl(A
);
3807 // If the argument is read-only, no-alias cannot break synchronization.
3809 if (AA::isAssumedReadOnly(A
, getIRPosition(), *this, IsKnown
))
3810 return Base::updateImpl(A
);
3812 // If the argument is never passed through callbacks, no-alias cannot break
3814 bool UsedAssumedInformation
= false;
3815 if (A
.checkForAllCallSites(
3816 [](AbstractCallSite ACS
) { return !ACS
.isCallbackCall(); }, *this,
3817 true, UsedAssumedInformation
))
3818 return Base::updateImpl(A
);
3820 // TODO: add no-alias but make sure it doesn't break synchronization by
3821 // introducing fake uses. See:
3822 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3823 // International Workshop on OpenMP 2018,
3824 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3826 return indicatePessimisticFixpoint();
3829 /// See AbstractAttribute::trackStatistics()
3830 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(noalias
) }
3833 struct AANoAliasCallSiteArgument final
: AANoAliasImpl
{
3834 AANoAliasCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
3835 : AANoAliasImpl(IRP
, A
) {}
3837 /// Determine if the underlying value may alias with the call site argument
3838 /// \p OtherArgNo of \p ICS (= the underlying call site).
3839 bool mayAliasWithArgument(Attributor
&A
, AAResults
*&AAR
,
3840 const AAMemoryBehavior
&MemBehaviorAA
,
3841 const CallBase
&CB
, unsigned OtherArgNo
) {
3842 // We do not need to worry about aliasing with the underlying IRP.
3843 if (this->getCalleeArgNo() == (int)OtherArgNo
)
3846 // If it is not a pointer or pointer vector we do not alias.
3847 const Value
*ArgOp
= CB
.getArgOperand(OtherArgNo
);
3848 if (!ArgOp
->getType()->isPtrOrPtrVectorTy())
3851 auto *CBArgMemBehaviorAA
= A
.getAAFor
<AAMemoryBehavior
>(
3852 *this, IRPosition::callsite_argument(CB
, OtherArgNo
), DepClassTy::NONE
);
3854 // If the argument is readnone, there is no read-write aliasing.
3855 if (CBArgMemBehaviorAA
&& CBArgMemBehaviorAA
->isAssumedReadNone()) {
3856 A
.recordDependence(*CBArgMemBehaviorAA
, *this, DepClassTy::OPTIONAL
);
3860 // If the argument is readonly and the underlying value is readonly, there
3861 // is no read-write aliasing.
3862 bool IsReadOnly
= MemBehaviorAA
.isAssumedReadOnly();
3863 if (CBArgMemBehaviorAA
&& CBArgMemBehaviorAA
->isAssumedReadOnly() &&
3865 A
.recordDependence(MemBehaviorAA
, *this, DepClassTy::OPTIONAL
);
3866 A
.recordDependence(*CBArgMemBehaviorAA
, *this, DepClassTy::OPTIONAL
);
3870 // We have to utilize actual alias analysis queries so we need the object.
3872 AAR
= A
.getInfoCache().getAnalysisResultForFunction
<AAManager
>(
3875 // Try to rule it out at the call site.
3876 bool IsAliasing
= !AAR
|| !AAR
->isNoAlias(&getAssociatedValue(), ArgOp
);
3877 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3878 "callsite arguments: "
3879 << getAssociatedValue() << " " << *ArgOp
<< " => "
3880 << (IsAliasing
? "" : "no-") << "alias \n");
3885 bool isKnownNoAliasDueToNoAliasPreservation(
3886 Attributor
&A
, AAResults
*&AAR
, const AAMemoryBehavior
&MemBehaviorAA
) {
3887 // We can deduce "noalias" if the following conditions hold.
3888 // (i) Associated value is assumed to be noalias in the definition.
3889 // (ii) Associated value is assumed to be no-capture in all the uses
3890 // possibly executed before this callsite.
3891 // (iii) There is no other pointer argument which could alias with the
3894 auto IsDereferenceableOrNull
= [&](Value
*O
, const DataLayout
&DL
) {
3895 const auto *DerefAA
= A
.getAAFor
<AADereferenceable
>(
3896 *this, IRPosition::value(*O
), DepClassTy::OPTIONAL
);
3897 return DerefAA
? DerefAA
->getAssumedDereferenceableBytes() : 0;
3900 const IRPosition
&VIRP
= IRPosition::value(getAssociatedValue());
3901 const Function
*ScopeFn
= VIRP
.getAnchorScope();
3902 // Check whether the value is captured in the scope using AANoCapture.
3903 // Look at CFG and check only uses possibly executed before this
3905 auto UsePred
= [&](const Use
&U
, bool &Follow
) -> bool {
3906 Instruction
*UserI
= cast
<Instruction
>(U
.getUser());
3908 // If UserI is the curr instruction and there is a single potential use of
3909 // the value in UserI we allow the use.
3910 // TODO: We should inspect the operands and allow those that cannot alias
3912 if (UserI
== getCtxI() && UserI
->getNumOperands() == 1)
3916 if (auto *CB
= dyn_cast
<CallBase
>(UserI
)) {
3917 if (CB
->isArgOperand(&U
)) {
3919 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
3921 bool IsKnownNoCapture
;
3922 if (AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
3923 A
, this, IRPosition::callsite_argument(*CB
, ArgNo
),
3924 DepClassTy::OPTIONAL
, IsKnownNoCapture
))
3929 if (!AA::isPotentiallyReachable(
3930 A
, *UserI
, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3931 [ScopeFn
](const Function
&Fn
) { return &Fn
!= ScopeFn
; }))
3935 // TODO: We should track the capturing uses in AANoCapture but the problem
3936 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3937 // a value in the module slice.
3938 switch (DetermineUseCaptureKind(U
, IsDereferenceableOrNull
)) {
3939 case UseCaptureKind::NO_CAPTURE
:
3941 case UseCaptureKind::MAY_CAPTURE
:
3942 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI
3945 case UseCaptureKind::PASSTHROUGH
:
3949 llvm_unreachable("unknown UseCaptureKind");
3952 bool IsKnownNoCapture
;
3953 const AANoCapture
*NoCaptureAA
= nullptr;
3954 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
3955 A
, this, VIRP
, DepClassTy::NONE
, IsKnownNoCapture
, false, &NoCaptureAA
);
3956 if (!IsAssumedNoCapture
&&
3957 (!NoCaptureAA
|| !NoCaptureAA
->isAssumedNoCaptureMaybeReturned())) {
3958 if (!A
.checkForAllUses(UsePred
, *this, getAssociatedValue())) {
3960 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3961 << " cannot be noalias as it is potentially captured\n");
3966 A
.recordDependence(*NoCaptureAA
, *this, DepClassTy::OPTIONAL
);
3968 // Check there is no other pointer argument which could alias with the
3969 // value passed at this call site.
3970 // TODO: AbstractCallSite
3971 const auto &CB
= cast
<CallBase
>(getAnchorValue());
3972 for (unsigned OtherArgNo
= 0; OtherArgNo
< CB
.arg_size(); OtherArgNo
++)
3973 if (mayAliasWithArgument(A
, AAR
, MemBehaviorAA
, CB
, OtherArgNo
))
3979 /// See AbstractAttribute::updateImpl(...).
3980 ChangeStatus
updateImpl(Attributor
&A
) override
{
3981 // If the argument is readnone we are done as there are no accesses via the
3983 auto *MemBehaviorAA
=
3984 A
.getAAFor
<AAMemoryBehavior
>(*this, getIRPosition(), DepClassTy::NONE
);
3985 if (MemBehaviorAA
&& MemBehaviorAA
->isAssumedReadNone()) {
3986 A
.recordDependence(*MemBehaviorAA
, *this, DepClassTy::OPTIONAL
);
3987 return ChangeStatus::UNCHANGED
;
3990 bool IsKnownNoAlias
;
3991 const IRPosition
&VIRP
= IRPosition::value(getAssociatedValue());
3992 if (!AA::hasAssumedIRAttr
<Attribute::NoAlias
>(
3993 A
, this, VIRP
, DepClassTy::REQUIRED
, IsKnownNoAlias
)) {
3994 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
3995 << " is not no-alias at the definition\n");
3996 return indicatePessimisticFixpoint();
3999 AAResults
*AAR
= nullptr;
4000 if (MemBehaviorAA
&&
4001 isKnownNoAliasDueToNoAliasPreservation(A
, AAR
, *MemBehaviorAA
)) {
4003 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4004 return ChangeStatus::UNCHANGED
;
4007 return indicatePessimisticFixpoint();
4010 /// See AbstractAttribute::trackStatistics()
4011 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(noalias
) }
4014 /// NoAlias attribute for function return value.
4015 struct AANoAliasReturned final
: AANoAliasImpl
{
4016 AANoAliasReturned(const IRPosition
&IRP
, Attributor
&A
)
4017 : AANoAliasImpl(IRP
, A
) {}
4019 /// See AbstractAttribute::updateImpl(...).
4020 ChangeStatus
updateImpl(Attributor
&A
) override
{
4022 auto CheckReturnValue
= [&](Value
&RV
) -> bool {
4023 if (Constant
*C
= dyn_cast
<Constant
>(&RV
))
4024 if (C
->isNullValue() || isa
<UndefValue
>(C
))
4027 /// For now, we can only deduce noalias if we have call sites.
4028 /// FIXME: add more support.
4029 if (!isa
<CallBase
>(&RV
))
4032 const IRPosition
&RVPos
= IRPosition::value(RV
);
4033 bool IsKnownNoAlias
;
4034 if (!AA::hasAssumedIRAttr
<Attribute::NoAlias
>(
4035 A
, this, RVPos
, DepClassTy::REQUIRED
, IsKnownNoAlias
))
4038 bool IsKnownNoCapture
;
4039 const AANoCapture
*NoCaptureAA
= nullptr;
4040 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
4041 A
, this, RVPos
, DepClassTy::REQUIRED
, IsKnownNoCapture
, false,
4043 return IsAssumedNoCapture
||
4044 (NoCaptureAA
&& NoCaptureAA
->isAssumedNoCaptureMaybeReturned());
4047 if (!A
.checkForAllReturnedValues(CheckReturnValue
, *this))
4048 return indicatePessimisticFixpoint();
4050 return ChangeStatus::UNCHANGED
;
4053 /// See AbstractAttribute::trackStatistics()
4054 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(noalias
) }
4057 /// NoAlias attribute deduction for a call site return value.
4058 struct AANoAliasCallSiteReturned final
4059 : AACalleeToCallSite
<AANoAlias
, AANoAliasImpl
> {
4060 AANoAliasCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
4061 : AACalleeToCallSite
<AANoAlias
, AANoAliasImpl
>(IRP
, A
) {}
4063 /// See AbstractAttribute::trackStatistics()
4064 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(noalias
); }
4068 /// -------------------AAIsDead Function Attribute-----------------------
4071 struct AAIsDeadValueImpl
: public AAIsDead
{
4072 AAIsDeadValueImpl(const IRPosition
&IRP
, Attributor
&A
) : AAIsDead(IRP
, A
) {}
4074 /// See AAIsDead::isAssumedDead().
4075 bool isAssumedDead() const override
{ return isAssumed(IS_DEAD
); }
4077 /// See AAIsDead::isKnownDead().
4078 bool isKnownDead() const override
{ return isKnown(IS_DEAD
); }
4080 /// See AAIsDead::isAssumedDead(BasicBlock *).
4081 bool isAssumedDead(const BasicBlock
*BB
) const override
{ return false; }
4083 /// See AAIsDead::isKnownDead(BasicBlock *).
4084 bool isKnownDead(const BasicBlock
*BB
) const override
{ return false; }
4086 /// See AAIsDead::isAssumedDead(Instruction *I).
4087 bool isAssumedDead(const Instruction
*I
) const override
{
4088 return I
== getCtxI() && isAssumedDead();
4091 /// See AAIsDead::isKnownDead(Instruction *I).
4092 bool isKnownDead(const Instruction
*I
) const override
{
4093 return isAssumedDead(I
) && isKnownDead();
4096 /// See AbstractAttribute::getAsStr().
4097 const std::string
getAsStr(Attributor
*A
) const override
{
4098 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4101 /// Check if all uses are assumed dead.
4102 bool areAllUsesAssumedDead(Attributor
&A
, Value
&V
) {
4103 // Callers might not check the type, void has no uses.
4104 if (V
.getType()->isVoidTy() || V
.use_empty())
4107 // If we replace a value with a constant there are no uses left afterwards.
4108 if (!isa
<Constant
>(V
)) {
4109 if (auto *I
= dyn_cast
<Instruction
>(&V
))
4110 if (!A
.isRunOn(*I
->getFunction()))
4112 bool UsedAssumedInformation
= false;
4113 std::optional
<Constant
*> C
=
4114 A
.getAssumedConstant(V
, *this, UsedAssumedInformation
);
4119 auto UsePred
= [&](const Use
&U
, bool &Follow
) { return false; };
4120 // Explicitly set the dependence class to required because we want a long
4121 // chain of N dependent instructions to be considered live as soon as one is
4122 // without going through N update cycles. This is not required for
4124 return A
.checkForAllUses(UsePred
, *this, V
, /* CheckBBLivenessOnly */ false,
4125 DepClassTy::REQUIRED
,
4126 /* IgnoreDroppableUses */ false);
4129 /// Determine if \p I is assumed to be side-effect free.
4130 bool isAssumedSideEffectFree(Attributor
&A
, Instruction
*I
) {
4131 if (!I
|| wouldInstructionBeTriviallyDead(I
))
4134 auto *CB
= dyn_cast
<CallBase
>(I
);
4135 if (!CB
|| isa
<IntrinsicInst
>(CB
))
4138 const IRPosition
&CallIRP
= IRPosition::callsite_function(*CB
);
4140 bool IsKnownNoUnwind
;
4141 if (!AA::hasAssumedIRAttr
<Attribute::NoUnwind
>(
4142 A
, this, CallIRP
, DepClassTy::OPTIONAL
, IsKnownNoUnwind
))
4146 return AA::isAssumedReadOnly(A
, CallIRP
, *this, IsKnown
);
4150 struct AAIsDeadFloating
: public AAIsDeadValueImpl
{
4151 AAIsDeadFloating(const IRPosition
&IRP
, Attributor
&A
)
4152 : AAIsDeadValueImpl(IRP
, A
) {}
4154 /// See AbstractAttribute::initialize(...).
4155 void initialize(Attributor
&A
) override
{
4156 AAIsDeadValueImpl::initialize(A
);
4158 if (isa
<UndefValue
>(getAssociatedValue())) {
4159 indicatePessimisticFixpoint();
4163 Instruction
*I
= dyn_cast
<Instruction
>(&getAssociatedValue());
4164 if (!isAssumedSideEffectFree(A
, I
)) {
4165 if (!isa_and_nonnull
<StoreInst
>(I
) && !isa_and_nonnull
<FenceInst
>(I
))
4166 indicatePessimisticFixpoint();
4168 removeAssumedBits(HAS_NO_EFFECT
);
4172 bool isDeadFence(Attributor
&A
, FenceInst
&FI
) {
4173 const auto *ExecDomainAA
= A
.lookupAAFor
<AAExecutionDomain
>(
4174 IRPosition::function(*FI
.getFunction()), *this, DepClassTy::NONE
);
4175 if (!ExecDomainAA
|| !ExecDomainAA
->isNoOpFence(FI
))
4177 A
.recordDependence(*ExecDomainAA
, *this, DepClassTy::OPTIONAL
);
4181 bool isDeadStore(Attributor
&A
, StoreInst
&SI
,
4182 SmallSetVector
<Instruction
*, 8> *AssumeOnlyInst
= nullptr) {
4183 // Lang ref now states volatile store is not UB/dead, let's skip them.
4184 if (SI
.isVolatile())
4187 // If we are collecting assumes to be deleted we are in the manifest stage.
4188 // It's problematic to collect the potential copies again now so we use the
4190 bool UsedAssumedInformation
= false;
4191 if (!AssumeOnlyInst
) {
4192 PotentialCopies
.clear();
4193 if (!AA::getPotentialCopiesOfStoredValue(A
, SI
, PotentialCopies
, *this,
4194 UsedAssumedInformation
)) {
4197 << "[AAIsDead] Could not determine potential copies of store!\n");
4201 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies
.size()
4202 << " potential copies.\n");
4204 InformationCache
&InfoCache
= A
.getInfoCache();
4205 return llvm::all_of(PotentialCopies
, [&](Value
*V
) {
4206 if (A
.isAssumedDead(IRPosition::value(*V
), this, nullptr,
4207 UsedAssumedInformation
))
4209 if (auto *LI
= dyn_cast
<LoadInst
>(V
)) {
4210 if (llvm::all_of(LI
->uses(), [&](const Use
&U
) {
4211 auto &UserI
= cast
<Instruction
>(*U
.getUser());
4212 if (InfoCache
.isOnlyUsedByAssume(UserI
)) {
4214 AssumeOnlyInst
->insert(&UserI
);
4217 return A
.isAssumedDead(U
, this, nullptr, UsedAssumedInformation
);
4222 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4223 << " is assumed live!\n");
4228 /// See AbstractAttribute::getAsStr().
4229 const std::string
getAsStr(Attributor
*A
) const override
{
4230 Instruction
*I
= dyn_cast
<Instruction
>(&getAssociatedValue());
4231 if (isa_and_nonnull
<StoreInst
>(I
))
4233 return "assumed-dead-store";
4234 if (isa_and_nonnull
<FenceInst
>(I
))
4236 return "assumed-dead-fence";
4237 return AAIsDeadValueImpl::getAsStr(A
);
4240 /// See AbstractAttribute::updateImpl(...).
4241 ChangeStatus
updateImpl(Attributor
&A
) override
{
4242 Instruction
*I
= dyn_cast
<Instruction
>(&getAssociatedValue());
4243 if (auto *SI
= dyn_cast_or_null
<StoreInst
>(I
)) {
4244 if (!isDeadStore(A
, *SI
))
4245 return indicatePessimisticFixpoint();
4246 } else if (auto *FI
= dyn_cast_or_null
<FenceInst
>(I
)) {
4247 if (!isDeadFence(A
, *FI
))
4248 return indicatePessimisticFixpoint();
4250 if (!isAssumedSideEffectFree(A
, I
))
4251 return indicatePessimisticFixpoint();
4252 if (!areAllUsesAssumedDead(A
, getAssociatedValue()))
4253 return indicatePessimisticFixpoint();
4255 return ChangeStatus::UNCHANGED
;
4258 bool isRemovableStore() const override
{
4259 return isAssumed(IS_REMOVABLE
) && isa
<StoreInst
>(&getAssociatedValue());
4262 /// See AbstractAttribute::manifest(...).
4263 ChangeStatus
manifest(Attributor
&A
) override
{
4264 Value
&V
= getAssociatedValue();
4265 if (auto *I
= dyn_cast
<Instruction
>(&V
)) {
4266 // If we get here we basically know the users are all dead. We check if
4267 // isAssumedSideEffectFree returns true here again because it might not be
4268 // the case and only the users are dead but the instruction (=call) is
4270 if (auto *SI
= dyn_cast
<StoreInst
>(I
)) {
4271 SmallSetVector
<Instruction
*, 8> AssumeOnlyInst
;
4272 bool IsDead
= isDeadStore(A
, *SI
, &AssumeOnlyInst
);
4274 assert(IsDead
&& "Store was assumed to be dead!");
4275 A
.deleteAfterManifest(*I
);
4276 for (size_t i
= 0; i
< AssumeOnlyInst
.size(); ++i
) {
4277 Instruction
*AOI
= AssumeOnlyInst
[i
];
4278 for (auto *Usr
: AOI
->users())
4279 AssumeOnlyInst
.insert(cast
<Instruction
>(Usr
));
4280 A
.deleteAfterManifest(*AOI
);
4282 return ChangeStatus::CHANGED
;
4284 if (auto *FI
= dyn_cast
<FenceInst
>(I
)) {
4285 assert(isDeadFence(A
, *FI
));
4286 A
.deleteAfterManifest(*FI
);
4287 return ChangeStatus::CHANGED
;
4289 if (isAssumedSideEffectFree(A
, I
) && !isa
<InvokeInst
>(I
)) {
4290 A
.deleteAfterManifest(*I
);
4291 return ChangeStatus::CHANGED
;
4294 return ChangeStatus::UNCHANGED
;
4297 /// See AbstractAttribute::trackStatistics()
4298 void trackStatistics() const override
{
4299 STATS_DECLTRACK_FLOATING_ATTR(IsDead
)
4303 // The potential copies of a dead store, used for deletion during manifest.
4304 SmallSetVector
<Value
*, 4> PotentialCopies
;
4307 struct AAIsDeadArgument
: public AAIsDeadFloating
{
4308 AAIsDeadArgument(const IRPosition
&IRP
, Attributor
&A
)
4309 : AAIsDeadFloating(IRP
, A
) {}
4311 /// See AbstractAttribute::manifest(...).
4312 ChangeStatus
manifest(Attributor
&A
) override
{
4313 Argument
&Arg
= *getAssociatedArgument();
4314 if (A
.isValidFunctionSignatureRewrite(Arg
, /* ReplacementTypes */ {}))
4315 if (A
.registerFunctionSignatureRewrite(
4316 Arg
, /* ReplacementTypes */ {},
4317 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy
{},
4318 Attributor::ArgumentReplacementInfo::ACSRepairCBTy
{})) {
4319 return ChangeStatus::CHANGED
;
4321 return ChangeStatus::UNCHANGED
;
4324 /// See AbstractAttribute::trackStatistics()
4325 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(IsDead
) }
4328 struct AAIsDeadCallSiteArgument
: public AAIsDeadValueImpl
{
4329 AAIsDeadCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
4330 : AAIsDeadValueImpl(IRP
, A
) {}
4332 /// See AbstractAttribute::initialize(...).
4333 void initialize(Attributor
&A
) override
{
4334 AAIsDeadValueImpl::initialize(A
);
4335 if (isa
<UndefValue
>(getAssociatedValue()))
4336 indicatePessimisticFixpoint();
4339 /// See AbstractAttribute::updateImpl(...).
4340 ChangeStatus
updateImpl(Attributor
&A
) override
{
4341 // TODO: Once we have call site specific value information we can provide
4342 // call site specific liveness information and then it makes
4343 // sense to specialize attributes for call sites arguments instead of
4344 // redirecting requests to the callee argument.
4345 Argument
*Arg
= getAssociatedArgument();
4347 return indicatePessimisticFixpoint();
4348 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
4349 auto *ArgAA
= A
.getAAFor
<AAIsDead
>(*this, ArgPos
, DepClassTy::REQUIRED
);
4351 return indicatePessimisticFixpoint();
4352 return clampStateAndIndicateChange(getState(), ArgAA
->getState());
4355 /// See AbstractAttribute::manifest(...).
4356 ChangeStatus
manifest(Attributor
&A
) override
{
4357 CallBase
&CB
= cast
<CallBase
>(getAnchorValue());
4358 Use
&U
= CB
.getArgOperandUse(getCallSiteArgNo());
4359 assert(!isa
<UndefValue
>(U
.get()) &&
4360 "Expected undef values to be filtered out!");
4361 UndefValue
&UV
= *UndefValue::get(U
->getType());
4362 if (A
.changeUseAfterManifest(U
, UV
))
4363 return ChangeStatus::CHANGED
;
4364 return ChangeStatus::UNCHANGED
;
4367 /// See AbstractAttribute::trackStatistics()
4368 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(IsDead
) }
4371 struct AAIsDeadCallSiteReturned
: public AAIsDeadFloating
{
4372 AAIsDeadCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
4373 : AAIsDeadFloating(IRP
, A
) {}
4375 /// See AAIsDead::isAssumedDead().
4376 bool isAssumedDead() const override
{
4377 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree
;
4380 /// See AbstractAttribute::initialize(...).
4381 void initialize(Attributor
&A
) override
{
4382 AAIsDeadFloating::initialize(A
);
4383 if (isa
<UndefValue
>(getAssociatedValue())) {
4384 indicatePessimisticFixpoint();
4388 // We track this separately as a secondary state.
4389 IsAssumedSideEffectFree
= isAssumedSideEffectFree(A
, getCtxI());
4392 /// See AbstractAttribute::updateImpl(...).
4393 ChangeStatus
updateImpl(Attributor
&A
) override
{
4394 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
4395 if (IsAssumedSideEffectFree
&& !isAssumedSideEffectFree(A
, getCtxI())) {
4396 IsAssumedSideEffectFree
= false;
4397 Changed
= ChangeStatus::CHANGED
;
4399 if (!areAllUsesAssumedDead(A
, getAssociatedValue()))
4400 return indicatePessimisticFixpoint();
4404 /// See AbstractAttribute::trackStatistics()
4405 void trackStatistics() const override
{
4406 if (IsAssumedSideEffectFree
)
4407 STATS_DECLTRACK_CSRET_ATTR(IsDead
)
4409 STATS_DECLTRACK_CSRET_ATTR(UnusedResult
)
4412 /// See AbstractAttribute::getAsStr().
4413 const std::string
getAsStr(Attributor
*A
) const override
{
4414 return isAssumedDead()
4416 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4420 bool IsAssumedSideEffectFree
= true;
4423 struct AAIsDeadReturned
: public AAIsDeadValueImpl
{
4424 AAIsDeadReturned(const IRPosition
&IRP
, Attributor
&A
)
4425 : AAIsDeadValueImpl(IRP
, A
) {}
4427 /// See AbstractAttribute::updateImpl(...).
4428 ChangeStatus
updateImpl(Attributor
&A
) override
{
4430 bool UsedAssumedInformation
= false;
4431 A
.checkForAllInstructions([](Instruction
&) { return true; }, *this,
4432 {Instruction::Ret
}, UsedAssumedInformation
);
4434 auto PredForCallSite
= [&](AbstractCallSite ACS
) {
4435 if (ACS
.isCallbackCall() || !ACS
.getInstruction())
4437 return areAllUsesAssumedDead(A
, *ACS
.getInstruction());
4440 if (!A
.checkForAllCallSites(PredForCallSite
, *this, true,
4441 UsedAssumedInformation
))
4442 return indicatePessimisticFixpoint();
4444 return ChangeStatus::UNCHANGED
;
4447 /// See AbstractAttribute::manifest(...).
4448 ChangeStatus
manifest(Attributor
&A
) override
{
4449 // TODO: Rewrite the signature to return void?
4450 bool AnyChange
= false;
4451 UndefValue
&UV
= *UndefValue::get(getAssociatedFunction()->getReturnType());
4452 auto RetInstPred
= [&](Instruction
&I
) {
4453 ReturnInst
&RI
= cast
<ReturnInst
>(I
);
4454 if (!isa
<UndefValue
>(RI
.getReturnValue()))
4455 AnyChange
|= A
.changeUseAfterManifest(RI
.getOperandUse(0), UV
);
4458 bool UsedAssumedInformation
= false;
4459 A
.checkForAllInstructions(RetInstPred
, *this, {Instruction::Ret
},
4460 UsedAssumedInformation
);
4461 return AnyChange
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
4464 /// See AbstractAttribute::trackStatistics()
4465 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(IsDead
) }
4468 struct AAIsDeadFunction
: public AAIsDead
{
4469 AAIsDeadFunction(const IRPosition
&IRP
, Attributor
&A
) : AAIsDead(IRP
, A
) {}
4471 /// See AbstractAttribute::initialize(...).
4472 void initialize(Attributor
&A
) override
{
4473 Function
*F
= getAnchorScope();
4474 assert(F
&& "Did expect an anchor function");
4475 if (!isAssumedDeadInternalFunction(A
)) {
4476 ToBeExploredFrom
.insert(&F
->getEntryBlock().front());
4477 assumeLive(A
, F
->getEntryBlock());
4481 bool isAssumedDeadInternalFunction(Attributor
&A
) {
4482 if (!getAnchorScope()->hasLocalLinkage())
4484 bool UsedAssumedInformation
= false;
4485 return A
.checkForAllCallSites([](AbstractCallSite
) { return false; }, *this,
4486 true, UsedAssumedInformation
);
4489 /// See AbstractAttribute::getAsStr().
4490 const std::string
getAsStr(Attributor
*A
) const override
{
4491 return "Live[#BB " + std::to_string(AssumedLiveBlocks
.size()) + "/" +
4492 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4493 std::to_string(ToBeExploredFrom
.size()) + "][#KDE " +
4494 std::to_string(KnownDeadEnds
.size()) + "]";
4497 /// See AbstractAttribute::manifest(...).
4498 ChangeStatus
manifest(Attributor
&A
) override
{
4499 assert(getState().isValidState() &&
4500 "Attempted to manifest an invalid state!");
4502 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
4503 Function
&F
= *getAnchorScope();
4505 if (AssumedLiveBlocks
.empty()) {
4506 A
.deleteAfterManifest(F
);
4507 return ChangeStatus::CHANGED
;
4510 // Flag to determine if we can change an invoke to a call assuming the
4511 // callee is nounwind. This is not possible if the personality of the
4512 // function allows to catch asynchronous exceptions.
4513 bool Invoke2CallAllowed
= !mayCatchAsynchronousExceptions(F
);
4515 KnownDeadEnds
.set_union(ToBeExploredFrom
);
4516 for (const Instruction
*DeadEndI
: KnownDeadEnds
) {
4517 auto *CB
= dyn_cast
<CallBase
>(DeadEndI
);
4520 bool IsKnownNoReturn
;
4521 bool MayReturn
= !AA::hasAssumedIRAttr
<Attribute::NoReturn
>(
4522 A
, this, IRPosition::callsite_function(*CB
), DepClassTy::OPTIONAL
,
4524 if (MayReturn
&& (!Invoke2CallAllowed
|| !isa
<InvokeInst
>(CB
)))
4527 if (auto *II
= dyn_cast
<InvokeInst
>(DeadEndI
))
4528 A
.registerInvokeWithDeadSuccessor(const_cast<InvokeInst
&>(*II
));
4530 A
.changeToUnreachableAfterManifest(
4531 const_cast<Instruction
*>(DeadEndI
->getNextNode()));
4532 HasChanged
= ChangeStatus::CHANGED
;
4535 STATS_DECL(AAIsDead
, BasicBlock
, "Number of dead basic blocks deleted.");
4536 for (BasicBlock
&BB
: F
)
4537 if (!AssumedLiveBlocks
.count(&BB
)) {
4538 A
.deleteAfterManifest(BB
);
4539 ++BUILD_STAT_NAME(AAIsDead
, BasicBlock
);
4540 HasChanged
= ChangeStatus::CHANGED
;
4546 /// See AbstractAttribute::updateImpl(...).
4547 ChangeStatus
updateImpl(Attributor
&A
) override
;
4549 bool isEdgeDead(const BasicBlock
*From
, const BasicBlock
*To
) const override
{
4550 assert(From
->getParent() == getAnchorScope() &&
4551 To
->getParent() == getAnchorScope() &&
4552 "Used AAIsDead of the wrong function");
4553 return isValidState() && !AssumedLiveEdges
.count(std::make_pair(From
, To
));
4556 /// See AbstractAttribute::trackStatistics()
4557 void trackStatistics() const override
{}
4559 /// Returns true if the function is assumed dead.
4560 bool isAssumedDead() const override
{ return false; }
4562 /// See AAIsDead::isKnownDead().
4563 bool isKnownDead() const override
{ return false; }
4565 /// See AAIsDead::isAssumedDead(BasicBlock *).
4566 bool isAssumedDead(const BasicBlock
*BB
) const override
{
4567 assert(BB
->getParent() == getAnchorScope() &&
4568 "BB must be in the same anchor scope function.");
4572 return !AssumedLiveBlocks
.count(BB
);
4575 /// See AAIsDead::isKnownDead(BasicBlock *).
4576 bool isKnownDead(const BasicBlock
*BB
) const override
{
4577 return getKnown() && isAssumedDead(BB
);
4580 /// See AAIsDead::isAssumed(Instruction *I).
4581 bool isAssumedDead(const Instruction
*I
) const override
{
4582 assert(I
->getParent()->getParent() == getAnchorScope() &&
4583 "Instruction must be in the same anchor scope function.");
4588 // If it is not in AssumedLiveBlocks then it for sure dead.
4589 // Otherwise, it can still be after noreturn call in a live block.
4590 if (!AssumedLiveBlocks
.count(I
->getParent()))
4593 // If it is not after a liveness barrier it is live.
4594 const Instruction
*PrevI
= I
->getPrevNode();
4596 if (KnownDeadEnds
.count(PrevI
) || ToBeExploredFrom
.count(PrevI
))
4598 PrevI
= PrevI
->getPrevNode();
4603 /// See AAIsDead::isKnownDead(Instruction *I).
4604 bool isKnownDead(const Instruction
*I
) const override
{
4605 return getKnown() && isAssumedDead(I
);
4608 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4609 /// that internal function called from \p BB should now be looked at.
4610 bool assumeLive(Attributor
&A
, const BasicBlock
&BB
) {
4611 if (!AssumedLiveBlocks
.insert(&BB
).second
)
4614 // We assume that all of BB is (probably) live now and if there are calls to
4615 // internal functions we will assume that those are now live as well. This
4616 // is a performance optimization for blocks with calls to a lot of internal
4617 // functions. It can however cause dead functions to be treated as live.
4618 for (const Instruction
&I
: BB
)
4619 if (const auto *CB
= dyn_cast
<CallBase
>(&I
))
4620 if (auto *F
= dyn_cast_if_present
<Function
>(CB
->getCalledOperand()))
4621 if (F
->hasLocalLinkage())
4622 A
.markLiveInternalFunction(*F
);
4626 /// Collection of instructions that need to be explored again, e.g., we
4627 /// did assume they do not transfer control to (one of their) successors.
4628 SmallSetVector
<const Instruction
*, 8> ToBeExploredFrom
;
4630 /// Collection of instructions that are known to not transfer control.
4631 SmallSetVector
<const Instruction
*, 8> KnownDeadEnds
;
4633 /// Collection of all assumed live edges
4634 DenseSet
<std::pair
<const BasicBlock
*, const BasicBlock
*>> AssumedLiveEdges
;
4636 /// Collection of all assumed live BasicBlocks.
4637 DenseSet
<const BasicBlock
*> AssumedLiveBlocks
;
4641 identifyAliveSuccessors(Attributor
&A
, const CallBase
&CB
,
4642 AbstractAttribute
&AA
,
4643 SmallVectorImpl
<const Instruction
*> &AliveSuccessors
) {
4644 const IRPosition
&IPos
= IRPosition::callsite_function(CB
);
4646 bool IsKnownNoReturn
;
4647 if (AA::hasAssumedIRAttr
<Attribute::NoReturn
>(
4648 A
, &AA
, IPos
, DepClassTy::OPTIONAL
, IsKnownNoReturn
))
4649 return !IsKnownNoReturn
;
4650 if (CB
.isTerminator())
4651 AliveSuccessors
.push_back(&CB
.getSuccessor(0)->front());
4653 AliveSuccessors
.push_back(CB
.getNextNode());
4658 identifyAliveSuccessors(Attributor
&A
, const InvokeInst
&II
,
4659 AbstractAttribute
&AA
,
4660 SmallVectorImpl
<const Instruction
*> &AliveSuccessors
) {
4661 bool UsedAssumedInformation
=
4662 identifyAliveSuccessors(A
, cast
<CallBase
>(II
), AA
, AliveSuccessors
);
4664 // First, determine if we can change an invoke to a call assuming the
4665 // callee is nounwind. This is not possible if the personality of the
4666 // function allows to catch asynchronous exceptions.
4667 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II
.getFunction())) {
4668 AliveSuccessors
.push_back(&II
.getUnwindDest()->front());
4670 const IRPosition
&IPos
= IRPosition::callsite_function(II
);
4672 bool IsKnownNoUnwind
;
4673 if (AA::hasAssumedIRAttr
<Attribute::NoUnwind
>(
4674 A
, &AA
, IPos
, DepClassTy::OPTIONAL
, IsKnownNoUnwind
)) {
4675 UsedAssumedInformation
|= !IsKnownNoUnwind
;
4677 AliveSuccessors
.push_back(&II
.getUnwindDest()->front());
4680 return UsedAssumedInformation
;
4684 identifyAliveSuccessors(Attributor
&A
, const BranchInst
&BI
,
4685 AbstractAttribute
&AA
,
4686 SmallVectorImpl
<const Instruction
*> &AliveSuccessors
) {
4687 bool UsedAssumedInformation
= false;
4688 if (BI
.getNumSuccessors() == 1) {
4689 AliveSuccessors
.push_back(&BI
.getSuccessor(0)->front());
4691 std::optional
<Constant
*> C
=
4692 A
.getAssumedConstant(*BI
.getCondition(), AA
, UsedAssumedInformation
);
4693 if (!C
|| isa_and_nonnull
<UndefValue
>(*C
)) {
4694 // No value yet, assume both edges are dead.
4695 } else if (isa_and_nonnull
<ConstantInt
>(*C
)) {
4696 const BasicBlock
*SuccBB
=
4697 BI
.getSuccessor(1 - cast
<ConstantInt
>(*C
)->getValue().getZExtValue());
4698 AliveSuccessors
.push_back(&SuccBB
->front());
4700 AliveSuccessors
.push_back(&BI
.getSuccessor(0)->front());
4701 AliveSuccessors
.push_back(&BI
.getSuccessor(1)->front());
4702 UsedAssumedInformation
= false;
4705 return UsedAssumedInformation
;
4709 identifyAliveSuccessors(Attributor
&A
, const SwitchInst
&SI
,
4710 AbstractAttribute
&AA
,
4711 SmallVectorImpl
<const Instruction
*> &AliveSuccessors
) {
4712 bool UsedAssumedInformation
= false;
4713 SmallVector
<AA::ValueAndContext
> Values
;
4714 if (!A
.getAssumedSimplifiedValues(IRPosition::value(*SI
.getCondition()), &AA
,
4715 Values
, AA::AnyScope
,
4716 UsedAssumedInformation
)) {
4717 // Something went wrong, assume all successors are live.
4718 for (const BasicBlock
*SuccBB
: successors(SI
.getParent()))
4719 AliveSuccessors
.push_back(&SuccBB
->front());
4723 if (Values
.empty() ||
4724 (Values
.size() == 1 &&
4725 isa_and_nonnull
<UndefValue
>(Values
.front().getValue()))) {
4726 // No valid value yet, assume all edges are dead.
4727 return UsedAssumedInformation
;
4730 Type
&Ty
= *SI
.getCondition()->getType();
4731 SmallPtrSet
<ConstantInt
*, 8> Constants
;
4732 auto CheckForConstantInt
= [&](Value
*V
) {
4733 if (auto *CI
= dyn_cast_if_present
<ConstantInt
>(AA::getWithType(*V
, Ty
))) {
4734 Constants
.insert(CI
);
4740 if (!all_of(Values
, [&](AA::ValueAndContext
&VAC
) {
4741 return CheckForConstantInt(VAC
.getValue());
4743 for (const BasicBlock
*SuccBB
: successors(SI
.getParent()))
4744 AliveSuccessors
.push_back(&SuccBB
->front());
4745 return UsedAssumedInformation
;
4748 unsigned MatchedCases
= 0;
4749 for (const auto &CaseIt
: SI
.cases()) {
4750 if (Constants
.count(CaseIt
.getCaseValue())) {
4752 AliveSuccessors
.push_back(&CaseIt
.getCaseSuccessor()->front());
4756 // If all potential values have been matched, we will not visit the default
4758 if (MatchedCases
< Constants
.size())
4759 AliveSuccessors
.push_back(&SI
.getDefaultDest()->front());
4760 return UsedAssumedInformation
;
4763 ChangeStatus
AAIsDeadFunction::updateImpl(Attributor
&A
) {
4764 ChangeStatus Change
= ChangeStatus::UNCHANGED
;
4766 if (AssumedLiveBlocks
.empty()) {
4767 if (isAssumedDeadInternalFunction(A
))
4768 return ChangeStatus::UNCHANGED
;
4770 Function
*F
= getAnchorScope();
4771 ToBeExploredFrom
.insert(&F
->getEntryBlock().front());
4772 assumeLive(A
, F
->getEntryBlock());
4773 Change
= ChangeStatus::CHANGED
;
4776 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks
.size() << "/"
4777 << getAnchorScope()->size() << "] BBs and "
4778 << ToBeExploredFrom
.size() << " exploration points and "
4779 << KnownDeadEnds
.size() << " known dead ends\n");
4781 // Copy and clear the list of instructions we need to explore from. It is
4782 // refilled with instructions the next update has to look at.
4783 SmallVector
<const Instruction
*, 8> Worklist(ToBeExploredFrom
.begin(),
4784 ToBeExploredFrom
.end());
4785 decltype(ToBeExploredFrom
) NewToBeExploredFrom
;
4787 SmallVector
<const Instruction
*, 8> AliveSuccessors
;
4788 while (!Worklist
.empty()) {
4789 const Instruction
*I
= Worklist
.pop_back_val();
4790 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I
<< "\n");
4792 // Fast forward for uninteresting instructions. We could look for UB here
4794 while (!I
->isTerminator() && !isa
<CallBase
>(I
))
4795 I
= I
->getNextNode();
4797 AliveSuccessors
.clear();
4799 bool UsedAssumedInformation
= false;
4800 switch (I
->getOpcode()) {
4801 // TODO: look for (assumed) UB to backwards propagate "deadness".
4803 assert(I
->isTerminator() &&
4804 "Expected non-terminators to be handled already!");
4805 for (const BasicBlock
*SuccBB
: successors(I
->getParent()))
4806 AliveSuccessors
.push_back(&SuccBB
->front());
4808 case Instruction::Call
:
4809 UsedAssumedInformation
= identifyAliveSuccessors(A
, cast
<CallInst
>(*I
),
4810 *this, AliveSuccessors
);
4812 case Instruction::Invoke
:
4813 UsedAssumedInformation
= identifyAliveSuccessors(A
, cast
<InvokeInst
>(*I
),
4814 *this, AliveSuccessors
);
4816 case Instruction::Br
:
4817 UsedAssumedInformation
= identifyAliveSuccessors(A
, cast
<BranchInst
>(*I
),
4818 *this, AliveSuccessors
);
4820 case Instruction::Switch
:
4821 UsedAssumedInformation
= identifyAliveSuccessors(A
, cast
<SwitchInst
>(*I
),
4822 *this, AliveSuccessors
);
4826 if (UsedAssumedInformation
) {
4827 NewToBeExploredFrom
.insert(I
);
4828 } else if (AliveSuccessors
.empty() ||
4829 (I
->isTerminator() &&
4830 AliveSuccessors
.size() < I
->getNumSuccessors())) {
4831 if (KnownDeadEnds
.insert(I
))
4832 Change
= ChangeStatus::CHANGED
;
4835 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4836 << AliveSuccessors
.size() << " UsedAssumedInformation: "
4837 << UsedAssumedInformation
<< "\n");
4839 for (const Instruction
*AliveSuccessor
: AliveSuccessors
) {
4840 if (!I
->isTerminator()) {
4841 assert(AliveSuccessors
.size() == 1 &&
4842 "Non-terminator expected to have a single successor!");
4843 Worklist
.push_back(AliveSuccessor
);
4845 // record the assumed live edge
4846 auto Edge
= std::make_pair(I
->getParent(), AliveSuccessor
->getParent());
4847 if (AssumedLiveEdges
.insert(Edge
).second
)
4848 Change
= ChangeStatus::CHANGED
;
4849 if (assumeLive(A
, *AliveSuccessor
->getParent()))
4850 Worklist
.push_back(AliveSuccessor
);
4855 // Check if the content of ToBeExploredFrom changed, ignore the order.
4856 if (NewToBeExploredFrom
.size() != ToBeExploredFrom
.size() ||
4857 llvm::any_of(NewToBeExploredFrom
, [&](const Instruction
*I
) {
4858 return !ToBeExploredFrom
.count(I
);
4860 Change
= ChangeStatus::CHANGED
;
4861 ToBeExploredFrom
= std::move(NewToBeExploredFrom
);
4864 // If we know everything is live there is no need to query for liveness.
4865 // Instead, indicating a pessimistic fixpoint will cause the state to be
4866 // "invalid" and all queries to be answered conservatively without lookups.
4867 // To be in this state we have to (1) finished the exploration and (3) not
4868 // discovered any non-trivial dead end and (2) not ruled unreachable code
4870 if (ToBeExploredFrom
.empty() &&
4871 getAnchorScope()->size() == AssumedLiveBlocks
.size() &&
4872 llvm::all_of(KnownDeadEnds
, [](const Instruction
*DeadEndI
) {
4873 return DeadEndI
->isTerminator() && DeadEndI
->getNumSuccessors() == 0;
4875 return indicatePessimisticFixpoint();
4879 /// Liveness information for a call sites.
4880 struct AAIsDeadCallSite final
: AAIsDeadFunction
{
4881 AAIsDeadCallSite(const IRPosition
&IRP
, Attributor
&A
)
4882 : AAIsDeadFunction(IRP
, A
) {}
4884 /// See AbstractAttribute::initialize(...).
4885 void initialize(Attributor
&A
) override
{
4886 // TODO: Once we have call site specific value information we can provide
4887 // call site specific liveness information and then it makes
4888 // sense to specialize attributes for call sites instead of
4889 // redirecting requests to the callee.
4890 llvm_unreachable("Abstract attributes for liveness are not "
4891 "supported for call sites yet!");
4894 /// See AbstractAttribute::updateImpl(...).
4895 ChangeStatus
updateImpl(Attributor
&A
) override
{
4896 return indicatePessimisticFixpoint();
4899 /// See AbstractAttribute::trackStatistics()
4900 void trackStatistics() const override
{}
4904 /// -------------------- Dereferenceable Argument Attribute --------------------
4907 struct AADereferenceableImpl
: AADereferenceable
{
4908 AADereferenceableImpl(const IRPosition
&IRP
, Attributor
&A
)
4909 : AADereferenceable(IRP
, A
) {}
4910 using StateType
= DerefState
;
4912 /// See AbstractAttribute::initialize(...).
4913 void initialize(Attributor
&A
) override
{
4914 Value
&V
= *getAssociatedValue().stripPointerCasts();
4915 SmallVector
<Attribute
, 4> Attrs
;
4916 A
.getAttrs(getIRPosition(),
4917 {Attribute::Dereferenceable
, Attribute::DereferenceableOrNull
},
4918 Attrs
, /* IgnoreSubsumingPositions */ false);
4919 for (const Attribute
&Attr
: Attrs
)
4920 takeKnownDerefBytesMaximum(Attr
.getValueAsInt());
4922 // Ensure we initialize the non-null AA (if necessary).
4923 bool IsKnownNonNull
;
4924 AA::hasAssumedIRAttr
<Attribute::NonNull
>(
4925 A
, this, getIRPosition(), DepClassTy::OPTIONAL
, IsKnownNonNull
);
4927 bool CanBeNull
, CanBeFreed
;
4928 takeKnownDerefBytesMaximum(V
.getPointerDereferenceableBytes(
4929 A
.getDataLayout(), CanBeNull
, CanBeFreed
));
4931 if (Instruction
*CtxI
= getCtxI())
4932 followUsesInMBEC(*this, A
, getState(), *CtxI
);
4935 /// See AbstractAttribute::getState()
4937 StateType
&getState() override
{ return *this; }
4938 const StateType
&getState() const override
{ return *this; }
4941 /// Helper function for collecting accessed bytes in must-be-executed-context
4942 void addAccessedBytesForUse(Attributor
&A
, const Use
*U
, const Instruction
*I
,
4943 DerefState
&State
) {
4944 const Value
*UseV
= U
->get();
4945 if (!UseV
->getType()->isPointerTy())
4948 std::optional
<MemoryLocation
> Loc
= MemoryLocation::getOrNone(I
);
4949 if (!Loc
|| Loc
->Ptr
!= UseV
|| !Loc
->Size
.isPrecise() || I
->isVolatile())
4953 const Value
*Base
= GetPointerBaseWithConstantOffset(
4954 Loc
->Ptr
, Offset
, A
.getDataLayout(), /*AllowNonInbounds*/ true);
4955 if (Base
&& Base
== &getAssociatedValue())
4956 State
.addAccessedBytes(Offset
, Loc
->Size
.getValue());
4959 /// See followUsesInMBEC
4960 bool followUseInMBEC(Attributor
&A
, const Use
*U
, const Instruction
*I
,
4961 AADereferenceable::StateType
&State
) {
4962 bool IsNonNull
= false;
4963 bool TrackUse
= false;
4964 int64_t DerefBytes
= getKnownNonNullAndDerefBytesForUse(
4965 A
, *this, getAssociatedValue(), U
, I
, IsNonNull
, TrackUse
);
4966 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4967 << " for instruction " << *I
<< "\n");
4969 addAccessedBytesForUse(A
, U
, I
, State
);
4970 State
.takeKnownDerefBytesMaximum(DerefBytes
);
4974 /// See AbstractAttribute::manifest(...).
4975 ChangeStatus
manifest(Attributor
&A
) override
{
4976 ChangeStatus Change
= AADereferenceable::manifest(A
);
4977 bool IsKnownNonNull
;
4978 bool IsAssumedNonNull
= AA::hasAssumedIRAttr
<Attribute::NonNull
>(
4979 A
, this, getIRPosition(), DepClassTy::NONE
, IsKnownNonNull
);
4980 if (IsAssumedNonNull
&&
4981 A
.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull
)) {
4982 A
.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull
});
4983 return ChangeStatus::CHANGED
;
4988 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
4989 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
4990 // TODO: Add *_globally support
4991 bool IsKnownNonNull
;
4992 bool IsAssumedNonNull
= AA::hasAssumedIRAttr
<Attribute::NonNull
>(
4993 A
, this, getIRPosition(), DepClassTy::NONE
, IsKnownNonNull
);
4994 if (IsAssumedNonNull
)
4995 Attrs
.emplace_back(Attribute::getWithDereferenceableBytes(
4996 Ctx
, getAssumedDereferenceableBytes()));
4998 Attrs
.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
4999 Ctx
, getAssumedDereferenceableBytes()));
5002 /// See AbstractAttribute::getAsStr().
5003 const std::string
getAsStr(Attributor
*A
) const override
{
5004 if (!getAssumedDereferenceableBytes())
5005 return "unknown-dereferenceable";
5006 bool IsKnownNonNull
;
5007 bool IsAssumedNonNull
= false;
5009 IsAssumedNonNull
= AA::hasAssumedIRAttr
<Attribute::NonNull
>(
5010 *A
, this, getIRPosition(), DepClassTy::NONE
, IsKnownNonNull
);
5011 return std::string("dereferenceable") +
5012 (IsAssumedNonNull
? "" : "_or_null") +
5013 (isAssumedGlobal() ? "_globally" : "") + "<" +
5014 std::to_string(getKnownDereferenceableBytes()) + "-" +
5015 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5016 (!A
? " [non-null is unknown]" : "");
5020 /// Dereferenceable attribute for a floating value.
5021 struct AADereferenceableFloating
: AADereferenceableImpl
{
5022 AADereferenceableFloating(const IRPosition
&IRP
, Attributor
&A
)
5023 : AADereferenceableImpl(IRP
, A
) {}
5025 /// See AbstractAttribute::updateImpl(...).
5026 ChangeStatus
updateImpl(Attributor
&A
) override
{
5028 bool UsedAssumedInformation
= false;
5029 SmallVector
<AA::ValueAndContext
> Values
;
5030 if (!A
.getAssumedSimplifiedValues(getIRPosition(), *this, Values
,
5031 AA::AnyScope
, UsedAssumedInformation
)) {
5032 Values
.push_back({getAssociatedValue(), getCtxI()});
5035 Stripped
= Values
.size() != 1 ||
5036 Values
.front().getValue() != &getAssociatedValue();
5039 const DataLayout
&DL
= A
.getDataLayout();
5042 auto VisitValueCB
= [&](const Value
&V
) -> bool {
5044 DL
.getIndexSizeInBits(V
.getType()->getPointerAddressSpace());
5045 APInt
Offset(IdxWidth
, 0);
5046 const Value
*Base
= stripAndAccumulateOffsets(
5047 A
, *this, &V
, DL
, Offset
, /* GetMinOffset */ false,
5048 /* AllowNonInbounds */ true);
5050 const auto *AA
= A
.getAAFor
<AADereferenceable
>(
5051 *this, IRPosition::value(*Base
), DepClassTy::REQUIRED
);
5052 int64_t DerefBytes
= 0;
5053 if (!AA
|| (!Stripped
&& this == AA
)) {
5054 // Use IR information if we did not strip anything.
5055 // TODO: track globally.
5056 bool CanBeNull
, CanBeFreed
;
5058 Base
->getPointerDereferenceableBytes(DL
, CanBeNull
, CanBeFreed
);
5059 T
.GlobalState
.indicatePessimisticFixpoint();
5061 const DerefState
&DS
= AA
->getState();
5062 DerefBytes
= DS
.DerefBytesState
.getAssumed();
5063 T
.GlobalState
&= DS
.GlobalState
;
5066 // For now we do not try to "increase" dereferenceability due to negative
5067 // indices as we first have to come up with code to deal with loops and
5068 // for overflows of the dereferenceable bytes.
5069 int64_t OffsetSExt
= Offset
.getSExtValue();
5073 T
.takeAssumedDerefBytesMinimum(
5074 std::max(int64_t(0), DerefBytes
- OffsetSExt
));
5078 // If nothing was stripped IR information is all we got.
5079 T
.takeKnownDerefBytesMaximum(
5080 std::max(int64_t(0), DerefBytes
- OffsetSExt
));
5081 T
.indicatePessimisticFixpoint();
5082 } else if (OffsetSExt
> 0) {
5083 // If something was stripped but there is circular reasoning we look
5084 // for the offset. If it is positive we basically decrease the
5085 // dereferenceable bytes in a circular loop now, which will simply
5086 // drive them down to the known value in a very slow way which we
5088 T
.indicatePessimisticFixpoint();
5092 return T
.isValidState();
5095 for (const auto &VAC
: Values
)
5096 if (!VisitValueCB(*VAC
.getValue()))
5097 return indicatePessimisticFixpoint();
5099 return clampStateAndIndicateChange(getState(), T
);
5102 /// See AbstractAttribute::trackStatistics()
5103 void trackStatistics() const override
{
5104 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable
)
5108 /// Dereferenceable attribute for a return value.
5109 struct AADereferenceableReturned final
5110 : AAReturnedFromReturnedValues
<AADereferenceable
, AADereferenceableImpl
> {
5112 AAReturnedFromReturnedValues
<AADereferenceable
, AADereferenceableImpl
>;
5113 AADereferenceableReturned(const IRPosition
&IRP
, Attributor
&A
)
5116 /// See AbstractAttribute::trackStatistics()
5117 void trackStatistics() const override
{
5118 STATS_DECLTRACK_FNRET_ATTR(dereferenceable
)
5122 /// Dereferenceable attribute for an argument
5123 struct AADereferenceableArgument final
5124 : AAArgumentFromCallSiteArguments
<AADereferenceable
,
5125 AADereferenceableImpl
> {
5127 AAArgumentFromCallSiteArguments
<AADereferenceable
, AADereferenceableImpl
>;
5128 AADereferenceableArgument(const IRPosition
&IRP
, Attributor
&A
)
5131 /// See AbstractAttribute::trackStatistics()
5132 void trackStatistics() const override
{
5133 STATS_DECLTRACK_ARG_ATTR(dereferenceable
)
5137 /// Dereferenceable attribute for a call site argument.
5138 struct AADereferenceableCallSiteArgument final
: AADereferenceableFloating
{
5139 AADereferenceableCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
5140 : AADereferenceableFloating(IRP
, A
) {}
5142 /// See AbstractAttribute::trackStatistics()
5143 void trackStatistics() const override
{
5144 STATS_DECLTRACK_CSARG_ATTR(dereferenceable
)
5148 /// Dereferenceable attribute deduction for a call site return value.
5149 struct AADereferenceableCallSiteReturned final
5150 : AACalleeToCallSite
<AADereferenceable
, AADereferenceableImpl
> {
5151 using Base
= AACalleeToCallSite
<AADereferenceable
, AADereferenceableImpl
>;
5152 AADereferenceableCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
5155 /// See AbstractAttribute::trackStatistics()
5156 void trackStatistics() const override
{
5157 STATS_DECLTRACK_CS_ATTR(dereferenceable
);
5162 // ------------------------ Align Argument Attribute ------------------------
5165 static unsigned getKnownAlignForUse(Attributor
&A
, AAAlign
&QueryingAA
,
5166 Value
&AssociatedValue
, const Use
*U
,
5167 const Instruction
*I
, bool &TrackUse
) {
5168 // We need to follow common pointer manipulation uses to the accesses they
5170 if (isa
<CastInst
>(I
)) {
5171 // Follow all but ptr2int casts.
5172 TrackUse
= !isa
<PtrToIntInst
>(I
);
5175 if (auto *GEP
= dyn_cast
<GetElementPtrInst
>(I
)) {
5176 if (GEP
->hasAllConstantIndices())
5182 if (const auto *CB
= dyn_cast
<CallBase
>(I
)) {
5183 if (CB
->isBundleOperand(U
) || CB
->isCallee(U
))
5186 unsigned ArgNo
= CB
->getArgOperandNo(U
);
5187 IRPosition IRP
= IRPosition::callsite_argument(*CB
, ArgNo
);
5188 // As long as we only use known information there is no need to track
5189 // dependences here.
5190 auto *AlignAA
= A
.getAAFor
<AAAlign
>(QueryingAA
, IRP
, DepClassTy::NONE
);
5192 MA
= MaybeAlign(AlignAA
->getKnownAlign());
5195 const DataLayout
&DL
= A
.getDataLayout();
5196 const Value
*UseV
= U
->get();
5197 if (auto *SI
= dyn_cast
<StoreInst
>(I
)) {
5198 if (SI
->getPointerOperand() == UseV
)
5199 MA
= SI
->getAlign();
5200 } else if (auto *LI
= dyn_cast
<LoadInst
>(I
)) {
5201 if (LI
->getPointerOperand() == UseV
)
5202 MA
= LI
->getAlign();
5205 if (!MA
|| *MA
<= QueryingAA
.getKnownAlign())
5208 unsigned Alignment
= MA
->value();
5211 if (const Value
*Base
= GetPointerBaseWithConstantOffset(UseV
, Offset
, DL
)) {
5212 if (Base
== &AssociatedValue
) {
5213 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5214 // So we can say that the maximum power of two which is a divisor of
5215 // gcd(Offset, Alignment) is an alignment.
5217 uint32_t gcd
= std::gcd(uint32_t(abs((int32_t)Offset
)), Alignment
);
5218 Alignment
= llvm::bit_floor(gcd
);
5225 struct AAAlignImpl
: AAAlign
{
5226 AAAlignImpl(const IRPosition
&IRP
, Attributor
&A
) : AAAlign(IRP
, A
) {}
5228 /// See AbstractAttribute::initialize(...).
5229 void initialize(Attributor
&A
) override
{
5230 SmallVector
<Attribute
, 4> Attrs
;
5231 A
.getAttrs(getIRPosition(), {Attribute::Alignment
}, Attrs
);
5232 for (const Attribute
&Attr
: Attrs
)
5233 takeKnownMaximum(Attr
.getValueAsInt());
5235 Value
&V
= *getAssociatedValue().stripPointerCasts();
5236 takeKnownMaximum(V
.getPointerAlignment(A
.getDataLayout()).value());
5238 if (Instruction
*CtxI
= getCtxI())
5239 followUsesInMBEC(*this, A
, getState(), *CtxI
);
5242 /// See AbstractAttribute::manifest(...).
5243 ChangeStatus
manifest(Attributor
&A
) override
{
5244 ChangeStatus LoadStoreChanged
= ChangeStatus::UNCHANGED
;
5246 // Check for users that allow alignment annotations.
5247 Value
&AssociatedValue
= getAssociatedValue();
5248 for (const Use
&U
: AssociatedValue
.uses()) {
5249 if (auto *SI
= dyn_cast
<StoreInst
>(U
.getUser())) {
5250 if (SI
->getPointerOperand() == &AssociatedValue
)
5251 if (SI
->getAlign() < getAssumedAlign()) {
5252 STATS_DECLTRACK(AAAlign
, Store
,
5253 "Number of times alignment added to a store");
5254 SI
->setAlignment(getAssumedAlign());
5255 LoadStoreChanged
= ChangeStatus::CHANGED
;
5257 } else if (auto *LI
= dyn_cast
<LoadInst
>(U
.getUser())) {
5258 if (LI
->getPointerOperand() == &AssociatedValue
)
5259 if (LI
->getAlign() < getAssumedAlign()) {
5260 LI
->setAlignment(getAssumedAlign());
5261 STATS_DECLTRACK(AAAlign
, Load
,
5262 "Number of times alignment added to a load");
5263 LoadStoreChanged
= ChangeStatus::CHANGED
;
5268 ChangeStatus Changed
= AAAlign::manifest(A
);
5270 Align InheritAlign
=
5271 getAssociatedValue().getPointerAlignment(A
.getDataLayout());
5272 if (InheritAlign
>= getAssumedAlign())
5273 return LoadStoreChanged
;
5274 return Changed
| LoadStoreChanged
;
5277 // TODO: Provide a helper to determine the implied ABI alignment and check in
5278 // the existing manifest method and a new one for AAAlignImpl that value
5279 // to avoid making the alignment explicit if it did not improve.
5281 /// See AbstractAttribute::getDeducedAttributes
5282 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
5283 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
5284 if (getAssumedAlign() > 1)
5286 Attribute::getWithAlignment(Ctx
, Align(getAssumedAlign())));
5289 /// See followUsesInMBEC
5290 bool followUseInMBEC(Attributor
&A
, const Use
*U
, const Instruction
*I
,
5291 AAAlign::StateType
&State
) {
5292 bool TrackUse
= false;
5294 unsigned int KnownAlign
=
5295 getKnownAlignForUse(A
, *this, getAssociatedValue(), U
, I
, TrackUse
);
5296 State
.takeKnownMaximum(KnownAlign
);
5301 /// See AbstractAttribute::getAsStr().
5302 const std::string
getAsStr(Attributor
*A
) const override
{
5303 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5304 std::to_string(getAssumedAlign().value()) + ">";
5308 /// Align attribute for a floating value.
5309 struct AAAlignFloating
: AAAlignImpl
{
5310 AAAlignFloating(const IRPosition
&IRP
, Attributor
&A
) : AAAlignImpl(IRP
, A
) {}
5312 /// See AbstractAttribute::updateImpl(...).
5313 ChangeStatus
updateImpl(Attributor
&A
) override
{
5314 const DataLayout
&DL
= A
.getDataLayout();
5317 bool UsedAssumedInformation
= false;
5318 SmallVector
<AA::ValueAndContext
> Values
;
5319 if (!A
.getAssumedSimplifiedValues(getIRPosition(), *this, Values
,
5320 AA::AnyScope
, UsedAssumedInformation
)) {
5321 Values
.push_back({getAssociatedValue(), getCtxI()});
5324 Stripped
= Values
.size() != 1 ||
5325 Values
.front().getValue() != &getAssociatedValue();
5329 auto VisitValueCB
= [&](Value
&V
) -> bool {
5330 if (isa
<UndefValue
>(V
) || isa
<ConstantPointerNull
>(V
))
5332 const auto *AA
= A
.getAAFor
<AAAlign
>(*this, IRPosition::value(V
),
5333 DepClassTy::REQUIRED
);
5334 if (!AA
|| (!Stripped
&& this == AA
)) {
5336 unsigned Alignment
= 1;
5337 if (const Value
*Base
=
5338 GetPointerBaseWithConstantOffset(&V
, Offset
, DL
)) {
5339 // TODO: Use AAAlign for the base too.
5340 Align PA
= Base
->getPointerAlignment(DL
);
5341 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5342 // So we can say that the maximum power of two which is a divisor of
5343 // gcd(Offset, Alignment) is an alignment.
5346 std::gcd(uint32_t(abs((int32_t)Offset
)), uint32_t(PA
.value()));
5347 Alignment
= llvm::bit_floor(gcd
);
5349 Alignment
= V
.getPointerAlignment(DL
).value();
5351 // Use only IR information if we did not strip anything.
5352 T
.takeKnownMaximum(Alignment
);
5353 T
.indicatePessimisticFixpoint();
5355 // Use abstract attribute information.
5356 const AAAlign::StateType
&DS
= AA
->getState();
5359 return T
.isValidState();
5362 for (const auto &VAC
: Values
) {
5363 if (!VisitValueCB(*VAC
.getValue()))
5364 return indicatePessimisticFixpoint();
5367 // TODO: If we know we visited all incoming values, thus no are assumed
5368 // dead, we can take the known information from the state T.
5369 return clampStateAndIndicateChange(getState(), T
);
5372 /// See AbstractAttribute::trackStatistics()
5373 void trackStatistics() const override
{ STATS_DECLTRACK_FLOATING_ATTR(align
) }
5376 /// Align attribute for function return value.
5377 struct AAAlignReturned final
5378 : AAReturnedFromReturnedValues
<AAAlign
, AAAlignImpl
> {
5379 using Base
= AAReturnedFromReturnedValues
<AAAlign
, AAAlignImpl
>;
5380 AAAlignReturned(const IRPosition
&IRP
, Attributor
&A
) : Base(IRP
, A
) {}
5382 /// See AbstractAttribute::trackStatistics()
5383 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(aligned
) }
5386 /// Align attribute for function argument.
5387 struct AAAlignArgument final
5388 : AAArgumentFromCallSiteArguments
<AAAlign
, AAAlignImpl
> {
5389 using Base
= AAArgumentFromCallSiteArguments
<AAAlign
, AAAlignImpl
>;
5390 AAAlignArgument(const IRPosition
&IRP
, Attributor
&A
) : Base(IRP
, A
) {}
5392 /// See AbstractAttribute::manifest(...).
5393 ChangeStatus
manifest(Attributor
&A
) override
{
5394 // If the associated argument is involved in a must-tail call we give up
5395 // because we would need to keep the argument alignments of caller and
5396 // callee in-sync. Just does not seem worth the trouble right now.
5397 if (A
.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5398 return ChangeStatus::UNCHANGED
;
5399 return Base::manifest(A
);
5402 /// See AbstractAttribute::trackStatistics()
5403 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(aligned
) }
5406 struct AAAlignCallSiteArgument final
: AAAlignFloating
{
5407 AAAlignCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
5408 : AAAlignFloating(IRP
, A
) {}
5410 /// See AbstractAttribute::manifest(...).
5411 ChangeStatus
manifest(Attributor
&A
) override
{
5412 // If the associated argument is involved in a must-tail call we give up
5413 // because we would need to keep the argument alignments of caller and
5414 // callee in-sync. Just does not seem worth the trouble right now.
5415 if (Argument
*Arg
= getAssociatedArgument())
5416 if (A
.getInfoCache().isInvolvedInMustTailCall(*Arg
))
5417 return ChangeStatus::UNCHANGED
;
5418 ChangeStatus Changed
= AAAlignImpl::manifest(A
);
5419 Align InheritAlign
=
5420 getAssociatedValue().getPointerAlignment(A
.getDataLayout());
5421 if (InheritAlign
>= getAssumedAlign())
5422 Changed
= ChangeStatus::UNCHANGED
;
5426 /// See AbstractAttribute::updateImpl(Attributor &A).
5427 ChangeStatus
updateImpl(Attributor
&A
) override
{
5428 ChangeStatus Changed
= AAAlignFloating::updateImpl(A
);
5429 if (Argument
*Arg
= getAssociatedArgument()) {
5430 // We only take known information from the argument
5431 // so we do not need to track a dependence.
5432 const auto *ArgAlignAA
= A
.getAAFor
<AAAlign
>(
5433 *this, IRPosition::argument(*Arg
), DepClassTy::NONE
);
5435 takeKnownMaximum(ArgAlignAA
->getKnownAlign().value());
5440 /// See AbstractAttribute::trackStatistics()
5441 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(aligned
) }
5444 /// Align attribute deduction for a call site return value.
5445 struct AAAlignCallSiteReturned final
5446 : AACalleeToCallSite
<AAAlign
, AAAlignImpl
> {
5447 using Base
= AACalleeToCallSite
<AAAlign
, AAAlignImpl
>;
5448 AAAlignCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
5451 /// See AbstractAttribute::trackStatistics()
5452 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(align
); }
5456 /// ------------------ Function No-Return Attribute ----------------------------
5458 struct AANoReturnImpl
: public AANoReturn
{
5459 AANoReturnImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoReturn(IRP
, A
) {}
5461 /// See AbstractAttribute::initialize(...).
5462 void initialize(Attributor
&A
) override
{
5464 assert(!AA::hasAssumedIRAttr
<Attribute::NoReturn
>(
5465 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
5469 /// See AbstractAttribute::getAsStr().
5470 const std::string
getAsStr(Attributor
*A
) const override
{
5471 return getAssumed() ? "noreturn" : "may-return";
5474 /// See AbstractAttribute::updateImpl(Attributor &A).
5475 ChangeStatus
updateImpl(Attributor
&A
) override
{
5476 auto CheckForNoReturn
= [](Instruction
&) { return false; };
5477 bool UsedAssumedInformation
= false;
5478 if (!A
.checkForAllInstructions(CheckForNoReturn
, *this,
5479 {(unsigned)Instruction::Ret
},
5480 UsedAssumedInformation
))
5481 return indicatePessimisticFixpoint();
5482 return ChangeStatus::UNCHANGED
;
5486 struct AANoReturnFunction final
: AANoReturnImpl
{
5487 AANoReturnFunction(const IRPosition
&IRP
, Attributor
&A
)
5488 : AANoReturnImpl(IRP
, A
) {}
5490 /// See AbstractAttribute::trackStatistics()
5491 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(noreturn
) }
5494 /// NoReturn attribute deduction for a call sites.
5495 struct AANoReturnCallSite final
5496 : AACalleeToCallSite
<AANoReturn
, AANoReturnImpl
> {
5497 AANoReturnCallSite(const IRPosition
&IRP
, Attributor
&A
)
5498 : AACalleeToCallSite
<AANoReturn
, AANoReturnImpl
>(IRP
, A
) {}
5500 /// See AbstractAttribute::trackStatistics()
5501 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(noreturn
); }
5505 /// ----------------------- Instance Info ---------------------------------
5508 /// A class to hold the state of for no-capture attributes.
5509 struct AAInstanceInfoImpl
: public AAInstanceInfo
{
5510 AAInstanceInfoImpl(const IRPosition
&IRP
, Attributor
&A
)
5511 : AAInstanceInfo(IRP
, A
) {}
5513 /// See AbstractAttribute::initialize(...).
5514 void initialize(Attributor
&A
) override
{
5515 Value
&V
= getAssociatedValue();
5516 if (auto *C
= dyn_cast
<Constant
>(&V
)) {
5517 if (C
->isThreadDependent())
5518 indicatePessimisticFixpoint();
5520 indicateOptimisticFixpoint();
5523 if (auto *CB
= dyn_cast
<CallBase
>(&V
))
5524 if (CB
->arg_size() == 0 && !CB
->mayHaveSideEffects() &&
5525 !CB
->mayReadFromMemory()) {
5526 indicateOptimisticFixpoint();
5529 if (auto *I
= dyn_cast
<Instruction
>(&V
)) {
5531 A
.getInfoCache().getAnalysisResultForFunction
<CycleAnalysis
>(
5533 if (mayBeInCycle(CI
, I
, /* HeaderOnly */ false)) {
5534 indicatePessimisticFixpoint();
5540 /// See AbstractAttribute::updateImpl(...).
5541 ChangeStatus
updateImpl(Attributor
&A
) override
{
5542 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
5544 Value
&V
= getAssociatedValue();
5545 const Function
*Scope
= nullptr;
5546 if (auto *I
= dyn_cast
<Instruction
>(&V
))
5547 Scope
= I
->getFunction();
5548 if (auto *A
= dyn_cast
<Argument
>(&V
)) {
5549 Scope
= A
->getParent();
5550 if (!Scope
->hasLocalLinkage())
5554 return indicateOptimisticFixpoint();
5556 bool IsKnownNoRecurse
;
5557 if (AA::hasAssumedIRAttr
<Attribute::NoRecurse
>(
5558 A
, this, IRPosition::function(*Scope
), DepClassTy::OPTIONAL
,
5562 auto UsePred
= [&](const Use
&U
, bool &Follow
) {
5563 const Instruction
*UserI
= dyn_cast
<Instruction
>(U
.getUser());
5564 if (!UserI
|| isa
<GetElementPtrInst
>(UserI
) || isa
<CastInst
>(UserI
) ||
5565 isa
<PHINode
>(UserI
) || isa
<SelectInst
>(UserI
)) {
5569 if (isa
<LoadInst
>(UserI
) || isa
<CmpInst
>(UserI
) ||
5570 (isa
<StoreInst
>(UserI
) &&
5571 cast
<StoreInst
>(UserI
)->getValueOperand() != U
.get()))
5573 if (auto *CB
= dyn_cast
<CallBase
>(UserI
)) {
5574 // This check is not guaranteeing uniqueness but for now that we cannot
5575 // end up with two versions of \p U thinking it was one.
5576 auto *Callee
= dyn_cast_if_present
<Function
>(CB
->getCalledOperand());
5577 if (!Callee
|| !Callee
->hasLocalLinkage())
5579 if (!CB
->isArgOperand(&U
))
5581 const auto *ArgInstanceInfoAA
= A
.getAAFor
<AAInstanceInfo
>(
5582 *this, IRPosition::callsite_argument(*CB
, CB
->getArgOperandNo(&U
)),
5583 DepClassTy::OPTIONAL
);
5584 if (!ArgInstanceInfoAA
||
5585 !ArgInstanceInfoAA
->isAssumedUniqueForAnalysis())
5587 // If this call base might reach the scope again we might forward the
5588 // argument back here. This is very conservative.
5589 if (AA::isPotentiallyReachable(
5590 A
, *CB
, *Scope
, *this, /* ExclusionSet */ nullptr,
5591 [Scope
](const Function
&Fn
) { return &Fn
!= Scope
; }))
5598 auto EquivalentUseCB
= [&](const Use
&OldU
, const Use
&NewU
) {
5599 if (auto *SI
= dyn_cast
<StoreInst
>(OldU
.getUser())) {
5600 auto *Ptr
= SI
->getPointerOperand()->stripPointerCasts();
5601 if ((isa
<AllocaInst
>(Ptr
) || isNoAliasCall(Ptr
)) &&
5602 AA::isDynamicallyUnique(A
, *this, *Ptr
))
5608 if (!A
.checkForAllUses(UsePred
, *this, V
, /* CheckBBLivenessOnly */ true,
5609 DepClassTy::OPTIONAL
,
5610 /* IgnoreDroppableUses */ true, EquivalentUseCB
))
5611 return indicatePessimisticFixpoint();
5616 /// See AbstractState::getAsStr().
5617 const std::string
getAsStr(Attributor
*A
) const override
{
5618 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5621 /// See AbstractAttribute::trackStatistics()
5622 void trackStatistics() const override
{}
5625 /// InstanceInfo attribute for floating values.
5626 struct AAInstanceInfoFloating
: AAInstanceInfoImpl
{
5627 AAInstanceInfoFloating(const IRPosition
&IRP
, Attributor
&A
)
5628 : AAInstanceInfoImpl(IRP
, A
) {}
5631 /// NoCapture attribute for function arguments.
5632 struct AAInstanceInfoArgument final
: AAInstanceInfoFloating
{
5633 AAInstanceInfoArgument(const IRPosition
&IRP
, Attributor
&A
)
5634 : AAInstanceInfoFloating(IRP
, A
) {}
5637 /// InstanceInfo attribute for call site arguments.
5638 struct AAInstanceInfoCallSiteArgument final
: AAInstanceInfoImpl
{
5639 AAInstanceInfoCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
5640 : AAInstanceInfoImpl(IRP
, A
) {}
5642 /// See AbstractAttribute::updateImpl(...).
5643 ChangeStatus
updateImpl(Attributor
&A
) override
{
5644 // TODO: Once we have call site specific value information we can provide
5645 // call site specific liveness information and then it makes
5646 // sense to specialize attributes for call sites arguments instead of
5647 // redirecting requests to the callee argument.
5648 Argument
*Arg
= getAssociatedArgument();
5650 return indicatePessimisticFixpoint();
5651 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
5653 A
.getAAFor
<AAInstanceInfo
>(*this, ArgPos
, DepClassTy::REQUIRED
);
5655 return indicatePessimisticFixpoint();
5656 return clampStateAndIndicateChange(getState(), ArgAA
->getState());
5660 /// InstanceInfo attribute for function return value.
5661 struct AAInstanceInfoReturned final
: AAInstanceInfoImpl
{
5662 AAInstanceInfoReturned(const IRPosition
&IRP
, Attributor
&A
)
5663 : AAInstanceInfoImpl(IRP
, A
) {
5664 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5667 /// See AbstractAttribute::initialize(...).
5668 void initialize(Attributor
&A
) override
{
5669 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5672 /// See AbstractAttribute::updateImpl(...).
5673 ChangeStatus
updateImpl(Attributor
&A
) override
{
5674 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5678 /// InstanceInfo attribute deduction for a call site return value.
5679 struct AAInstanceInfoCallSiteReturned final
: AAInstanceInfoFloating
{
5680 AAInstanceInfoCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
5681 : AAInstanceInfoFloating(IRP
, A
) {}
5685 /// ----------------------- Variable Capturing ---------------------------------
5686 bool AANoCapture::isImpliedByIR(Attributor
&A
, const IRPosition
&IRP
,
5687 Attribute::AttrKind ImpliedAttributeKind
,
5688 bool IgnoreSubsumingPositions
) {
5689 assert(ImpliedAttributeKind
== Attribute::NoCapture
&&
5690 "Unexpected attribute kind");
5691 Value
&V
= IRP
.getAssociatedValue();
5692 if (!IRP
.isArgumentPosition())
5693 return V
.use_empty();
5695 // You cannot "capture" null in the default address space.
5696 if (isa
<UndefValue
>(V
) || (isa
<ConstantPointerNull
>(V
) &&
5697 V
.getType()->getPointerAddressSpace() == 0)) {
5701 if (A
.hasAttr(IRP
, {Attribute::NoCapture
},
5702 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture
))
5705 if (IRP
.getPositionKind() == IRP_CALL_SITE_ARGUMENT
)
5706 if (Argument
*Arg
= IRP
.getAssociatedArgument())
5707 if (A
.hasAttr(IRPosition::argument(*Arg
),
5708 {Attribute::NoCapture
, Attribute::ByVal
},
5709 /* IgnoreSubsumingPositions */ true)) {
5710 A
.manifestAttrs(IRP
,
5711 Attribute::get(V
.getContext(), Attribute::NoCapture
));
5715 if (const Function
*F
= IRP
.getAssociatedFunction()) {
5716 // Check what state the associated function can actually capture.
5717 AANoCapture::StateType State
;
5718 determineFunctionCaptureCapabilities(IRP
, *F
, State
);
5719 if (State
.isKnown(NO_CAPTURE
)) {
5720 A
.manifestAttrs(IRP
,
5721 Attribute::get(V
.getContext(), Attribute::NoCapture
));
5729 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5730 /// depending on the ability of the function associated with \p IRP to capture
5731 /// state in memory and through "returning/throwing", respectively.
5732 void AANoCapture::determineFunctionCaptureCapabilities(const IRPosition
&IRP
,
5734 BitIntegerState
&State
) {
5735 // TODO: Once we have memory behavior attributes we should use them here.
5737 // If we know we cannot communicate or write to memory, we do not care about
5739 bool ReadOnly
= F
.onlyReadsMemory();
5740 bool NoThrow
= F
.doesNotThrow();
5741 bool IsVoidReturn
= F
.getReturnType()->isVoidTy();
5742 if (ReadOnly
&& NoThrow
&& IsVoidReturn
) {
5743 State
.addKnownBits(NO_CAPTURE
);
5747 // A function cannot capture state in memory if it only reads memory, it can
5748 // however return/throw state and the state might be influenced by the
5749 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5751 State
.addKnownBits(NOT_CAPTURED_IN_MEM
);
5753 // A function cannot communicate state back if it does not through
5754 // exceptions and doesn not return values.
5755 if (NoThrow
&& IsVoidReturn
)
5756 State
.addKnownBits(NOT_CAPTURED_IN_RET
);
5758 // Check existing "returned" attributes.
5759 int ArgNo
= IRP
.getCalleeArgNo();
5760 if (!NoThrow
|| ArgNo
< 0 ||
5761 !F
.getAttributes().hasAttrSomewhere(Attribute::Returned
))
5764 for (unsigned U
= 0, E
= F
.arg_size(); U
< E
; ++U
)
5765 if (F
.hasParamAttribute(U
, Attribute::Returned
)) {
5766 if (U
== unsigned(ArgNo
))
5767 State
.removeAssumedBits(NOT_CAPTURED_IN_RET
);
5769 State
.addKnownBits(NO_CAPTURE
);
5771 State
.addKnownBits(NOT_CAPTURED_IN_RET
);
5777 /// A class to hold the state of for no-capture attributes.
5778 struct AANoCaptureImpl
: public AANoCapture
{
5779 AANoCaptureImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoCapture(IRP
, A
) {}
5781 /// See AbstractAttribute::initialize(...).
5782 void initialize(Attributor
&A
) override
{
5784 assert(!AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
5785 A
, nullptr, getIRPosition(), DepClassTy::NONE
, IsKnown
));
5789 /// See AbstractAttribute::updateImpl(...).
5790 ChangeStatus
updateImpl(Attributor
&A
) override
;
5792 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5793 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
5794 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
5795 if (!isAssumedNoCaptureMaybeReturned())
5798 if (isArgumentPosition()) {
5799 if (isAssumedNoCapture())
5800 Attrs
.emplace_back(Attribute::get(Ctx
, Attribute::NoCapture
));
5801 else if (ManifestInternal
)
5802 Attrs
.emplace_back(Attribute::get(Ctx
, "no-capture-maybe-returned"));
5806 /// See AbstractState::getAsStr().
5807 const std::string
getAsStr(Attributor
*A
) const override
{
5808 if (isKnownNoCapture())
5809 return "known not-captured";
5810 if (isAssumedNoCapture())
5811 return "assumed not-captured";
5812 if (isKnownNoCaptureMaybeReturned())
5813 return "known not-captured-maybe-returned";
5814 if (isAssumedNoCaptureMaybeReturned())
5815 return "assumed not-captured-maybe-returned";
5816 return "assumed-captured";
5819 /// Check the use \p U and update \p State accordingly. Return true if we
5820 /// should continue to update the state.
5821 bool checkUse(Attributor
&A
, AANoCapture::StateType
&State
, const Use
&U
,
5823 Instruction
*UInst
= cast
<Instruction
>(U
.getUser());
5824 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U
.get() << " in "
5827 // Deal with ptr2int by following uses.
5828 if (isa
<PtrToIntInst
>(UInst
)) {
5829 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5830 return isCapturedIn(State
, /* Memory */ true, /* Integer */ true,
5834 // For stores we already checked if we can follow them, if they make it
5836 if (isa
<StoreInst
>(UInst
))
5837 return isCapturedIn(State
, /* Memory */ true, /* Integer */ true,
5840 // Explicitly catch return instructions.
5841 if (isa
<ReturnInst
>(UInst
)) {
5842 if (UInst
->getFunction() == getAnchorScope())
5843 return isCapturedIn(State
, /* Memory */ false, /* Integer */ false,
5845 return isCapturedIn(State
, /* Memory */ true, /* Integer */ true,
5849 // For now we only use special logic for call sites. However, the tracker
5850 // itself knows about a lot of other non-capturing cases already.
5851 auto *CB
= dyn_cast
<CallBase
>(UInst
);
5852 if (!CB
|| !CB
->isArgOperand(&U
))
5853 return isCapturedIn(State
, /* Memory */ true, /* Integer */ true,
5856 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
5857 const IRPosition
&CSArgPos
= IRPosition::callsite_argument(*CB
, ArgNo
);
5858 // If we have a abstract no-capture attribute for the argument we can use
5859 // it to justify a non-capture attribute here. This allows recursion!
5860 bool IsKnownNoCapture
;
5861 const AANoCapture
*ArgNoCaptureAA
= nullptr;
5862 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
5863 A
, this, CSArgPos
, DepClassTy::REQUIRED
, IsKnownNoCapture
, false,
5865 if (IsAssumedNoCapture
)
5866 return isCapturedIn(State
, /* Memory */ false, /* Integer */ false,
5867 /* Return */ false);
5868 if (ArgNoCaptureAA
&& ArgNoCaptureAA
->isAssumedNoCaptureMaybeReturned()) {
5870 return isCapturedIn(State
, /* Memory */ false, /* Integer */ false,
5871 /* Return */ false);
5874 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5875 return isCapturedIn(State
, /* Memory */ true, /* Integer */ true,
5879 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5880 /// \p CapturedInRet, then return true if we should continue updating the
5882 static bool isCapturedIn(AANoCapture::StateType
&State
, bool CapturedInMem
,
5883 bool CapturedInInt
, bool CapturedInRet
) {
5884 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem
<< "|Int "
5885 << CapturedInInt
<< "|Ret " << CapturedInRet
<< "]\n");
5887 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM
);
5889 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT
);
5891 State
.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET
);
5892 return State
.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED
);
5896 ChangeStatus
AANoCaptureImpl::updateImpl(Attributor
&A
) {
5897 const IRPosition
&IRP
= getIRPosition();
5898 Value
*V
= isArgumentPosition() ? IRP
.getAssociatedArgument()
5899 : &IRP
.getAssociatedValue();
5901 return indicatePessimisticFixpoint();
5904 isArgumentPosition() ? IRP
.getAssociatedFunction() : IRP
.getAnchorScope();
5905 assert(F
&& "Expected a function!");
5906 const IRPosition
&FnPos
= IRPosition::function(*F
);
5908 AANoCapture::StateType T
;
5910 // Readonly means we cannot capture through memory.
5912 if (AA::isAssumedReadOnly(A
, FnPos
, *this, IsKnown
)) {
5913 T
.addKnownBits(NOT_CAPTURED_IN_MEM
);
5915 addKnownBits(NOT_CAPTURED_IN_MEM
);
5918 // Make sure all returned values are different than the underlying value.
5919 // TODO: we could do this in a more sophisticated way inside
5920 // AAReturnedValues, e.g., track all values that escape through returns
5921 // directly somehow.
5922 auto CheckReturnedArgs
= [&](bool &UsedAssumedInformation
) {
5923 SmallVector
<AA::ValueAndContext
> Values
;
5924 if (!A
.getAssumedSimplifiedValues(IRPosition::returned(*F
), this, Values
,
5925 AA::ValueScope::Intraprocedural
,
5926 UsedAssumedInformation
))
5928 bool SeenConstant
= false;
5929 for (const AA::ValueAndContext
&VAC
: Values
) {
5930 if (isa
<Constant
>(VAC
.getValue())) {
5933 SeenConstant
= true;
5934 } else if (!isa
<Argument
>(VAC
.getValue()) ||
5935 VAC
.getValue() == getAssociatedArgument())
5941 bool IsKnownNoUnwind
;
5942 if (AA::hasAssumedIRAttr
<Attribute::NoUnwind
>(
5943 A
, this, FnPos
, DepClassTy::OPTIONAL
, IsKnownNoUnwind
)) {
5944 bool IsVoidTy
= F
->getReturnType()->isVoidTy();
5945 bool UsedAssumedInformation
= false;
5946 if (IsVoidTy
|| CheckReturnedArgs(UsedAssumedInformation
)) {
5947 T
.addKnownBits(NOT_CAPTURED_IN_RET
);
5948 if (T
.isKnown(NOT_CAPTURED_IN_MEM
))
5949 return ChangeStatus::UNCHANGED
;
5950 if (IsKnownNoUnwind
&& (IsVoidTy
|| !UsedAssumedInformation
)) {
5951 addKnownBits(NOT_CAPTURED_IN_RET
);
5952 if (isKnown(NOT_CAPTURED_IN_MEM
))
5953 return indicateOptimisticFixpoint();
5958 auto IsDereferenceableOrNull
= [&](Value
*O
, const DataLayout
&DL
) {
5959 const auto *DerefAA
= A
.getAAFor
<AADereferenceable
>(
5960 *this, IRPosition::value(*O
), DepClassTy::OPTIONAL
);
5961 return DerefAA
&& DerefAA
->getAssumedDereferenceableBytes();
5964 auto UseCheck
= [&](const Use
&U
, bool &Follow
) -> bool {
5965 switch (DetermineUseCaptureKind(U
, IsDereferenceableOrNull
)) {
5966 case UseCaptureKind::NO_CAPTURE
:
5968 case UseCaptureKind::MAY_CAPTURE
:
5969 return checkUse(A
, T
, U
, Follow
);
5970 case UseCaptureKind::PASSTHROUGH
:
5974 llvm_unreachable("Unexpected use capture kind!");
5977 if (!A
.checkForAllUses(UseCheck
, *this, *V
))
5978 return indicatePessimisticFixpoint();
5980 AANoCapture::StateType
&S
= getState();
5981 auto Assumed
= S
.getAssumed();
5982 S
.intersectAssumedBits(T
.getAssumed());
5983 if (!isAssumedNoCaptureMaybeReturned())
5984 return indicatePessimisticFixpoint();
5985 return Assumed
== S
.getAssumed() ? ChangeStatus::UNCHANGED
5986 : ChangeStatus::CHANGED
;
5989 /// NoCapture attribute for function arguments.
5990 struct AANoCaptureArgument final
: AANoCaptureImpl
{
5991 AANoCaptureArgument(const IRPosition
&IRP
, Attributor
&A
)
5992 : AANoCaptureImpl(IRP
, A
) {}
5994 /// See AbstractAttribute::trackStatistics()
5995 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nocapture
) }
5998 /// NoCapture attribute for call site arguments.
5999 struct AANoCaptureCallSiteArgument final
: AANoCaptureImpl
{
6000 AANoCaptureCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
6001 : AANoCaptureImpl(IRP
, A
) {}
6003 /// See AbstractAttribute::updateImpl(...).
6004 ChangeStatus
updateImpl(Attributor
&A
) override
{
6005 // TODO: Once we have call site specific value information we can provide
6006 // call site specific liveness information and then it makes
6007 // sense to specialize attributes for call sites arguments instead of
6008 // redirecting requests to the callee argument.
6009 Argument
*Arg
= getAssociatedArgument();
6011 return indicatePessimisticFixpoint();
6012 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
6013 bool IsKnownNoCapture
;
6014 const AANoCapture
*ArgAA
= nullptr;
6015 if (AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
6016 A
, this, ArgPos
, DepClassTy::REQUIRED
, IsKnownNoCapture
, false,
6018 return ChangeStatus::UNCHANGED
;
6019 if (!ArgAA
|| !ArgAA
->isAssumedNoCaptureMaybeReturned())
6020 return indicatePessimisticFixpoint();
6021 return clampStateAndIndicateChange(getState(), ArgAA
->getState());
6024 /// See AbstractAttribute::trackStatistics()
6025 void trackStatistics() const override
{STATS_DECLTRACK_CSARG_ATTR(nocapture
)};
6028 /// NoCapture attribute for floating values.
6029 struct AANoCaptureFloating final
: AANoCaptureImpl
{
6030 AANoCaptureFloating(const IRPosition
&IRP
, Attributor
&A
)
6031 : AANoCaptureImpl(IRP
, A
) {}
6033 /// See AbstractAttribute::trackStatistics()
6034 void trackStatistics() const override
{
6035 STATS_DECLTRACK_FLOATING_ATTR(nocapture
)
6039 /// NoCapture attribute for function return value.
6040 struct AANoCaptureReturned final
: AANoCaptureImpl
{
6041 AANoCaptureReturned(const IRPosition
&IRP
, Attributor
&A
)
6042 : AANoCaptureImpl(IRP
, A
) {
6043 llvm_unreachable("NoCapture is not applicable to function returns!");
6046 /// See AbstractAttribute::initialize(...).
6047 void initialize(Attributor
&A
) override
{
6048 llvm_unreachable("NoCapture is not applicable to function returns!");
6051 /// See AbstractAttribute::updateImpl(...).
6052 ChangeStatus
updateImpl(Attributor
&A
) override
{
6053 llvm_unreachable("NoCapture is not applicable to function returns!");
6056 /// See AbstractAttribute::trackStatistics()
6057 void trackStatistics() const override
{}
6060 /// NoCapture attribute deduction for a call site return value.
6061 struct AANoCaptureCallSiteReturned final
: AANoCaptureImpl
{
6062 AANoCaptureCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
6063 : AANoCaptureImpl(IRP
, A
) {}
6065 /// See AbstractAttribute::initialize(...).
6066 void initialize(Attributor
&A
) override
{
6067 const Function
*F
= getAnchorScope();
6068 // Check what state the associated function can actually capture.
6069 determineFunctionCaptureCapabilities(getIRPosition(), *F
, *this);
6072 /// See AbstractAttribute::trackStatistics()
6073 void trackStatistics() const override
{
6074 STATS_DECLTRACK_CSRET_ATTR(nocapture
)
6079 /// ------------------ Value Simplify Attribute ----------------------------
6081 bool ValueSimplifyStateType::unionAssumed(std::optional
<Value
*> Other
) {
6082 // FIXME: Add a typecast support.
6083 SimplifiedAssociatedValue
= AA::combineOptionalValuesInAAValueLatice(
6084 SimplifiedAssociatedValue
, Other
, Ty
);
6085 if (SimplifiedAssociatedValue
== std::optional
<Value
*>(nullptr))
6089 if (SimplifiedAssociatedValue
)
6090 dbgs() << "[ValueSimplify] is assumed to be "
6091 << **SimplifiedAssociatedValue
<< "\n";
6093 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6099 struct AAValueSimplifyImpl
: AAValueSimplify
{
6100 AAValueSimplifyImpl(const IRPosition
&IRP
, Attributor
&A
)
6101 : AAValueSimplify(IRP
, A
) {}
6103 /// See AbstractAttribute::initialize(...).
6104 void initialize(Attributor
&A
) override
{
6105 if (getAssociatedValue().getType()->isVoidTy())
6106 indicatePessimisticFixpoint();
6107 if (A
.hasSimplificationCallback(getIRPosition()))
6108 indicatePessimisticFixpoint();
6111 /// See AbstractAttribute::getAsStr().
6112 const std::string
getAsStr(Attributor
*A
) const override
{
6114 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue
<< " ";
6115 if (SimplifiedAssociatedValue
&& *SimplifiedAssociatedValue
)
6116 dbgs() << "SAV: " << **SimplifiedAssociatedValue
<< " ";
6118 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6122 /// See AbstractAttribute::trackStatistics()
6123 void trackStatistics() const override
{}
6125 /// See AAValueSimplify::getAssumedSimplifiedValue()
6126 std::optional
<Value
*>
6127 getAssumedSimplifiedValue(Attributor
&A
) const override
{
6128 return SimplifiedAssociatedValue
;
6131 /// Ensure the return value is \p V with type \p Ty, if not possible return
6132 /// nullptr. If \p Check is true we will only verify such an operation would
6133 /// suceed and return a non-nullptr value if that is the case. No IR is
6134 /// generated or modified.
6135 static Value
*ensureType(Attributor
&A
, Value
&V
, Type
&Ty
, Instruction
*CtxI
,
6137 if (auto *TypedV
= AA::getWithType(V
, Ty
))
6139 if (CtxI
&& V
.getType()->canLosslesslyBitCastTo(&Ty
))
6141 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(&V
, &Ty
,
6146 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6147 /// If \p Check is true we will only verify such an operation would suceed and
6148 /// return a non-nullptr value if that is the case. No IR is generated or
6150 static Value
*reproduceInst(Attributor
&A
,
6151 const AbstractAttribute
&QueryingAA
,
6152 Instruction
&I
, Type
&Ty
, Instruction
*CtxI
,
6153 bool Check
, ValueToValueMapTy
&VMap
) {
6154 assert(CtxI
&& "Cannot reproduce an instruction without context!");
6155 if (Check
&& (I
.mayReadFromMemory() ||
6156 !isSafeToSpeculativelyExecute(&I
, CtxI
, /* DT */ nullptr,
6157 /* TLI */ nullptr)))
6159 for (Value
*Op
: I
.operands()) {
6160 Value
*NewOp
= reproduceValue(A
, QueryingAA
, *Op
, Ty
, CtxI
, Check
, VMap
);
6162 assert(Check
&& "Manifest of new value unexpectedly failed!");
6171 Instruction
*CloneI
= I
.clone();
6172 // TODO: Try to salvage debug information here.
6173 CloneI
->setDebugLoc(DebugLoc());
6175 CloneI
->insertBefore(CtxI
);
6176 RemapInstruction(CloneI
, VMap
);
6180 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6181 /// If \p Check is true we will only verify such an operation would suceed and
6182 /// return a non-nullptr value if that is the case. No IR is generated or
6184 static Value
*reproduceValue(Attributor
&A
,
6185 const AbstractAttribute
&QueryingAA
, Value
&V
,
6186 Type
&Ty
, Instruction
*CtxI
, bool Check
,
6187 ValueToValueMapTy
&VMap
) {
6188 if (const auto &NewV
= VMap
.lookup(&V
))
6190 bool UsedAssumedInformation
= false;
6191 std::optional
<Value
*> SimpleV
= A
.getAssumedSimplified(
6192 V
, QueryingAA
, UsedAssumedInformation
, AA::Interprocedural
);
6193 if (!SimpleV
.has_value())
6194 return PoisonValue::get(&Ty
);
6195 Value
*EffectiveV
= &V
;
6197 EffectiveV
= *SimpleV
;
6198 if (auto *C
= dyn_cast
<Constant
>(EffectiveV
))
6200 if (CtxI
&& AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV
, *CtxI
),
6202 return ensureType(A
, *EffectiveV
, Ty
, CtxI
, Check
);
6203 if (auto *I
= dyn_cast
<Instruction
>(EffectiveV
))
6204 if (Value
*NewV
= reproduceInst(A
, QueryingAA
, *I
, Ty
, CtxI
, Check
, VMap
))
6205 return ensureType(A
, *NewV
, Ty
, CtxI
, Check
);
6209 /// Return a value we can use as replacement for the associated one, or
6210 /// nullptr if we don't have one that makes sense.
6211 Value
*manifestReplacementValue(Attributor
&A
, Instruction
*CtxI
) const {
6212 Value
*NewV
= SimplifiedAssociatedValue
6213 ? *SimplifiedAssociatedValue
6214 : UndefValue::get(getAssociatedType());
6215 if (NewV
&& NewV
!= &getAssociatedValue()) {
6216 ValueToValueMapTy VMap
;
6217 // First verify we can reprduce the value with the required type at the
6218 // context location before we actually start modifying the IR.
6219 if (reproduceValue(A
, *this, *NewV
, *getAssociatedType(), CtxI
,
6220 /* CheckOnly */ true, VMap
))
6221 return reproduceValue(A
, *this, *NewV
, *getAssociatedType(), CtxI
,
6222 /* CheckOnly */ false, VMap
);
6227 /// Helper function for querying AAValueSimplify and updating candidate.
6228 /// \param IRP The value position we are trying to unify with SimplifiedValue
6229 bool checkAndUpdate(Attributor
&A
, const AbstractAttribute
&QueryingAA
,
6230 const IRPosition
&IRP
, bool Simplify
= true) {
6231 bool UsedAssumedInformation
= false;
6232 std::optional
<Value
*> QueryingValueSimplified
= &IRP
.getAssociatedValue();
6234 QueryingValueSimplified
= A
.getAssumedSimplified(
6235 IRP
, QueryingAA
, UsedAssumedInformation
, AA::Interprocedural
);
6236 return unionAssumed(QueryingValueSimplified
);
6239 /// Returns a candidate is found or not
6240 template <typename AAType
> bool askSimplifiedValueFor(Attributor
&A
) {
6241 if (!getAssociatedValue().getType()->isIntegerTy())
6244 // This will also pass the call base context.
6246 A
.getAAFor
<AAType
>(*this, getIRPosition(), DepClassTy::NONE
);
6250 std::optional
<Constant
*> COpt
= AA
->getAssumedConstant(A
);
6253 SimplifiedAssociatedValue
= std::nullopt
;
6254 A
.recordDependence(*AA
, *this, DepClassTy::OPTIONAL
);
6257 if (auto *C
= *COpt
) {
6258 SimplifiedAssociatedValue
= C
;
6259 A
.recordDependence(*AA
, *this, DepClassTy::OPTIONAL
);
6265 bool askSimplifiedValueForOtherAAs(Attributor
&A
) {
6266 if (askSimplifiedValueFor
<AAValueConstantRange
>(A
))
6268 if (askSimplifiedValueFor
<AAPotentialConstantValues
>(A
))
6273 /// See AbstractAttribute::manifest(...).
6274 ChangeStatus
manifest(Attributor
&A
) override
{
6275 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
6276 for (auto &U
: getAssociatedValue().uses()) {
6277 // Check if we need to adjust the insertion point to make sure the IR is
6279 Instruction
*IP
= dyn_cast
<Instruction
>(U
.getUser());
6280 if (auto *PHI
= dyn_cast_or_null
<PHINode
>(IP
))
6281 IP
= PHI
->getIncomingBlock(U
)->getTerminator();
6282 if (auto *NewV
= manifestReplacementValue(A
, IP
)) {
6283 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6284 << " -> " << *NewV
<< " :: " << *this << "\n");
6285 if (A
.changeUseAfterManifest(U
, *NewV
))
6286 Changed
= ChangeStatus::CHANGED
;
6290 return Changed
| AAValueSimplify::manifest(A
);
6293 /// See AbstractState::indicatePessimisticFixpoint(...).
6294 ChangeStatus
indicatePessimisticFixpoint() override
{
6295 SimplifiedAssociatedValue
= &getAssociatedValue();
6296 return AAValueSimplify::indicatePessimisticFixpoint();
6300 struct AAValueSimplifyArgument final
: AAValueSimplifyImpl
{
6301 AAValueSimplifyArgument(const IRPosition
&IRP
, Attributor
&A
)
6302 : AAValueSimplifyImpl(IRP
, A
) {}
6304 void initialize(Attributor
&A
) override
{
6305 AAValueSimplifyImpl::initialize(A
);
6306 if (A
.hasAttr(getIRPosition(),
6307 {Attribute::InAlloca
, Attribute::Preallocated
,
6308 Attribute::StructRet
, Attribute::Nest
, Attribute::ByVal
},
6309 /* IgnoreSubsumingPositions */ true))
6310 indicatePessimisticFixpoint();
6313 /// See AbstractAttribute::updateImpl(...).
6314 ChangeStatus
updateImpl(Attributor
&A
) override
{
6315 // Byval is only replacable if it is readonly otherwise we would write into
6316 // the replaced value and not the copy that byval creates implicitly.
6317 Argument
*Arg
= getAssociatedArgument();
6318 if (Arg
->hasByValAttr()) {
6319 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6320 // there is no race by not copying a constant byval.
6322 if (!AA::isAssumedReadOnly(A
, getIRPosition(), *this, IsKnown
))
6323 return indicatePessimisticFixpoint();
6326 auto Before
= SimplifiedAssociatedValue
;
6328 auto PredForCallSite
= [&](AbstractCallSite ACS
) {
6329 const IRPosition
&ACSArgPos
=
6330 IRPosition::callsite_argument(ACS
, getCallSiteArgNo());
6331 // Check if a coresponding argument was found or if it is on not
6332 // associated (which can happen for callback calls).
6333 if (ACSArgPos
.getPositionKind() == IRPosition::IRP_INVALID
)
6336 // Simplify the argument operand explicitly and check if the result is
6337 // valid in the current scope. This avoids refering to simplified values
6338 // in other functions, e.g., we don't want to say a an argument in a
6339 // static function is actually an argument in a different function.
6340 bool UsedAssumedInformation
= false;
6341 std::optional
<Constant
*> SimpleArgOp
=
6342 A
.getAssumedConstant(ACSArgPos
, *this, UsedAssumedInformation
);
6347 if (!AA::isDynamicallyUnique(A
, *this, **SimpleArgOp
))
6349 return unionAssumed(*SimpleArgOp
);
6352 // Generate a answer specific to a call site context.
6354 bool UsedAssumedInformation
= false;
6355 if (hasCallBaseContext() &&
6356 getCallBaseContext()->getCalledOperand() == Arg
->getParent())
6357 Success
= PredForCallSite(
6358 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6360 Success
= A
.checkForAllCallSites(PredForCallSite
, *this, true,
6361 UsedAssumedInformation
);
6364 if (!askSimplifiedValueForOtherAAs(A
))
6365 return indicatePessimisticFixpoint();
6367 // If a candidate was found in this update, return CHANGED.
6368 return Before
== SimplifiedAssociatedValue
? ChangeStatus::UNCHANGED
6369 : ChangeStatus ::CHANGED
;
6372 /// See AbstractAttribute::trackStatistics()
6373 void trackStatistics() const override
{
6374 STATS_DECLTRACK_ARG_ATTR(value_simplify
)
6378 struct AAValueSimplifyReturned
: AAValueSimplifyImpl
{
6379 AAValueSimplifyReturned(const IRPosition
&IRP
, Attributor
&A
)
6380 : AAValueSimplifyImpl(IRP
, A
) {}
6382 /// See AAValueSimplify::getAssumedSimplifiedValue()
6383 std::optional
<Value
*>
6384 getAssumedSimplifiedValue(Attributor
&A
) const override
{
6385 if (!isValidState())
6387 return SimplifiedAssociatedValue
;
6390 /// See AbstractAttribute::updateImpl(...).
6391 ChangeStatus
updateImpl(Attributor
&A
) override
{
6392 auto Before
= SimplifiedAssociatedValue
;
6394 auto ReturnInstCB
= [&](Instruction
&I
) {
6395 auto &RI
= cast
<ReturnInst
>(I
);
6396 return checkAndUpdate(
6398 IRPosition::value(*RI
.getReturnValue(), getCallBaseContext()));
6401 bool UsedAssumedInformation
= false;
6402 if (!A
.checkForAllInstructions(ReturnInstCB
, *this, {Instruction::Ret
},
6403 UsedAssumedInformation
))
6404 if (!askSimplifiedValueForOtherAAs(A
))
6405 return indicatePessimisticFixpoint();
6407 // If a candidate was found in this update, return CHANGED.
6408 return Before
== SimplifiedAssociatedValue
? ChangeStatus::UNCHANGED
6409 : ChangeStatus ::CHANGED
;
6412 ChangeStatus
manifest(Attributor
&A
) override
{
6413 // We queried AAValueSimplify for the returned values so they will be
6414 // replaced if a simplified form was found. Nothing to do here.
6415 return ChangeStatus::UNCHANGED
;
6418 /// See AbstractAttribute::trackStatistics()
6419 void trackStatistics() const override
{
6420 STATS_DECLTRACK_FNRET_ATTR(value_simplify
)
6424 struct AAValueSimplifyFloating
: AAValueSimplifyImpl
{
6425 AAValueSimplifyFloating(const IRPosition
&IRP
, Attributor
&A
)
6426 : AAValueSimplifyImpl(IRP
, A
) {}
6428 /// See AbstractAttribute::initialize(...).
6429 void initialize(Attributor
&A
) override
{
6430 AAValueSimplifyImpl::initialize(A
);
6431 Value
&V
= getAnchorValue();
6433 // TODO: add other stuffs
6434 if (isa
<Constant
>(V
))
6435 indicatePessimisticFixpoint();
6438 /// See AbstractAttribute::updateImpl(...).
6439 ChangeStatus
updateImpl(Attributor
&A
) override
{
6440 auto Before
= SimplifiedAssociatedValue
;
6441 if (!askSimplifiedValueForOtherAAs(A
))
6442 return indicatePessimisticFixpoint();
6444 // If a candidate was found in this update, return CHANGED.
6445 return Before
== SimplifiedAssociatedValue
? ChangeStatus::UNCHANGED
6446 : ChangeStatus ::CHANGED
;
6449 /// See AbstractAttribute::trackStatistics()
6450 void trackStatistics() const override
{
6451 STATS_DECLTRACK_FLOATING_ATTR(value_simplify
)
6455 struct AAValueSimplifyFunction
: AAValueSimplifyImpl
{
6456 AAValueSimplifyFunction(const IRPosition
&IRP
, Attributor
&A
)
6457 : AAValueSimplifyImpl(IRP
, A
) {}
6459 /// See AbstractAttribute::initialize(...).
6460 void initialize(Attributor
&A
) override
{
6461 SimplifiedAssociatedValue
= nullptr;
6462 indicateOptimisticFixpoint();
6464 /// See AbstractAttribute::initialize(...).
6465 ChangeStatus
updateImpl(Attributor
&A
) override
{
6467 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6469 /// See AbstractAttribute::trackStatistics()
6470 void trackStatistics() const override
{
6471 STATS_DECLTRACK_FN_ATTR(value_simplify
)
6475 struct AAValueSimplifyCallSite
: AAValueSimplifyFunction
{
6476 AAValueSimplifyCallSite(const IRPosition
&IRP
, Attributor
&A
)
6477 : AAValueSimplifyFunction(IRP
, A
) {}
6478 /// See AbstractAttribute::trackStatistics()
6479 void trackStatistics() const override
{
6480 STATS_DECLTRACK_CS_ATTR(value_simplify
)
6484 struct AAValueSimplifyCallSiteReturned
: AAValueSimplifyImpl
{
6485 AAValueSimplifyCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
6486 : AAValueSimplifyImpl(IRP
, A
) {}
6488 void initialize(Attributor
&A
) override
{
6489 AAValueSimplifyImpl::initialize(A
);
6490 Function
*Fn
= getAssociatedFunction();
6491 assert(Fn
&& "Did expect an associted function");
6492 for (Argument
&Arg
: Fn
->args()) {
6493 if (Arg
.hasReturnedAttr()) {
6494 auto IRP
= IRPosition::callsite_argument(*cast
<CallBase
>(getCtxI()),
6496 if (IRP
.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT
&&
6497 checkAndUpdate(A
, *this, IRP
))
6498 indicateOptimisticFixpoint();
6500 indicatePessimisticFixpoint();
6506 /// See AbstractAttribute::updateImpl(...).
6507 ChangeStatus
updateImpl(Attributor
&A
) override
{
6508 return indicatePessimisticFixpoint();
6511 void trackStatistics() const override
{
6512 STATS_DECLTRACK_CSRET_ATTR(value_simplify
)
6516 struct AAValueSimplifyCallSiteArgument
: AAValueSimplifyFloating
{
6517 AAValueSimplifyCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
6518 : AAValueSimplifyFloating(IRP
, A
) {}
6520 /// See AbstractAttribute::manifest(...).
6521 ChangeStatus
manifest(Attributor
&A
) override
{
6522 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
6523 // TODO: We should avoid simplification duplication to begin with.
6524 auto *FloatAA
= A
.lookupAAFor
<AAValueSimplify
>(
6525 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE
);
6526 if (FloatAA
&& FloatAA
->getState().isValidState())
6529 if (auto *NewV
= manifestReplacementValue(A
, getCtxI())) {
6530 Use
&U
= cast
<CallBase
>(&getAnchorValue())
6531 ->getArgOperandUse(getCallSiteArgNo());
6532 if (A
.changeUseAfterManifest(U
, *NewV
))
6533 Changed
= ChangeStatus::CHANGED
;
6536 return Changed
| AAValueSimplify::manifest(A
);
6539 void trackStatistics() const override
{
6540 STATS_DECLTRACK_CSARG_ATTR(value_simplify
)
6545 /// ----------------------- Heap-To-Stack Conversion ---------------------------
6547 struct AAHeapToStackFunction final
: public AAHeapToStack
{
6549 struct AllocationInfo
{
6550 /// The call that allocates the memory.
6553 /// The library function id for the allocation.
6554 LibFunc LibraryFunctionId
= NotLibFunc
;
6556 /// The status wrt. a rewrite.
6561 } Status
= STACK_DUE_TO_USE
;
6563 /// Flag to indicate if we encountered a use that might free this allocation
6564 /// but which is not in the deallocation infos.
6565 bool HasPotentiallyFreeingUnknownUses
= false;
6567 /// Flag to indicate that we should place the new alloca in the function
6568 /// entry block rather than where the call site (CB) is.
6569 bool MoveAllocaIntoEntry
= true;
6571 /// The set of free calls that use this allocation.
6572 SmallSetVector
<CallBase
*, 1> PotentialFreeCalls
{};
6575 struct DeallocationInfo
{
6576 /// The call that deallocates the memory.
6578 /// The value freed by the call.
6581 /// Flag to indicate if we don't know all objects this deallocation might
6583 bool MightFreeUnknownObjects
= false;
6585 /// The set of allocation calls that are potentially freed.
6586 SmallSetVector
<CallBase
*, 1> PotentialAllocationCalls
{};
6589 AAHeapToStackFunction(const IRPosition
&IRP
, Attributor
&A
)
6590 : AAHeapToStack(IRP
, A
) {}
6592 ~AAHeapToStackFunction() {
6593 // Ensure we call the destructor so we release any memory allocated in the
6595 for (auto &It
: AllocationInfos
)
6596 It
.second
->~AllocationInfo();
6597 for (auto &It
: DeallocationInfos
)
6598 It
.second
->~DeallocationInfo();
6601 void initialize(Attributor
&A
) override
{
6602 AAHeapToStack::initialize(A
);
6604 const Function
*F
= getAnchorScope();
6605 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
6607 auto AllocationIdentifierCB
= [&](Instruction
&I
) {
6608 CallBase
*CB
= dyn_cast
<CallBase
>(&I
);
6611 if (Value
*FreedOp
= getFreedOperand(CB
, TLI
)) {
6612 DeallocationInfos
[CB
] = new (A
.Allocator
) DeallocationInfo
{CB
, FreedOp
};
6615 // To do heap to stack, we need to know that the allocation itself is
6616 // removable once uses are rewritten, and that we can initialize the
6617 // alloca to the same pattern as the original allocation result.
6618 if (isRemovableAlloc(CB
, TLI
)) {
6619 auto *I8Ty
= Type::getInt8Ty(CB
->getParent()->getContext());
6620 if (nullptr != getInitialValueOfAllocation(CB
, TLI
, I8Ty
)) {
6621 AllocationInfo
*AI
= new (A
.Allocator
) AllocationInfo
{CB
};
6622 AllocationInfos
[CB
] = AI
;
6624 TLI
->getLibFunc(*CB
, AI
->LibraryFunctionId
);
6630 bool UsedAssumedInformation
= false;
6631 bool Success
= A
.checkForAllCallLikeInstructions(
6632 AllocationIdentifierCB
, *this, UsedAssumedInformation
,
6633 /* CheckBBLivenessOnly */ false,
6634 /* CheckPotentiallyDead */ true);
6636 assert(Success
&& "Did not expect the call base visit callback to fail!");
6638 Attributor::SimplifictionCallbackTy SCB
=
6639 [](const IRPosition
&, const AbstractAttribute
*,
6640 bool &) -> std::optional
<Value
*> { return nullptr; };
6641 for (const auto &It
: AllocationInfos
)
6642 A
.registerSimplificationCallback(IRPosition::callsite_returned(*It
.first
),
6644 for (const auto &It
: DeallocationInfos
)
6645 A
.registerSimplificationCallback(IRPosition::callsite_returned(*It
.first
),
6649 const std::string
getAsStr(Attributor
*A
) const override
{
6650 unsigned NumH2SMallocs
= 0, NumInvalidMallocs
= 0;
6651 for (const auto &It
: AllocationInfos
) {
6652 if (It
.second
->Status
== AllocationInfo::INVALID
)
6653 ++NumInvalidMallocs
;
6657 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs
) + "/" +
6658 std::to_string(NumInvalidMallocs
);
6661 /// See AbstractAttribute::trackStatistics().
6662 void trackStatistics() const override
{
6664 MallocCalls
, Function
,
6665 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6666 for (const auto &It
: AllocationInfos
)
6667 if (It
.second
->Status
!= AllocationInfo::INVALID
)
6668 ++BUILD_STAT_NAME(MallocCalls
, Function
);
6671 bool isAssumedHeapToStack(const CallBase
&CB
) const override
{
6673 if (AllocationInfo
*AI
=
6674 AllocationInfos
.lookup(const_cast<CallBase
*>(&CB
)))
6675 return AI
->Status
!= AllocationInfo::INVALID
;
6679 bool isAssumedHeapToStackRemovedFree(CallBase
&CB
) const override
{
6680 if (!isValidState())
6683 for (const auto &It
: AllocationInfos
) {
6684 AllocationInfo
&AI
= *It
.second
;
6685 if (AI
.Status
== AllocationInfo::INVALID
)
6688 if (AI
.PotentialFreeCalls
.count(&CB
))
6695 ChangeStatus
manifest(Attributor
&A
) override
{
6696 assert(getState().isValidState() &&
6697 "Attempted to manifest an invalid state!");
6699 ChangeStatus HasChanged
= ChangeStatus::UNCHANGED
;
6700 Function
*F
= getAnchorScope();
6701 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
6703 for (auto &It
: AllocationInfos
) {
6704 AllocationInfo
&AI
= *It
.second
;
6705 if (AI
.Status
== AllocationInfo::INVALID
)
6708 for (CallBase
*FreeCall
: AI
.PotentialFreeCalls
) {
6709 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall
<< "\n");
6710 A
.deleteAfterManifest(*FreeCall
);
6711 HasChanged
= ChangeStatus::CHANGED
;
6714 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI
.CB
6717 auto Remark
= [&](OptimizationRemark OR
) {
6718 LibFunc IsAllocShared
;
6719 if (TLI
->getLibFunc(*AI
.CB
, IsAllocShared
))
6720 if (IsAllocShared
== LibFunc___kmpc_alloc_shared
)
6721 return OR
<< "Moving globalized variable to the stack.";
6722 return OR
<< "Moving memory allocation from the heap to the stack.";
6724 if (AI
.LibraryFunctionId
== LibFunc___kmpc_alloc_shared
)
6725 A
.emitRemark
<OptimizationRemark
>(AI
.CB
, "OMP110", Remark
);
6727 A
.emitRemark
<OptimizationRemark
>(AI
.CB
, "HeapToStack", Remark
);
6729 const DataLayout
&DL
= A
.getInfoCache().getDL();
6731 std::optional
<APInt
> SizeAPI
= getSize(A
, *this, AI
);
6733 Size
= ConstantInt::get(AI
.CB
->getContext(), *SizeAPI
);
6735 LLVMContext
&Ctx
= AI
.CB
->getContext();
6736 ObjectSizeOpts Opts
;
6737 ObjectSizeOffsetEvaluator
Eval(DL
, TLI
, Ctx
, Opts
);
6738 SizeOffsetEvalType SizeOffsetPair
= Eval
.compute(AI
.CB
);
6739 assert(SizeOffsetPair
!= ObjectSizeOffsetEvaluator::unknown() &&
6740 cast
<ConstantInt
>(SizeOffsetPair
.second
)->isZero());
6741 Size
= SizeOffsetPair
.first
;
6745 AI
.MoveAllocaIntoEntry
? &F
->getEntryBlock().front() : AI
.CB
;
6748 if (MaybeAlign RetAlign
= AI
.CB
->getRetAlign())
6749 Alignment
= std::max(Alignment
, *RetAlign
);
6750 if (Value
*Align
= getAllocAlignment(AI
.CB
, TLI
)) {
6751 std::optional
<APInt
> AlignmentAPI
= getAPInt(A
, *this, *Align
);
6752 assert(AlignmentAPI
&& AlignmentAPI
->getZExtValue() > 0 &&
6753 "Expected an alignment during manifest!");
6755 std::max(Alignment
, assumeAligned(AlignmentAPI
->getZExtValue()));
6758 // TODO: Hoist the alloca towards the function entry.
6759 unsigned AS
= DL
.getAllocaAddrSpace();
6760 Instruction
*Alloca
=
6761 new AllocaInst(Type::getInt8Ty(F
->getContext()), AS
, Size
, Alignment
,
6762 AI
.CB
->getName() + ".h2s", IP
);
6764 if (Alloca
->getType() != AI
.CB
->getType())
6765 Alloca
= BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6766 Alloca
, AI
.CB
->getType(), "malloc_cast", AI
.CB
);
6768 auto *I8Ty
= Type::getInt8Ty(F
->getContext());
6769 auto *InitVal
= getInitialValueOfAllocation(AI
.CB
, TLI
, I8Ty
);
6771 "Must be able to materialize initial memory state of allocation");
6773 A
.changeAfterManifest(IRPosition::inst(*AI
.CB
), *Alloca
);
6775 if (auto *II
= dyn_cast
<InvokeInst
>(AI
.CB
)) {
6776 auto *NBB
= II
->getNormalDest();
6777 BranchInst::Create(NBB
, AI
.CB
->getParent());
6778 A
.deleteAfterManifest(*AI
.CB
);
6780 A
.deleteAfterManifest(*AI
.CB
);
6783 // Initialize the alloca with the same value as used by the allocation
6784 // function. We can skip undef as the initial value of an alloc is
6785 // undef, and the memset would simply end up being DSEd.
6786 if (!isa
<UndefValue
>(InitVal
)) {
6787 IRBuilder
<> Builder(Alloca
->getNextNode());
6788 // TODO: Use alignment above if align!=1
6789 Builder
.CreateMemSet(Alloca
, InitVal
, Size
, std::nullopt
);
6791 HasChanged
= ChangeStatus::CHANGED
;
6797 std::optional
<APInt
> getAPInt(Attributor
&A
, const AbstractAttribute
&AA
,
6799 bool UsedAssumedInformation
= false;
6800 std::optional
<Constant
*> SimpleV
=
6801 A
.getAssumedConstant(V
, AA
, UsedAssumedInformation
);
6803 return APInt(64, 0);
6804 if (auto *CI
= dyn_cast_or_null
<ConstantInt
>(*SimpleV
))
6805 return CI
->getValue();
6806 return std::nullopt
;
6809 std::optional
<APInt
> getSize(Attributor
&A
, const AbstractAttribute
&AA
,
6810 AllocationInfo
&AI
) {
6811 auto Mapper
= [&](const Value
*V
) -> const Value
* {
6812 bool UsedAssumedInformation
= false;
6813 if (std::optional
<Constant
*> SimpleV
=
6814 A
.getAssumedConstant(*V
, AA
, UsedAssumedInformation
))
6820 const Function
*F
= getAnchorScope();
6821 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
6822 return getAllocSize(AI
.CB
, TLI
, Mapper
);
6825 /// Collection of all malloc-like calls in a function with associated
6827 MapVector
<CallBase
*, AllocationInfo
*> AllocationInfos
;
6829 /// Collection of all free-like calls in a function with associated
6831 MapVector
<CallBase
*, DeallocationInfo
*> DeallocationInfos
;
6833 ChangeStatus
updateImpl(Attributor
&A
) override
;
6836 ChangeStatus
AAHeapToStackFunction::updateImpl(Attributor
&A
) {
6837 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
6838 const Function
*F
= getAnchorScope();
6839 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
6841 const auto *LivenessAA
=
6842 A
.getAAFor
<AAIsDead
>(*this, IRPosition::function(*F
), DepClassTy::NONE
);
6844 MustBeExecutedContextExplorer
*Explorer
=
6845 A
.getInfoCache().getMustBeExecutedContextExplorer();
6847 bool StackIsAccessibleByOtherThreads
=
6848 A
.getInfoCache().stackIsAccessibleByOtherThreads();
6851 A
.getInfoCache().getAnalysisResultForFunction
<LoopAnalysis
>(*F
);
6852 std::optional
<bool> MayContainIrreducibleControl
;
6853 auto IsInLoop
= [&](BasicBlock
&BB
) {
6854 if (&F
->getEntryBlock() == &BB
)
6856 if (!MayContainIrreducibleControl
.has_value())
6857 MayContainIrreducibleControl
= mayContainIrreducibleControl(*F
, LI
);
6858 if (*MayContainIrreducibleControl
)
6862 return LI
->getLoopFor(&BB
) != nullptr;
6865 // Flag to ensure we update our deallocation information at most once per
6866 // updateImpl call and only if we use the free check reasoning.
6867 bool HasUpdatedFrees
= false;
6869 auto UpdateFrees
= [&]() {
6870 HasUpdatedFrees
= true;
6872 for (auto &It
: DeallocationInfos
) {
6873 DeallocationInfo
&DI
= *It
.second
;
6874 // For now we cannot use deallocations that have unknown inputs, skip
6876 if (DI
.MightFreeUnknownObjects
)
6879 // No need to analyze dead calls, ignore them instead.
6880 bool UsedAssumedInformation
= false;
6881 if (A
.isAssumedDead(*DI
.CB
, this, LivenessAA
, UsedAssumedInformation
,
6882 /* CheckBBLivenessOnly */ true))
6885 // Use the non-optimistic version to get the freed object.
6886 Value
*Obj
= getUnderlyingObject(DI
.FreedOp
);
6888 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6889 DI
.MightFreeUnknownObjects
= true;
6893 // Free of null and undef can be ignored as no-ops (or UB in the latter
6895 if (isa
<ConstantPointerNull
>(Obj
) || isa
<UndefValue
>(Obj
))
6898 CallBase
*ObjCB
= dyn_cast
<CallBase
>(Obj
);
6900 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6902 DI
.MightFreeUnknownObjects
= true;
6906 AllocationInfo
*AI
= AllocationInfos
.lookup(ObjCB
);
6908 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6910 DI
.MightFreeUnknownObjects
= true;
6914 DI
.PotentialAllocationCalls
.insert(ObjCB
);
6918 auto FreeCheck
= [&](AllocationInfo
&AI
) {
6919 // If the stack is not accessible by other threads, the "must-free" logic
6920 // doesn't apply as the pointer could be shared and needs to be places in
6921 // "shareable" memory.
6922 if (!StackIsAccessibleByOtherThreads
) {
6924 if (!AA::hasAssumedIRAttr
<Attribute::NoSync
>(
6925 A
, this, getIRPosition(), DepClassTy::OPTIONAL
, IsKnownNoSycn
)) {
6927 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6928 "other threads and function is not nosync:\n");
6932 if (!HasUpdatedFrees
)
6935 // TODO: Allow multi exit functions that have different free calls.
6936 if (AI
.PotentialFreeCalls
.size() != 1) {
6937 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
6938 << AI
.PotentialFreeCalls
.size() << "\n");
6941 CallBase
*UniqueFree
= *AI
.PotentialFreeCalls
.begin();
6942 DeallocationInfo
*DI
= DeallocationInfos
.lookup(UniqueFree
);
6945 dbgs() << "[H2S] unique free call was not known as deallocation call "
6946 << *UniqueFree
<< "\n");
6949 if (DI
->MightFreeUnknownObjects
) {
6951 dbgs() << "[H2S] unique free call might free unknown allocations\n");
6954 if (DI
->PotentialAllocationCalls
.empty())
6956 if (DI
->PotentialAllocationCalls
.size() > 1) {
6957 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
6958 << DI
->PotentialAllocationCalls
.size()
6959 << " different allocations\n");
6962 if (*DI
->PotentialAllocationCalls
.begin() != AI
.CB
) {
6965 << "[H2S] unique free call not known to free this allocation but "
6966 << **DI
->PotentialAllocationCalls
.begin() << "\n");
6970 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
6971 if (AI
.LibraryFunctionId
!= LibFunc___kmpc_alloc_shared
) {
6972 Instruction
*CtxI
= isa
<InvokeInst
>(AI
.CB
) ? AI
.CB
: AI
.CB
->getNextNode();
6973 if (!Explorer
|| !Explorer
->findInContextOf(UniqueFree
, CtxI
)) {
6976 << "[H2S] unique free call might not be executed with the allocation "
6977 << *UniqueFree
<< "\n");
6984 auto UsesCheck
= [&](AllocationInfo
&AI
) {
6985 bool ValidUsesOnly
= true;
6987 auto Pred
= [&](const Use
&U
, bool &Follow
) -> bool {
6988 Instruction
*UserI
= cast
<Instruction
>(U
.getUser());
6989 if (isa
<LoadInst
>(UserI
))
6991 if (auto *SI
= dyn_cast
<StoreInst
>(UserI
)) {
6992 if (SI
->getValueOperand() == U
.get()) {
6994 << "[H2S] escaping store to memory: " << *UserI
<< "\n");
6995 ValidUsesOnly
= false;
6997 // A store into the malloc'ed memory is fine.
7001 if (auto *CB
= dyn_cast
<CallBase
>(UserI
)) {
7002 if (!CB
->isArgOperand(&U
) || CB
->isLifetimeStartOrEnd())
7004 if (DeallocationInfos
.count(CB
)) {
7005 AI
.PotentialFreeCalls
.insert(CB
);
7009 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
7010 auto CBIRP
= IRPosition::callsite_argument(*CB
, ArgNo
);
7012 bool IsKnownNoCapture
;
7013 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
7014 A
, this, CBIRP
, DepClassTy::OPTIONAL
, IsKnownNoCapture
);
7016 // If a call site argument use is nofree, we are fine.
7018 bool IsAssumedNoFree
= AA::hasAssumedIRAttr
<Attribute::NoFree
>(
7019 A
, this, CBIRP
, DepClassTy::OPTIONAL
, IsKnownNoFree
);
7021 if (!IsAssumedNoCapture
||
7022 (AI
.LibraryFunctionId
!= LibFunc___kmpc_alloc_shared
&&
7023 !IsAssumedNoFree
)) {
7024 AI
.HasPotentiallyFreeingUnknownUses
|= !IsAssumedNoFree
;
7026 // Emit a missed remark if this is missed OpenMP globalization.
7027 auto Remark
= [&](OptimizationRemarkMissed ORM
) {
7029 << "Could not move globalized variable to the stack. "
7030 "Variable is potentially captured in call. Mark "
7031 "parameter as `__attribute__((noescape))` to override.";
7034 if (ValidUsesOnly
&&
7035 AI
.LibraryFunctionId
== LibFunc___kmpc_alloc_shared
)
7036 A
.emitRemark
<OptimizationRemarkMissed
>(CB
, "OMP113", Remark
);
7038 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI
<< "\n");
7039 ValidUsesOnly
= false;
7044 if (isa
<GetElementPtrInst
>(UserI
) || isa
<BitCastInst
>(UserI
) ||
7045 isa
<PHINode
>(UserI
) || isa
<SelectInst
>(UserI
)) {
7049 // Unknown user for which we can not track uses further (in a way that
7051 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI
<< "\n");
7052 ValidUsesOnly
= false;
7055 if (!A
.checkForAllUses(Pred
, *this, *AI
.CB
, /* CheckBBLivenessOnly */ false,
7056 DepClassTy::OPTIONAL
, /* IgnoreDroppableUses */ true,
7057 [&](const Use
&OldU
, const Use
&NewU
) {
7058 auto *SI
= dyn_cast
<StoreInst
>(OldU
.getUser());
7059 return !SI
|| StackIsAccessibleByOtherThreads
||
7060 AA::isAssumedThreadLocalObject(
7061 A
, *SI
->getPointerOperand(), *this);
7064 return ValidUsesOnly
;
7067 // The actual update starts here. We look at all allocations and depending on
7068 // their status perform the appropriate check(s).
7069 for (auto &It
: AllocationInfos
) {
7070 AllocationInfo
&AI
= *It
.second
;
7071 if (AI
.Status
== AllocationInfo::INVALID
)
7074 if (Value
*Align
= getAllocAlignment(AI
.CB
, TLI
)) {
7075 std::optional
<APInt
> APAlign
= getAPInt(A
, *this, *Align
);
7077 // Can't generate an alloca which respects the required alignment
7078 // on the allocation.
7079 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI
.CB
7081 AI
.Status
= AllocationInfo::INVALID
;
7082 Changed
= ChangeStatus::CHANGED
;
7085 if (APAlign
->ugt(llvm::Value::MaximumAlignment
) ||
7086 !APAlign
->isPowerOf2()) {
7087 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7089 AI
.Status
= AllocationInfo::INVALID
;
7090 Changed
= ChangeStatus::CHANGED
;
7095 std::optional
<APInt
> Size
= getSize(A
, *this, AI
);
7096 if (AI
.LibraryFunctionId
!= LibFunc___kmpc_alloc_shared
&&
7097 MaxHeapToStackSize
!= -1) {
7098 if (!Size
|| Size
->ugt(MaxHeapToStackSize
)) {
7101 dbgs() << "[H2S] Unknown allocation size: " << *AI
.CB
<< "\n";
7103 dbgs() << "[H2S] Allocation size too large: " << *AI
.CB
<< " vs. "
7104 << MaxHeapToStackSize
<< "\n";
7107 AI
.Status
= AllocationInfo::INVALID
;
7108 Changed
= ChangeStatus::CHANGED
;
7113 switch (AI
.Status
) {
7114 case AllocationInfo::STACK_DUE_TO_USE
:
7117 AI
.Status
= AllocationInfo::STACK_DUE_TO_FREE
;
7119 case AllocationInfo::STACK_DUE_TO_FREE
:
7122 AI
.Status
= AllocationInfo::INVALID
;
7123 Changed
= ChangeStatus::CHANGED
;
7125 case AllocationInfo::INVALID
:
7126 llvm_unreachable("Invalid allocations should never reach this point!");
7129 // Check if we still think we can move it into the entry block. If the
7130 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7131 // ignore the potential compilations associated with loops.
7132 bool IsGlobalizedLocal
=
7133 AI
.LibraryFunctionId
== LibFunc___kmpc_alloc_shared
;
7134 if (AI
.MoveAllocaIntoEntry
&&
7135 (!Size
.has_value() ||
7136 (!IsGlobalizedLocal
&& IsInLoop(*AI
.CB
->getParent()))))
7137 AI
.MoveAllocaIntoEntry
= false;
7144 /// ----------------------- Privatizable Pointers ------------------------------
7146 struct AAPrivatizablePtrImpl
: public AAPrivatizablePtr
{
7147 AAPrivatizablePtrImpl(const IRPosition
&IRP
, Attributor
&A
)
7148 : AAPrivatizablePtr(IRP
, A
), PrivatizableType(std::nullopt
) {}
7150 ChangeStatus
indicatePessimisticFixpoint() override
{
7151 AAPrivatizablePtr::indicatePessimisticFixpoint();
7152 PrivatizableType
= nullptr;
7153 return ChangeStatus::CHANGED
;
7156 /// Identify the type we can chose for a private copy of the underlying
7157 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7159 virtual std::optional
<Type
*> identifyPrivatizableType(Attributor
&A
) = 0;
7161 /// Return a privatizable type that encloses both T0 and T1.
7162 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7163 std::optional
<Type
*> combineTypes(std::optional
<Type
*> T0
,
7164 std::optional
<Type
*> T1
) {
7174 std::optional
<Type
*> getPrivatizableType() const override
{
7175 return PrivatizableType
;
7178 const std::string
getAsStr(Attributor
*A
) const override
{
7179 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7183 std::optional
<Type
*> PrivatizableType
;
7186 // TODO: Do this for call site arguments (probably also other values) as well.
7188 struct AAPrivatizablePtrArgument final
: public AAPrivatizablePtrImpl
{
7189 AAPrivatizablePtrArgument(const IRPosition
&IRP
, Attributor
&A
)
7190 : AAPrivatizablePtrImpl(IRP
, A
) {}
7192 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7193 std::optional
<Type
*> identifyPrivatizableType(Attributor
&A
) override
{
7194 // If this is a byval argument and we know all the call sites (so we can
7195 // rewrite them), there is no need to check them explicitly.
7196 bool UsedAssumedInformation
= false;
7197 SmallVector
<Attribute
, 1> Attrs
;
7198 A
.getAttrs(getIRPosition(), {Attribute::ByVal
}, Attrs
,
7199 /* IgnoreSubsumingPositions */ true);
7200 if (!Attrs
.empty() &&
7201 A
.checkForAllCallSites([](AbstractCallSite ACS
) { return true; }, *this,
7202 true, UsedAssumedInformation
))
7203 return Attrs
[0].getValueAsType();
7205 std::optional
<Type
*> Ty
;
7206 unsigned ArgNo
= getIRPosition().getCallSiteArgNo();
7208 // Make sure the associated call site argument has the same type at all call
7209 // sites and it is an allocation we know is safe to privatize, for now that
7210 // means we only allow alloca instructions.
7211 // TODO: We can additionally analyze the accesses in the callee to create
7212 // the type from that information instead. That is a little more
7213 // involved and will be done in a follow up patch.
7214 auto CallSiteCheck
= [&](AbstractCallSite ACS
) {
7215 IRPosition ACSArgPos
= IRPosition::callsite_argument(ACS
, ArgNo
);
7216 // Check if a coresponding argument was found or if it is one not
7217 // associated (which can happen for callback calls).
7218 if (ACSArgPos
.getPositionKind() == IRPosition::IRP_INVALID
)
7221 // Check that all call sites agree on a type.
7223 A
.getAAFor
<AAPrivatizablePtr
>(*this, ACSArgPos
, DepClassTy::REQUIRED
);
7226 std::optional
<Type
*> CSTy
= PrivCSArgAA
->getPrivatizableType();
7229 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos
<< ", CSTy: ";
7231 (*CSTy
)->print(dbgs());
7233 dbgs() << "<nullptr>";
7238 Ty
= combineTypes(Ty
, CSTy
);
7241 dbgs() << " : New Type: ";
7243 (*Ty
)->print(dbgs());
7245 dbgs() << "<nullptr>";
7254 if (!A
.checkForAllCallSites(CallSiteCheck
, *this, true,
7255 UsedAssumedInformation
))
7260 /// See AbstractAttribute::updateImpl(...).
7261 ChangeStatus
updateImpl(Attributor
&A
) override
{
7262 PrivatizableType
= identifyPrivatizableType(A
);
7263 if (!PrivatizableType
)
7264 return ChangeStatus::UNCHANGED
;
7265 if (!*PrivatizableType
)
7266 return indicatePessimisticFixpoint();
7268 // The dependence is optional so we don't give up once we give up on the
7270 A
.getAAFor
<AAAlign
>(*this, IRPosition::value(getAssociatedValue()),
7271 DepClassTy::OPTIONAL
);
7273 // Avoid arguments with padding for now.
7274 if (!A
.hasAttr(getIRPosition(), Attribute::ByVal
) &&
7275 !isDenselyPacked(*PrivatizableType
, A
.getInfoCache().getDL())) {
7276 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7277 return indicatePessimisticFixpoint();
7280 // Collect the types that will replace the privatizable type in the function
7282 SmallVector
<Type
*, 16> ReplacementTypes
;
7283 identifyReplacementTypes(*PrivatizableType
, ReplacementTypes
);
7285 // Verify callee and caller agree on how the promoted argument would be
7287 Function
&Fn
= *getIRPosition().getAnchorScope();
7289 A
.getInfoCache().getAnalysisResultForFunction
<TargetIRAnalysis
>(Fn
);
7291 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7292 << Fn
.getName() << "\n");
7293 return indicatePessimisticFixpoint();
7296 auto CallSiteCheck
= [&](AbstractCallSite ACS
) {
7297 CallBase
*CB
= ACS
.getInstruction();
7298 return TTI
->areTypesABICompatible(
7300 dyn_cast_if_present
<Function
>(CB
->getCalledOperand()),
7303 bool UsedAssumedInformation
= false;
7304 if (!A
.checkForAllCallSites(CallSiteCheck
, *this, true,
7305 UsedAssumedInformation
)) {
7307 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7308 << Fn
.getName() << "\n");
7309 return indicatePessimisticFixpoint();
7312 // Register a rewrite of the argument.
7313 Argument
*Arg
= getAssociatedArgument();
7314 if (!A
.isValidFunctionSignatureRewrite(*Arg
, ReplacementTypes
)) {
7315 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7316 return indicatePessimisticFixpoint();
7319 unsigned ArgNo
= Arg
->getArgNo();
7321 // Helper to check if for the given call site the associated argument is
7322 // passed to a callback where the privatization would be different.
7323 auto IsCompatiblePrivArgOfCallback
= [&](CallBase
&CB
) {
7324 SmallVector
<const Use
*, 4> CallbackUses
;
7325 AbstractCallSite::getCallbackUses(CB
, CallbackUses
);
7326 for (const Use
*U
: CallbackUses
) {
7327 AbstractCallSite
CBACS(U
);
7328 assert(CBACS
&& CBACS
.isCallbackCall());
7329 for (Argument
&CBArg
: CBACS
.getCalledFunction()->args()) {
7330 int CBArgNo
= CBACS
.getCallArgOperandNo(CBArg
);
7334 << "[AAPrivatizablePtr] Argument " << *Arg
7335 << "check if can be privatized in the context of its parent ("
7336 << Arg
->getParent()->getName()
7337 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7339 << CBArgNo
<< "@" << CBACS
.getCalledFunction()->getName()
7340 << ")\n[AAPrivatizablePtr] " << CBArg
<< " : "
7341 << CBACS
.getCallArgOperand(CBArg
) << " vs "
7342 << CB
.getArgOperand(ArgNo
) << "\n"
7343 << "[AAPrivatizablePtr] " << CBArg
<< " : "
7344 << CBACS
.getCallArgOperandNo(CBArg
) << " vs " << ArgNo
<< "\n";
7347 if (CBArgNo
!= int(ArgNo
))
7349 const auto *CBArgPrivAA
= A
.getAAFor
<AAPrivatizablePtr
>(
7350 *this, IRPosition::argument(CBArg
), DepClassTy::REQUIRED
);
7351 if (CBArgPrivAA
&& CBArgPrivAA
->isValidState()) {
7352 auto CBArgPrivTy
= CBArgPrivAA
->getPrivatizableType();
7355 if (*CBArgPrivTy
== PrivatizableType
)
7360 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7361 << " cannot be privatized in the context of its parent ("
7362 << Arg
->getParent()->getName()
7363 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7365 << CBArgNo
<< "@" << CBACS
.getCalledFunction()->getName()
7366 << ").\n[AAPrivatizablePtr] for which the argument "
7367 "privatization is not compatible.\n";
7375 // Helper to check if for the given call site the associated argument is
7376 // passed to a direct call where the privatization would be different.
7377 auto IsCompatiblePrivArgOfDirectCS
= [&](AbstractCallSite ACS
) {
7378 CallBase
*DC
= cast
<CallBase
>(ACS
.getInstruction());
7379 int DCArgNo
= ACS
.getCallArgOperandNo(ArgNo
);
7380 assert(DCArgNo
>= 0 && unsigned(DCArgNo
) < DC
->arg_size() &&
7381 "Expected a direct call operand for callback call operand");
7383 Function
*DCCallee
=
7384 dyn_cast_if_present
<Function
>(DC
->getCalledOperand());
7386 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7387 << " check if be privatized in the context of its parent ("
7388 << Arg
->getParent()->getName()
7389 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7391 << DCArgNo
<< "@" << DCCallee
->getName() << ").\n";
7394 if (unsigned(DCArgNo
) < DCCallee
->arg_size()) {
7395 const auto *DCArgPrivAA
= A
.getAAFor
<AAPrivatizablePtr
>(
7396 *this, IRPosition::argument(*DCCallee
->getArg(DCArgNo
)),
7397 DepClassTy::REQUIRED
);
7398 if (DCArgPrivAA
&& DCArgPrivAA
->isValidState()) {
7399 auto DCArgPrivTy
= DCArgPrivAA
->getPrivatizableType();
7402 if (*DCArgPrivTy
== PrivatizableType
)
7408 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7409 << " cannot be privatized in the context of its parent ("
7410 << Arg
->getParent()->getName()
7411 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7413 << ACS
.getInstruction()->getCalledOperand()->getName()
7414 << ").\n[AAPrivatizablePtr] for which the argument "
7415 "privatization is not compatible.\n";
7420 // Helper to check if the associated argument is used at the given abstract
7421 // call site in a way that is incompatible with the privatization assumed
7423 auto IsCompatiblePrivArgOfOtherCallSite
= [&](AbstractCallSite ACS
) {
7424 if (ACS
.isDirectCall())
7425 return IsCompatiblePrivArgOfCallback(*ACS
.getInstruction());
7426 if (ACS
.isCallbackCall())
7427 return IsCompatiblePrivArgOfDirectCS(ACS
);
7431 if (!A
.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite
, *this, true,
7432 UsedAssumedInformation
))
7433 return indicatePessimisticFixpoint();
7435 return ChangeStatus::UNCHANGED
;
7438 /// Given a type to private \p PrivType, collect the constituates (which are
7439 /// used) in \p ReplacementTypes.
7441 identifyReplacementTypes(Type
*PrivType
,
7442 SmallVectorImpl
<Type
*> &ReplacementTypes
) {
7443 // TODO: For now we expand the privatization type to the fullest which can
7444 // lead to dead arguments that need to be removed later.
7445 assert(PrivType
&& "Expected privatizable type!");
7447 // Traverse the type, extract constituate types on the outermost level.
7448 if (auto *PrivStructType
= dyn_cast
<StructType
>(PrivType
)) {
7449 for (unsigned u
= 0, e
= PrivStructType
->getNumElements(); u
< e
; u
++)
7450 ReplacementTypes
.push_back(PrivStructType
->getElementType(u
));
7451 } else if (auto *PrivArrayType
= dyn_cast
<ArrayType
>(PrivType
)) {
7452 ReplacementTypes
.append(PrivArrayType
->getNumElements(),
7453 PrivArrayType
->getElementType());
7455 ReplacementTypes
.push_back(PrivType
);
7459 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7460 /// The values needed are taken from the arguments of \p F starting at
7461 /// position \p ArgNo.
7462 static void createInitialization(Type
*PrivType
, Value
&Base
, Function
&F
,
7463 unsigned ArgNo
, Instruction
&IP
) {
7464 assert(PrivType
&& "Expected privatizable type!");
7466 IRBuilder
<NoFolder
> IRB(&IP
);
7467 const DataLayout
&DL
= F
.getParent()->getDataLayout();
7469 // Traverse the type, build GEPs and stores.
7470 if (auto *PrivStructType
= dyn_cast
<StructType
>(PrivType
)) {
7471 const StructLayout
*PrivStructLayout
= DL
.getStructLayout(PrivStructType
);
7472 for (unsigned u
= 0, e
= PrivStructType
->getNumElements(); u
< e
; u
++) {
7473 Type
*PointeeTy
= PrivStructType
->getElementType(u
)->getPointerTo();
7475 constructPointer(PointeeTy
, PrivType
, &Base
,
7476 PrivStructLayout
->getElementOffset(u
), IRB
, DL
);
7477 new StoreInst(F
.getArg(ArgNo
+ u
), Ptr
, &IP
);
7479 } else if (auto *PrivArrayType
= dyn_cast
<ArrayType
>(PrivType
)) {
7480 Type
*PointeeTy
= PrivArrayType
->getElementType();
7481 Type
*PointeePtrTy
= PointeeTy
->getPointerTo();
7482 uint64_t PointeeTySize
= DL
.getTypeStoreSize(PointeeTy
);
7483 for (unsigned u
= 0, e
= PrivArrayType
->getNumElements(); u
< e
; u
++) {
7484 Value
*Ptr
= constructPointer(PointeePtrTy
, PrivType
, &Base
,
7485 u
* PointeeTySize
, IRB
, DL
);
7486 new StoreInst(F
.getArg(ArgNo
+ u
), Ptr
, &IP
);
7489 new StoreInst(F
.getArg(ArgNo
), &Base
, &IP
);
7493 /// Extract values from \p Base according to the type \p PrivType at the
7494 /// call position \p ACS. The values are appended to \p ReplacementValues.
7495 void createReplacementValues(Align Alignment
, Type
*PrivType
,
7496 AbstractCallSite ACS
, Value
*Base
,
7497 SmallVectorImpl
<Value
*> &ReplacementValues
) {
7498 assert(Base
&& "Expected base value!");
7499 assert(PrivType
&& "Expected privatizable type!");
7500 Instruction
*IP
= ACS
.getInstruction();
7502 IRBuilder
<NoFolder
> IRB(IP
);
7503 const DataLayout
&DL
= IP
->getModule()->getDataLayout();
7505 Type
*PrivPtrType
= PrivType
->getPointerTo();
7506 if (Base
->getType() != PrivPtrType
)
7507 Base
= BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7508 Base
, PrivPtrType
, "", ACS
.getInstruction());
7510 // Traverse the type, build GEPs and loads.
7511 if (auto *PrivStructType
= dyn_cast
<StructType
>(PrivType
)) {
7512 const StructLayout
*PrivStructLayout
= DL
.getStructLayout(PrivStructType
);
7513 for (unsigned u
= 0, e
= PrivStructType
->getNumElements(); u
< e
; u
++) {
7514 Type
*PointeeTy
= PrivStructType
->getElementType(u
);
7516 constructPointer(PointeeTy
->getPointerTo(), PrivType
, Base
,
7517 PrivStructLayout
->getElementOffset(u
), IRB
, DL
);
7518 LoadInst
*L
= new LoadInst(PointeeTy
, Ptr
, "", IP
);
7519 L
->setAlignment(Alignment
);
7520 ReplacementValues
.push_back(L
);
7522 } else if (auto *PrivArrayType
= dyn_cast
<ArrayType
>(PrivType
)) {
7523 Type
*PointeeTy
= PrivArrayType
->getElementType();
7524 uint64_t PointeeTySize
= DL
.getTypeStoreSize(PointeeTy
);
7525 Type
*PointeePtrTy
= PointeeTy
->getPointerTo();
7526 for (unsigned u
= 0, e
= PrivArrayType
->getNumElements(); u
< e
; u
++) {
7527 Value
*Ptr
= constructPointer(PointeePtrTy
, PrivType
, Base
,
7528 u
* PointeeTySize
, IRB
, DL
);
7529 LoadInst
*L
= new LoadInst(PointeeTy
, Ptr
, "", IP
);
7530 L
->setAlignment(Alignment
);
7531 ReplacementValues
.push_back(L
);
7534 LoadInst
*L
= new LoadInst(PrivType
, Base
, "", IP
);
7535 L
->setAlignment(Alignment
);
7536 ReplacementValues
.push_back(L
);
7540 /// See AbstractAttribute::manifest(...)
7541 ChangeStatus
manifest(Attributor
&A
) override
{
7542 if (!PrivatizableType
)
7543 return ChangeStatus::UNCHANGED
;
7544 assert(*PrivatizableType
&& "Expected privatizable type!");
7546 // Collect all tail calls in the function as we cannot allow new allocas to
7547 // escape into tail recursion.
7548 // TODO: Be smarter about new allocas escaping into tail calls.
7549 SmallVector
<CallInst
*, 16> TailCalls
;
7550 bool UsedAssumedInformation
= false;
7551 if (!A
.checkForAllInstructions(
7552 [&](Instruction
&I
) {
7553 CallInst
&CI
= cast
<CallInst
>(I
);
7554 if (CI
.isTailCall())
7555 TailCalls
.push_back(&CI
);
7558 *this, {Instruction::Call
}, UsedAssumedInformation
))
7559 return ChangeStatus::UNCHANGED
;
7561 Argument
*Arg
= getAssociatedArgument();
7562 // Query AAAlign attribute for alignment of associated argument to
7563 // determine the best alignment of loads.
7564 const auto *AlignAA
=
7565 A
.getAAFor
<AAAlign
>(*this, IRPosition::value(*Arg
), DepClassTy::NONE
);
7567 // Callback to repair the associated function. A new alloca is placed at the
7568 // beginning and initialized with the values passed through arguments. The
7569 // new alloca replaces the use of the old pointer argument.
7570 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB
=
7571 [=](const Attributor::ArgumentReplacementInfo
&ARI
,
7572 Function
&ReplacementFn
, Function::arg_iterator ArgIt
) {
7573 BasicBlock
&EntryBB
= ReplacementFn
.getEntryBlock();
7574 Instruction
*IP
= &*EntryBB
.getFirstInsertionPt();
7575 const DataLayout
&DL
= IP
->getModule()->getDataLayout();
7576 unsigned AS
= DL
.getAllocaAddrSpace();
7577 Instruction
*AI
= new AllocaInst(*PrivatizableType
, AS
,
7578 Arg
->getName() + ".priv", IP
);
7579 createInitialization(*PrivatizableType
, *AI
, ReplacementFn
,
7580 ArgIt
->getArgNo(), *IP
);
7582 if (AI
->getType() != Arg
->getType())
7583 AI
= BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7584 AI
, Arg
->getType(), "", IP
);
7585 Arg
->replaceAllUsesWith(AI
);
7587 for (CallInst
*CI
: TailCalls
)
7588 CI
->setTailCall(false);
7591 // Callback to repair a call site of the associated function. The elements
7592 // of the privatizable type are loaded prior to the call and passed to the
7593 // new function version.
7594 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB
=
7595 [=](const Attributor::ArgumentReplacementInfo
&ARI
,
7596 AbstractCallSite ACS
, SmallVectorImpl
<Value
*> &NewArgOperands
) {
7597 // When no alignment is specified for the load instruction,
7598 // natural alignment is assumed.
7599 createReplacementValues(
7600 AlignAA
? AlignAA
->getAssumedAlign() : Align(0),
7601 *PrivatizableType
, ACS
,
7602 ACS
.getCallArgOperand(ARI
.getReplacedArg().getArgNo()),
7606 // Collect the types that will replace the privatizable type in the function
7608 SmallVector
<Type
*, 16> ReplacementTypes
;
7609 identifyReplacementTypes(*PrivatizableType
, ReplacementTypes
);
7611 // Register a rewrite of the argument.
7612 if (A
.registerFunctionSignatureRewrite(*Arg
, ReplacementTypes
,
7613 std::move(FnRepairCB
),
7614 std::move(ACSRepairCB
)))
7615 return ChangeStatus::CHANGED
;
7616 return ChangeStatus::UNCHANGED
;
7619 /// See AbstractAttribute::trackStatistics()
7620 void trackStatistics() const override
{
7621 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr
);
7625 struct AAPrivatizablePtrFloating
: public AAPrivatizablePtrImpl
{
7626 AAPrivatizablePtrFloating(const IRPosition
&IRP
, Attributor
&A
)
7627 : AAPrivatizablePtrImpl(IRP
, A
) {}
7629 /// See AbstractAttribute::initialize(...).
7630 void initialize(Attributor
&A
) override
{
7631 // TODO: We can privatize more than arguments.
7632 indicatePessimisticFixpoint();
7635 ChangeStatus
updateImpl(Attributor
&A
) override
{
7636 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7637 "updateImpl will not be called");
7640 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7641 std::optional
<Type
*> identifyPrivatizableType(Attributor
&A
) override
{
7642 Value
*Obj
= getUnderlyingObject(&getAssociatedValue());
7644 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7648 if (auto *AI
= dyn_cast
<AllocaInst
>(Obj
))
7649 if (auto *CI
= dyn_cast
<ConstantInt
>(AI
->getArraySize()))
7651 return AI
->getAllocatedType();
7652 if (auto *Arg
= dyn_cast
<Argument
>(Obj
)) {
7653 auto *PrivArgAA
= A
.getAAFor
<AAPrivatizablePtr
>(
7654 *this, IRPosition::argument(*Arg
), DepClassTy::REQUIRED
);
7655 if (PrivArgAA
&& PrivArgAA
->isAssumedPrivatizablePtr())
7656 return PrivArgAA
->getPrivatizableType();
7659 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7660 "alloca nor privatizable argument: "
7665 /// See AbstractAttribute::trackStatistics()
7666 void trackStatistics() const override
{
7667 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr
);
7671 struct AAPrivatizablePtrCallSiteArgument final
7672 : public AAPrivatizablePtrFloating
{
7673 AAPrivatizablePtrCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
7674 : AAPrivatizablePtrFloating(IRP
, A
) {}
7676 /// See AbstractAttribute::initialize(...).
7677 void initialize(Attributor
&A
) override
{
7678 if (A
.hasAttr(getIRPosition(), Attribute::ByVal
))
7679 indicateOptimisticFixpoint();
7682 /// See AbstractAttribute::updateImpl(...).
7683 ChangeStatus
updateImpl(Attributor
&A
) override
{
7684 PrivatizableType
= identifyPrivatizableType(A
);
7685 if (!PrivatizableType
)
7686 return ChangeStatus::UNCHANGED
;
7687 if (!*PrivatizableType
)
7688 return indicatePessimisticFixpoint();
7690 const IRPosition
&IRP
= getIRPosition();
7691 bool IsKnownNoCapture
;
7692 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
7693 A
, this, IRP
, DepClassTy::REQUIRED
, IsKnownNoCapture
);
7694 if (!IsAssumedNoCapture
) {
7695 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7696 return indicatePessimisticFixpoint();
7699 bool IsKnownNoAlias
;
7700 if (!AA::hasAssumedIRAttr
<Attribute::NoAlias
>(
7701 A
, this, IRP
, DepClassTy::REQUIRED
, IsKnownNoAlias
)) {
7702 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7703 return indicatePessimisticFixpoint();
7707 if (!AA::isAssumedReadOnly(A
, IRP
, *this, IsKnown
)) {
7708 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7709 return indicatePessimisticFixpoint();
7712 return ChangeStatus::UNCHANGED
;
7715 /// See AbstractAttribute::trackStatistics()
7716 void trackStatistics() const override
{
7717 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr
);
7721 struct AAPrivatizablePtrCallSiteReturned final
7722 : public AAPrivatizablePtrFloating
{
7723 AAPrivatizablePtrCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
7724 : AAPrivatizablePtrFloating(IRP
, A
) {}
7726 /// See AbstractAttribute::initialize(...).
7727 void initialize(Attributor
&A
) override
{
7728 // TODO: We can privatize more than arguments.
7729 indicatePessimisticFixpoint();
7732 /// See AbstractAttribute::trackStatistics()
7733 void trackStatistics() const override
{
7734 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr
);
7738 struct AAPrivatizablePtrReturned final
: public AAPrivatizablePtrFloating
{
7739 AAPrivatizablePtrReturned(const IRPosition
&IRP
, Attributor
&A
)
7740 : AAPrivatizablePtrFloating(IRP
, A
) {}
7742 /// See AbstractAttribute::initialize(...).
7743 void initialize(Attributor
&A
) override
{
7744 // TODO: We can privatize more than arguments.
7745 indicatePessimisticFixpoint();
7748 /// See AbstractAttribute::trackStatistics()
7749 void trackStatistics() const override
{
7750 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr
);
7755 /// -------------------- Memory Behavior Attributes ----------------------------
7756 /// Includes read-none, read-only, and write-only.
7757 /// ----------------------------------------------------------------------------
7759 struct AAMemoryBehaviorImpl
: public AAMemoryBehavior
{
7760 AAMemoryBehaviorImpl(const IRPosition
&IRP
, Attributor
&A
)
7761 : AAMemoryBehavior(IRP
, A
) {}
7763 /// See AbstractAttribute::initialize(...).
7764 void initialize(Attributor
&A
) override
{
7765 intersectAssumedBits(BEST_STATE
);
7766 getKnownStateFromValue(A
, getIRPosition(), getState());
7767 AAMemoryBehavior::initialize(A
);
7770 /// Return the memory behavior information encoded in the IR for \p IRP.
7771 static void getKnownStateFromValue(Attributor
&A
, const IRPosition
&IRP
,
7772 BitIntegerState
&State
,
7773 bool IgnoreSubsumingPositions
= false) {
7774 SmallVector
<Attribute
, 2> Attrs
;
7775 A
.getAttrs(IRP
, AttrKinds
, Attrs
, IgnoreSubsumingPositions
);
7776 for (const Attribute
&Attr
: Attrs
) {
7777 switch (Attr
.getKindAsEnum()) {
7778 case Attribute::ReadNone
:
7779 State
.addKnownBits(NO_ACCESSES
);
7781 case Attribute::ReadOnly
:
7782 State
.addKnownBits(NO_WRITES
);
7784 case Attribute::WriteOnly
:
7785 State
.addKnownBits(NO_READS
);
7788 llvm_unreachable("Unexpected attribute!");
7792 if (auto *I
= dyn_cast
<Instruction
>(&IRP
.getAnchorValue())) {
7793 if (!I
->mayReadFromMemory())
7794 State
.addKnownBits(NO_READS
);
7795 if (!I
->mayWriteToMemory())
7796 State
.addKnownBits(NO_WRITES
);
7800 /// See AbstractAttribute::getDeducedAttributes(...).
7801 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
7802 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
7803 assert(Attrs
.size() == 0);
7804 if (isAssumedReadNone())
7805 Attrs
.push_back(Attribute::get(Ctx
, Attribute::ReadNone
));
7806 else if (isAssumedReadOnly())
7807 Attrs
.push_back(Attribute::get(Ctx
, Attribute::ReadOnly
));
7808 else if (isAssumedWriteOnly())
7809 Attrs
.push_back(Attribute::get(Ctx
, Attribute::WriteOnly
));
7810 assert(Attrs
.size() <= 1);
7813 /// See AbstractAttribute::manifest(...).
7814 ChangeStatus
manifest(Attributor
&A
) override
{
7815 const IRPosition
&IRP
= getIRPosition();
7817 if (A
.hasAttr(IRP
, Attribute::ReadNone
,
7818 /* IgnoreSubsumingPositions */ true))
7819 return ChangeStatus::UNCHANGED
;
7821 // Check if we would improve the existing attributes first.
7822 SmallVector
<Attribute
, 4> DeducedAttrs
;
7823 getDeducedAttributes(A
, IRP
.getAnchorValue().getContext(), DeducedAttrs
);
7824 if (llvm::all_of(DeducedAttrs
, [&](const Attribute
&Attr
) {
7825 return A
.hasAttr(IRP
, Attr
.getKindAsEnum(),
7826 /* IgnoreSubsumingPositions */ true);
7828 return ChangeStatus::UNCHANGED
;
7830 // Clear existing attributes.
7831 A
.removeAttrs(IRP
, AttrKinds
);
7833 // Use the generic manifest method.
7834 return IRAttribute::manifest(A
);
7837 /// See AbstractState::getAsStr().
7838 const std::string
getAsStr(Attributor
*A
) const override
{
7839 if (isAssumedReadNone())
7841 if (isAssumedReadOnly())
7843 if (isAssumedWriteOnly())
7845 return "may-read/write";
7848 /// The set of IR attributes AAMemoryBehavior deals with.
7849 static const Attribute::AttrKind AttrKinds
[3];
7852 const Attribute::AttrKind
AAMemoryBehaviorImpl::AttrKinds
[] = {
7853 Attribute::ReadNone
, Attribute::ReadOnly
, Attribute::WriteOnly
};
7855 /// Memory behavior attribute for a floating value.
7856 struct AAMemoryBehaviorFloating
: AAMemoryBehaviorImpl
{
7857 AAMemoryBehaviorFloating(const IRPosition
&IRP
, Attributor
&A
)
7858 : AAMemoryBehaviorImpl(IRP
, A
) {}
7860 /// See AbstractAttribute::updateImpl(...).
7861 ChangeStatus
updateImpl(Attributor
&A
) override
;
7863 /// See AbstractAttribute::trackStatistics()
7864 void trackStatistics() const override
{
7865 if (isAssumedReadNone())
7866 STATS_DECLTRACK_FLOATING_ATTR(readnone
)
7867 else if (isAssumedReadOnly())
7868 STATS_DECLTRACK_FLOATING_ATTR(readonly
)
7869 else if (isAssumedWriteOnly())
7870 STATS_DECLTRACK_FLOATING_ATTR(writeonly
)
7874 /// Return true if users of \p UserI might access the underlying
7875 /// variable/location described by \p U and should therefore be analyzed.
7876 bool followUsersOfUseIn(Attributor
&A
, const Use
&U
,
7877 const Instruction
*UserI
);
7879 /// Update the state according to the effect of use \p U in \p UserI.
7880 void analyzeUseIn(Attributor
&A
, const Use
&U
, const Instruction
*UserI
);
7883 /// Memory behavior attribute for function argument.
7884 struct AAMemoryBehaviorArgument
: AAMemoryBehaviorFloating
{
7885 AAMemoryBehaviorArgument(const IRPosition
&IRP
, Attributor
&A
)
7886 : AAMemoryBehaviorFloating(IRP
, A
) {}
7888 /// See AbstractAttribute::initialize(...).
7889 void initialize(Attributor
&A
) override
{
7890 intersectAssumedBits(BEST_STATE
);
7891 const IRPosition
&IRP
= getIRPosition();
7892 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7893 // can query it when we use has/getAttr. That would allow us to reuse the
7894 // initialize of the base class here.
7895 bool HasByVal
= A
.hasAttr(IRP
, {Attribute::ByVal
},
7896 /* IgnoreSubsumingPositions */ true);
7897 getKnownStateFromValue(A
, IRP
, getState(),
7898 /* IgnoreSubsumingPositions */ HasByVal
);
7901 ChangeStatus
manifest(Attributor
&A
) override
{
7902 // TODO: Pointer arguments are not supported on vectors of pointers yet.
7903 if (!getAssociatedValue().getType()->isPointerTy())
7904 return ChangeStatus::UNCHANGED
;
7906 // TODO: From readattrs.ll: "inalloca parameters are always
7907 // considered written"
7908 if (A
.hasAttr(getIRPosition(),
7909 {Attribute::InAlloca
, Attribute::Preallocated
})) {
7910 removeKnownBits(NO_WRITES
);
7911 removeAssumedBits(NO_WRITES
);
7913 A
.removeAttrs(getIRPosition(), AttrKinds
);
7914 return AAMemoryBehaviorFloating::manifest(A
);
7917 /// See AbstractAttribute::trackStatistics()
7918 void trackStatistics() const override
{
7919 if (isAssumedReadNone())
7920 STATS_DECLTRACK_ARG_ATTR(readnone
)
7921 else if (isAssumedReadOnly())
7922 STATS_DECLTRACK_ARG_ATTR(readonly
)
7923 else if (isAssumedWriteOnly())
7924 STATS_DECLTRACK_ARG_ATTR(writeonly
)
7928 struct AAMemoryBehaviorCallSiteArgument final
: AAMemoryBehaviorArgument
{
7929 AAMemoryBehaviorCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
7930 : AAMemoryBehaviorArgument(IRP
, A
) {}
7932 /// See AbstractAttribute::initialize(...).
7933 void initialize(Attributor
&A
) override
{
7934 // If we don't have an associated attribute this is either a variadic call
7935 // or an indirect call, either way, nothing to do here.
7936 Argument
*Arg
= getAssociatedArgument();
7938 indicatePessimisticFixpoint();
7941 if (Arg
->hasByValAttr()) {
7942 addKnownBits(NO_WRITES
);
7943 removeKnownBits(NO_READS
);
7944 removeAssumedBits(NO_READS
);
7946 AAMemoryBehaviorArgument::initialize(A
);
7947 if (getAssociatedFunction()->isDeclaration())
7948 indicatePessimisticFixpoint();
7951 /// See AbstractAttribute::updateImpl(...).
7952 ChangeStatus
updateImpl(Attributor
&A
) override
{
7953 // TODO: Once we have call site specific value information we can provide
7954 // call site specific liveness liveness information and then it makes
7955 // sense to specialize attributes for call sites arguments instead of
7956 // redirecting requests to the callee argument.
7957 Argument
*Arg
= getAssociatedArgument();
7958 const IRPosition
&ArgPos
= IRPosition::argument(*Arg
);
7960 A
.getAAFor
<AAMemoryBehavior
>(*this, ArgPos
, DepClassTy::REQUIRED
);
7962 return indicatePessimisticFixpoint();
7963 return clampStateAndIndicateChange(getState(), ArgAA
->getState());
7966 /// See AbstractAttribute::trackStatistics()
7967 void trackStatistics() const override
{
7968 if (isAssumedReadNone())
7969 STATS_DECLTRACK_CSARG_ATTR(readnone
)
7970 else if (isAssumedReadOnly())
7971 STATS_DECLTRACK_CSARG_ATTR(readonly
)
7972 else if (isAssumedWriteOnly())
7973 STATS_DECLTRACK_CSARG_ATTR(writeonly
)
7977 /// Memory behavior attribute for a call site return position.
7978 struct AAMemoryBehaviorCallSiteReturned final
: AAMemoryBehaviorFloating
{
7979 AAMemoryBehaviorCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
7980 : AAMemoryBehaviorFloating(IRP
, A
) {}
7982 /// See AbstractAttribute::initialize(...).
7983 void initialize(Attributor
&A
) override
{
7984 AAMemoryBehaviorImpl::initialize(A
);
7986 /// See AbstractAttribute::manifest(...).
7987 ChangeStatus
manifest(Attributor
&A
) override
{
7988 // We do not annotate returned values.
7989 return ChangeStatus::UNCHANGED
;
7992 /// See AbstractAttribute::trackStatistics()
7993 void trackStatistics() const override
{}
7996 /// An AA to represent the memory behavior function attributes.
7997 struct AAMemoryBehaviorFunction final
: public AAMemoryBehaviorImpl
{
7998 AAMemoryBehaviorFunction(const IRPosition
&IRP
, Attributor
&A
)
7999 : AAMemoryBehaviorImpl(IRP
, A
) {}
8001 /// See AbstractAttribute::updateImpl(Attributor &A).
8002 ChangeStatus
updateImpl(Attributor
&A
) override
;
8004 /// See AbstractAttribute::manifest(...).
8005 ChangeStatus
manifest(Attributor
&A
) override
{
8006 // TODO: It would be better to merge this with AAMemoryLocation, so that
8007 // we could determine read/write per location. This would also have the
8008 // benefit of only one place trying to manifest the memory attribute.
8009 Function
&F
= cast
<Function
>(getAnchorValue());
8010 MemoryEffects ME
= MemoryEffects::unknown();
8011 if (isAssumedReadNone())
8012 ME
= MemoryEffects::none();
8013 else if (isAssumedReadOnly())
8014 ME
= MemoryEffects::readOnly();
8015 else if (isAssumedWriteOnly())
8016 ME
= MemoryEffects::writeOnly();
8018 A
.removeAttrs(getIRPosition(), AttrKinds
);
8019 return A
.manifestAttrs(getIRPosition(),
8020 Attribute::getWithMemoryEffects(F
.getContext(), ME
));
8023 /// See AbstractAttribute::trackStatistics()
8024 void trackStatistics() const override
{
8025 if (isAssumedReadNone())
8026 STATS_DECLTRACK_FN_ATTR(readnone
)
8027 else if (isAssumedReadOnly())
8028 STATS_DECLTRACK_FN_ATTR(readonly
)
8029 else if (isAssumedWriteOnly())
8030 STATS_DECLTRACK_FN_ATTR(writeonly
)
8034 /// AAMemoryBehavior attribute for call sites.
8035 struct AAMemoryBehaviorCallSite final
8036 : AACalleeToCallSite
<AAMemoryBehavior
, AAMemoryBehaviorImpl
> {
8037 AAMemoryBehaviorCallSite(const IRPosition
&IRP
, Attributor
&A
)
8038 : AACalleeToCallSite
<AAMemoryBehavior
, AAMemoryBehaviorImpl
>(IRP
, A
) {}
8040 /// See AbstractAttribute::manifest(...).
8041 ChangeStatus
manifest(Attributor
&A
) override
{
8042 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8043 CallBase
&CB
= cast
<CallBase
>(getAnchorValue());
8044 MemoryEffects ME
= MemoryEffects::unknown();
8045 if (isAssumedReadNone())
8046 ME
= MemoryEffects::none();
8047 else if (isAssumedReadOnly())
8048 ME
= MemoryEffects::readOnly();
8049 else if (isAssumedWriteOnly())
8050 ME
= MemoryEffects::writeOnly();
8052 A
.removeAttrs(getIRPosition(), AttrKinds
);
8053 return A
.manifestAttrs(
8054 getIRPosition(), Attribute::getWithMemoryEffects(CB
.getContext(), ME
));
8057 /// See AbstractAttribute::trackStatistics()
8058 void trackStatistics() const override
{
8059 if (isAssumedReadNone())
8060 STATS_DECLTRACK_CS_ATTR(readnone
)
8061 else if (isAssumedReadOnly())
8062 STATS_DECLTRACK_CS_ATTR(readonly
)
8063 else if (isAssumedWriteOnly())
8064 STATS_DECLTRACK_CS_ATTR(writeonly
)
8068 ChangeStatus
AAMemoryBehaviorFunction::updateImpl(Attributor
&A
) {
8070 // The current assumed state used to determine a change.
8071 auto AssumedState
= getAssumed();
8073 auto CheckRWInst
= [&](Instruction
&I
) {
8074 // If the instruction has an own memory behavior state, use it to restrict
8075 // the local state. No further analysis is required as the other memory
8076 // state is as optimistic as it gets.
8077 if (const auto *CB
= dyn_cast
<CallBase
>(&I
)) {
8078 const auto *MemBehaviorAA
= A
.getAAFor
<AAMemoryBehavior
>(
8079 *this, IRPosition::callsite_function(*CB
), DepClassTy::REQUIRED
);
8080 if (MemBehaviorAA
) {
8081 intersectAssumedBits(MemBehaviorAA
->getAssumed());
8082 return !isAtFixpoint();
8086 // Remove access kind modifiers if necessary.
8087 if (I
.mayReadFromMemory())
8088 removeAssumedBits(NO_READS
);
8089 if (I
.mayWriteToMemory())
8090 removeAssumedBits(NO_WRITES
);
8091 return !isAtFixpoint();
8094 bool UsedAssumedInformation
= false;
8095 if (!A
.checkForAllReadWriteInstructions(CheckRWInst
, *this,
8096 UsedAssumedInformation
))
8097 return indicatePessimisticFixpoint();
8099 return (AssumedState
!= getAssumed()) ? ChangeStatus::CHANGED
8100 : ChangeStatus::UNCHANGED
;
8103 ChangeStatus
AAMemoryBehaviorFloating::updateImpl(Attributor
&A
) {
8105 const IRPosition
&IRP
= getIRPosition();
8106 const IRPosition
&FnPos
= IRPosition::function_scope(IRP
);
8107 AAMemoryBehavior::StateType
&S
= getState();
8109 // First, check the function scope. We take the known information and we avoid
8110 // work if the assumed information implies the current assumed information for
8111 // this attribute. This is a valid for all but byval arguments.
8112 Argument
*Arg
= IRP
.getAssociatedArgument();
8113 AAMemoryBehavior::base_t FnMemAssumedState
=
8114 AAMemoryBehavior::StateType::getWorstState();
8115 if (!Arg
|| !Arg
->hasByValAttr()) {
8116 const auto *FnMemAA
=
8117 A
.getAAFor
<AAMemoryBehavior
>(*this, FnPos
, DepClassTy::OPTIONAL
);
8119 FnMemAssumedState
= FnMemAA
->getAssumed();
8120 S
.addKnownBits(FnMemAA
->getKnown());
8121 if ((S
.getAssumed() & FnMemAA
->getAssumed()) == S
.getAssumed())
8122 return ChangeStatus::UNCHANGED
;
8126 // The current assumed state used to determine a change.
8127 auto AssumedState
= S
.getAssumed();
8129 // Make sure the value is not captured (except through "return"), if
8130 // it is, any information derived would be irrelevant anyway as we cannot
8131 // check the potential aliases introduced by the capture. However, no need
8132 // to fall back to anythign less optimistic than the function state.
8133 bool IsKnownNoCapture
;
8134 const AANoCapture
*ArgNoCaptureAA
= nullptr;
8135 bool IsAssumedNoCapture
= AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
8136 A
, this, IRP
, DepClassTy::OPTIONAL
, IsKnownNoCapture
, false,
8139 if (!IsAssumedNoCapture
&&
8140 (!ArgNoCaptureAA
|| !ArgNoCaptureAA
->isAssumedNoCaptureMaybeReturned())) {
8141 S
.intersectAssumedBits(FnMemAssumedState
);
8142 return (AssumedState
!= getAssumed()) ? ChangeStatus::CHANGED
8143 : ChangeStatus::UNCHANGED
;
8146 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8147 auto UsePred
= [&](const Use
&U
, bool &Follow
) -> bool {
8148 Instruction
*UserI
= cast
<Instruction
>(U
.getUser());
8149 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U
<< " in " << *UserI
8152 // Droppable users, e.g., llvm::assume does not actually perform any action.
8153 if (UserI
->isDroppable())
8156 // Check if the users of UserI should also be visited.
8157 Follow
= followUsersOfUseIn(A
, U
, UserI
);
8159 // If UserI might touch memory we analyze the use in detail.
8160 if (UserI
->mayReadOrWriteMemory())
8161 analyzeUseIn(A
, U
, UserI
);
8163 return !isAtFixpoint();
8166 if (!A
.checkForAllUses(UsePred
, *this, getAssociatedValue()))
8167 return indicatePessimisticFixpoint();
8169 return (AssumedState
!= getAssumed()) ? ChangeStatus::CHANGED
8170 : ChangeStatus::UNCHANGED
;
8173 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor
&A
, const Use
&U
,
8174 const Instruction
*UserI
) {
8175 // The loaded value is unrelated to the pointer argument, no need to
8176 // follow the users of the load.
8177 if (isa
<LoadInst
>(UserI
) || isa
<ReturnInst
>(UserI
))
8180 // By default we follow all uses assuming UserI might leak information on U,
8181 // we have special handling for call sites operands though.
8182 const auto *CB
= dyn_cast
<CallBase
>(UserI
);
8183 if (!CB
|| !CB
->isArgOperand(&U
))
8186 // If the use is a call argument known not to be captured, the users of
8187 // the call do not need to be visited because they have to be unrelated to
8188 // the input. Note that this check is not trivial even though we disallow
8189 // general capturing of the underlying argument. The reason is that the
8190 // call might the argument "through return", which we allow and for which we
8191 // need to check call users.
8192 if (U
.get()->getType()->isPointerTy()) {
8193 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
8194 bool IsKnownNoCapture
;
8195 return !AA::hasAssumedIRAttr
<Attribute::NoCapture
>(
8196 A
, this, IRPosition::callsite_argument(*CB
, ArgNo
),
8197 DepClassTy::OPTIONAL
, IsKnownNoCapture
);
8203 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor
&A
, const Use
&U
,
8204 const Instruction
*UserI
) {
8205 assert(UserI
->mayReadOrWriteMemory());
8207 switch (UserI
->getOpcode()) {
8209 // TODO: Handle all atomics and other side-effect operations we know of.
8211 case Instruction::Load
:
8212 // Loads cause the NO_READS property to disappear.
8213 removeAssumedBits(NO_READS
);
8216 case Instruction::Store
:
8217 // Stores cause the NO_WRITES property to disappear if the use is the
8218 // pointer operand. Note that while capturing was taken care of somewhere
8219 // else we need to deal with stores of the value that is not looked through.
8220 if (cast
<StoreInst
>(UserI
)->getPointerOperand() == U
.get())
8221 removeAssumedBits(NO_WRITES
);
8223 indicatePessimisticFixpoint();
8226 case Instruction::Call
:
8227 case Instruction::CallBr
:
8228 case Instruction::Invoke
: {
8229 // For call sites we look at the argument memory behavior attribute (this
8230 // could be recursive!) in order to restrict our own state.
8231 const auto *CB
= cast
<CallBase
>(UserI
);
8233 // Give up on operand bundles.
8234 if (CB
->isBundleOperand(&U
)) {
8235 indicatePessimisticFixpoint();
8239 // Calling a function does read the function pointer, maybe write it if the
8240 // function is self-modifying.
8241 if (CB
->isCallee(&U
)) {
8242 removeAssumedBits(NO_READS
);
8246 // Adjust the possible access behavior based on the information on the
8249 if (U
.get()->getType()->isPointerTy())
8250 Pos
= IRPosition::callsite_argument(*CB
, CB
->getArgOperandNo(&U
));
8252 Pos
= IRPosition::callsite_function(*CB
);
8253 const auto *MemBehaviorAA
=
8254 A
.getAAFor
<AAMemoryBehavior
>(*this, Pos
, DepClassTy::OPTIONAL
);
8257 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8258 // and at least "known".
8259 intersectAssumedBits(MemBehaviorAA
->getAssumed());
8264 // Generally, look at the "may-properties" and adjust the assumed state if we
8265 // did not trigger special handling before.
8266 if (UserI
->mayReadFromMemory())
8267 removeAssumedBits(NO_READS
);
8268 if (UserI
->mayWriteToMemory())
8269 removeAssumedBits(NO_WRITES
);
8273 /// -------------------- Memory Locations Attributes ---------------------------
8274 /// Includes read-none, argmemonly, inaccessiblememonly,
8275 /// inaccessiblememorargmemonly
8276 /// ----------------------------------------------------------------------------
8278 std::string
AAMemoryLocation::getMemoryLocationsAsStr(
8279 AAMemoryLocation::MemoryLocationsKind MLK
) {
8280 if (0 == (MLK
& AAMemoryLocation::NO_LOCATIONS
))
8281 return "all memory";
8282 if (MLK
== AAMemoryLocation::NO_LOCATIONS
)
8284 std::string S
= "memory:";
8285 if (0 == (MLK
& AAMemoryLocation::NO_LOCAL_MEM
))
8287 if (0 == (MLK
& AAMemoryLocation::NO_CONST_MEM
))
8289 if (0 == (MLK
& AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM
))
8290 S
+= "internal global,";
8291 if (0 == (MLK
& AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM
))
8292 S
+= "external global,";
8293 if (0 == (MLK
& AAMemoryLocation::NO_ARGUMENT_MEM
))
8295 if (0 == (MLK
& AAMemoryLocation::NO_INACCESSIBLE_MEM
))
8296 S
+= "inaccessible,";
8297 if (0 == (MLK
& AAMemoryLocation::NO_MALLOCED_MEM
))
8299 if (0 == (MLK
& AAMemoryLocation::NO_UNKOWN_MEM
))
8306 struct AAMemoryLocationImpl
: public AAMemoryLocation
{
8308 AAMemoryLocationImpl(const IRPosition
&IRP
, Attributor
&A
)
8309 : AAMemoryLocation(IRP
, A
), Allocator(A
.Allocator
) {
8310 AccessKind2Accesses
.fill(nullptr);
8313 ~AAMemoryLocationImpl() {
8314 // The AccessSets are allocated via a BumpPtrAllocator, we call
8315 // the destructor manually.
8316 for (AccessSet
*AS
: AccessKind2Accesses
)
8321 /// See AbstractAttribute::initialize(...).
8322 void initialize(Attributor
&A
) override
{
8323 intersectAssumedBits(BEST_STATE
);
8324 getKnownStateFromValue(A
, getIRPosition(), getState());
8325 AAMemoryLocation::initialize(A
);
8328 /// Return the memory behavior information encoded in the IR for \p IRP.
8329 static void getKnownStateFromValue(Attributor
&A
, const IRPosition
&IRP
,
8330 BitIntegerState
&State
,
8331 bool IgnoreSubsumingPositions
= false) {
8332 // For internal functions we ignore `argmemonly` and
8333 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8334 // constant propagation. It is unclear if this is the best way but it is
8335 // unlikely this will cause real performance problems. If we are deriving
8336 // attributes for the anchor function we even remove the attribute in
8337 // addition to ignoring it.
8338 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8339 // MemoryEffects::Other as a possible location.
8340 bool UseArgMemOnly
= true;
8341 Function
*AnchorFn
= IRP
.getAnchorScope();
8342 if (AnchorFn
&& A
.isRunOn(*AnchorFn
))
8343 UseArgMemOnly
= !AnchorFn
->hasLocalLinkage();
8345 SmallVector
<Attribute
, 2> Attrs
;
8346 A
.getAttrs(IRP
, {Attribute::Memory
}, Attrs
, IgnoreSubsumingPositions
);
8347 for (const Attribute
&Attr
: Attrs
) {
8348 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8349 MemoryEffects ME
= Attr
.getMemoryEffects();
8350 if (ME
.doesNotAccessMemory()) {
8351 State
.addKnownBits(NO_LOCAL_MEM
| NO_CONST_MEM
);
8354 if (ME
.onlyAccessesInaccessibleMem()) {
8355 State
.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM
, true, true));
8358 if (ME
.onlyAccessesArgPointees()) {
8360 State
.addKnownBits(inverseLocation(NO_ARGUMENT_MEM
, true, true));
8362 // Remove location information, only keep read/write info.
8363 ME
= MemoryEffects(ME
.getModRef());
8364 A
.manifestAttrs(IRP
,
8365 Attribute::getWithMemoryEffects(
8366 IRP
.getAnchorValue().getContext(), ME
),
8367 /*ForceReplace*/ true);
8371 if (ME
.onlyAccessesInaccessibleOrArgMem()) {
8373 State
.addKnownBits(inverseLocation(
8374 NO_INACCESSIBLE_MEM
| NO_ARGUMENT_MEM
, true, true));
8376 // Remove location information, only keep read/write info.
8377 ME
= MemoryEffects(ME
.getModRef());
8378 A
.manifestAttrs(IRP
,
8379 Attribute::getWithMemoryEffects(
8380 IRP
.getAnchorValue().getContext(), ME
),
8381 /*ForceReplace*/ true);
8388 /// See AbstractAttribute::getDeducedAttributes(...).
8389 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
8390 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
8391 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8392 assert(Attrs
.size() == 0);
8393 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION
) {
8394 if (isAssumedReadNone())
8396 Attribute::getWithMemoryEffects(Ctx
, MemoryEffects::none()));
8397 else if (isAssumedInaccessibleMemOnly())
8398 Attrs
.push_back(Attribute::getWithMemoryEffects(
8399 Ctx
, MemoryEffects::inaccessibleMemOnly()));
8400 else if (isAssumedArgMemOnly())
8402 Attribute::getWithMemoryEffects(Ctx
, MemoryEffects::argMemOnly()));
8403 else if (isAssumedInaccessibleOrArgMemOnly())
8404 Attrs
.push_back(Attribute::getWithMemoryEffects(
8405 Ctx
, MemoryEffects::inaccessibleOrArgMemOnly()));
8407 assert(Attrs
.size() <= 1);
8410 /// See AbstractAttribute::manifest(...).
8411 ChangeStatus
manifest(Attributor
&A
) override
{
8412 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8413 // provide per-location modref information here.
8414 const IRPosition
&IRP
= getIRPosition();
8416 SmallVector
<Attribute
, 1> DeducedAttrs
;
8417 getDeducedAttributes(A
, IRP
.getAnchorValue().getContext(), DeducedAttrs
);
8418 if (DeducedAttrs
.size() != 1)
8419 return ChangeStatus::UNCHANGED
;
8420 MemoryEffects ME
= DeducedAttrs
[0].getMemoryEffects();
8422 return A
.manifestAttrs(IRP
, Attribute::getWithMemoryEffects(
8423 IRP
.getAnchorValue().getContext(), ME
));
8426 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8427 bool checkForAllAccessesToMemoryKind(
8428 function_ref
<bool(const Instruction
*, const Value
*, AccessKind
,
8429 MemoryLocationsKind
)>
8431 MemoryLocationsKind RequestedMLK
) const override
{
8432 if (!isValidState())
8435 MemoryLocationsKind AssumedMLK
= getAssumedNotAccessedLocation();
8436 if (AssumedMLK
== NO_LOCATIONS
)
8440 for (MemoryLocationsKind CurMLK
= 1; CurMLK
< NO_LOCATIONS
;
8441 CurMLK
*= 2, ++Idx
) {
8442 if (CurMLK
& RequestedMLK
)
8445 if (const AccessSet
*Accesses
= AccessKind2Accesses
[Idx
])
8446 for (const AccessInfo
&AI
: *Accesses
)
8447 if (!Pred(AI
.I
, AI
.Ptr
, AI
.Kind
, CurMLK
))
8454 ChangeStatus
indicatePessimisticFixpoint() override
{
8455 // If we give up and indicate a pessimistic fixpoint this instruction will
8456 // become an access for all potential access kinds:
8457 // TODO: Add pointers for argmemonly and globals to improve the results of
8458 // checkForAllAccessesToMemoryKind.
8459 bool Changed
= false;
8460 MemoryLocationsKind KnownMLK
= getKnown();
8461 Instruction
*I
= dyn_cast
<Instruction
>(&getAssociatedValue());
8462 for (MemoryLocationsKind CurMLK
= 1; CurMLK
< NO_LOCATIONS
; CurMLK
*= 2)
8463 if (!(CurMLK
& KnownMLK
))
8464 updateStateAndAccessesMap(getState(), CurMLK
, I
, nullptr, Changed
,
8465 getAccessKindFromInst(I
));
8466 return AAMemoryLocation::indicatePessimisticFixpoint();
8470 /// Helper struct to tie together an instruction that has a read or write
8471 /// effect with the pointer it accesses (if any).
8474 /// The instruction that caused the access.
8475 const Instruction
*I
;
8477 /// The base pointer that is accessed, or null if unknown.
8480 /// The kind of access (read/write/read+write).
8483 bool operator==(const AccessInfo
&RHS
) const {
8484 return I
== RHS
.I
&& Ptr
== RHS
.Ptr
&& Kind
== RHS
.Kind
;
8486 bool operator()(const AccessInfo
&LHS
, const AccessInfo
&RHS
) const {
8488 return LHS
.I
< RHS
.I
;
8489 if (LHS
.Ptr
!= RHS
.Ptr
)
8490 return LHS
.Ptr
< RHS
.Ptr
;
8491 if (LHS
.Kind
!= RHS
.Kind
)
8492 return LHS
.Kind
< RHS
.Kind
;
8497 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8498 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8499 using AccessSet
= SmallSet
<AccessInfo
, 2, AccessInfo
>;
8500 std::array
<AccessSet
*, llvm::CTLog2
<VALID_STATE
>()> AccessKind2Accesses
;
8502 /// Categorize the pointer arguments of CB that might access memory in
8503 /// AccessedLoc and update the state and access map accordingly.
8505 categorizeArgumentPointerLocations(Attributor
&A
, CallBase
&CB
,
8506 AAMemoryLocation::StateType
&AccessedLocs
,
8509 /// Return the kind(s) of location that may be accessed by \p V.
8510 AAMemoryLocation::MemoryLocationsKind
8511 categorizeAccessedLocations(Attributor
&A
, Instruction
&I
, bool &Changed
);
8513 /// Return the access kind as determined by \p I.
8514 AccessKind
getAccessKindFromInst(const Instruction
*I
) {
8515 AccessKind AK
= READ_WRITE
;
8517 AK
= I
->mayReadFromMemory() ? READ
: NONE
;
8518 AK
= AccessKind(AK
| (I
->mayWriteToMemory() ? WRITE
: NONE
));
8523 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8524 /// an access of kind \p AK to a \p MLK memory location with the access
8526 void updateStateAndAccessesMap(AAMemoryLocation::StateType
&State
,
8527 MemoryLocationsKind MLK
, const Instruction
*I
,
8528 const Value
*Ptr
, bool &Changed
,
8529 AccessKind AK
= READ_WRITE
) {
8531 assert(isPowerOf2_32(MLK
) && "Expected a single location set!");
8532 auto *&Accesses
= AccessKind2Accesses
[llvm::Log2_32(MLK
)];
8534 Accesses
= new (Allocator
) AccessSet();
8535 Changed
|= Accesses
->insert(AccessInfo
{I
, Ptr
, AK
}).second
;
8536 if (MLK
== NO_UNKOWN_MEM
)
8538 State
.removeAssumedBits(MLK
);
8541 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8542 /// arguments, and update the state and access map accordingly.
8543 void categorizePtrValue(Attributor
&A
, const Instruction
&I
, const Value
&Ptr
,
8544 AAMemoryLocation::StateType
&State
, bool &Changed
,
8545 unsigned AccessAS
= 0);
8547 /// Used to allocate access sets.
8548 BumpPtrAllocator
&Allocator
;
8551 void AAMemoryLocationImpl::categorizePtrValue(
8552 Attributor
&A
, const Instruction
&I
, const Value
&Ptr
,
8553 AAMemoryLocation::StateType
&State
, bool &Changed
, unsigned AccessAS
) {
8554 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8556 << getMemoryLocationsAsStr(State
.getAssumed()) << "]\n");
8558 auto Pred
= [&](Value
&Obj
) {
8559 unsigned ObjectAS
= Obj
.getType()->getPointerAddressSpace();
8560 // TODO: recognize the TBAA used for constant accesses.
8561 MemoryLocationsKind MLK
= NO_LOCATIONS
;
8563 // Filter accesses to constant (GPU) memory if we have an AS at the access
8564 // site or the object is known to actually have the associated AS.
8565 if ((AccessAS
== (unsigned)AA::GPUAddressSpace::Constant
||
8566 (ObjectAS
== (unsigned)AA::GPUAddressSpace::Constant
&&
8567 isIdentifiedObject(&Obj
))) &&
8568 AA::isGPU(*I
.getModule()))
8571 if (isa
<UndefValue
>(&Obj
))
8573 if (isa
<Argument
>(&Obj
)) {
8574 // TODO: For now we do not treat byval arguments as local copies performed
8575 // on the call edge, though, we should. To make that happen we need to
8576 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8577 // would also allow us to mark functions only accessing byval arguments as
8578 // readnone again, arguably their accesses have no effect outside of the
8579 // function, like accesses to allocas.
8580 MLK
= NO_ARGUMENT_MEM
;
8581 } else if (auto *GV
= dyn_cast
<GlobalValue
>(&Obj
)) {
8582 // Reading constant memory is not treated as a read "effect" by the
8583 // function attr pass so we won't neither. Constants defined by TBAA are
8584 // similar. (We know we do not write it because it is constant.)
8585 if (auto *GVar
= dyn_cast
<GlobalVariable
>(GV
))
8586 if (GVar
->isConstant())
8589 if (GV
->hasLocalLinkage())
8590 MLK
= NO_GLOBAL_INTERNAL_MEM
;
8592 MLK
= NO_GLOBAL_EXTERNAL_MEM
;
8593 } else if (isa
<ConstantPointerNull
>(&Obj
) &&
8594 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS
) ||
8595 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS
))) {
8597 } else if (isa
<AllocaInst
>(&Obj
)) {
8599 } else if (const auto *CB
= dyn_cast
<CallBase
>(&Obj
)) {
8600 bool IsKnownNoAlias
;
8601 if (AA::hasAssumedIRAttr
<Attribute::NoAlias
>(
8602 A
, this, IRPosition::callsite_returned(*CB
), DepClassTy::OPTIONAL
,
8604 MLK
= NO_MALLOCED_MEM
;
8606 MLK
= NO_UNKOWN_MEM
;
8608 MLK
= NO_UNKOWN_MEM
;
8611 assert(MLK
!= NO_LOCATIONS
&& "No location specified!");
8612 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8613 << Obj
<< " -> " << getMemoryLocationsAsStr(MLK
) << "\n");
8614 updateStateAndAccessesMap(State
, MLK
, &I
, &Obj
, Changed
,
8615 getAccessKindFromInst(&I
));
8620 const auto *AA
= A
.getAAFor
<AAUnderlyingObjects
>(
8621 *this, IRPosition::value(Ptr
), DepClassTy::OPTIONAL
);
8622 if (!AA
|| !AA
->forallUnderlyingObjects(Pred
, AA::Intraprocedural
)) {
8624 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8625 updateStateAndAccessesMap(State
, NO_UNKOWN_MEM
, &I
, nullptr, Changed
,
8626 getAccessKindFromInst(&I
));
8631 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8632 << getMemoryLocationsAsStr(State
.getAssumed()) << "\n");
8635 void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8636 Attributor
&A
, CallBase
&CB
, AAMemoryLocation::StateType
&AccessedLocs
,
8638 for (unsigned ArgNo
= 0, E
= CB
.arg_size(); ArgNo
< E
; ++ArgNo
) {
8640 // Skip non-pointer arguments.
8641 const Value
*ArgOp
= CB
.getArgOperand(ArgNo
);
8642 if (!ArgOp
->getType()->isPtrOrPtrVectorTy())
8645 // Skip readnone arguments.
8646 const IRPosition
&ArgOpIRP
= IRPosition::callsite_argument(CB
, ArgNo
);
8647 const auto *ArgOpMemLocationAA
=
8648 A
.getAAFor
<AAMemoryBehavior
>(*this, ArgOpIRP
, DepClassTy::OPTIONAL
);
8650 if (ArgOpMemLocationAA
&& ArgOpMemLocationAA
->isAssumedReadNone())
8653 // Categorize potentially accessed pointer arguments as if there was an
8654 // access instruction with them as pointer.
8655 categorizePtrValue(A
, CB
, *ArgOp
, AccessedLocs
, Changed
);
8659 AAMemoryLocation::MemoryLocationsKind
8660 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor
&A
, Instruction
&I
,
8662 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8665 AAMemoryLocation::StateType AccessedLocs
;
8666 AccessedLocs
.intersectAssumedBits(NO_LOCATIONS
);
8668 if (auto *CB
= dyn_cast
<CallBase
>(&I
)) {
8670 // First check if we assume any memory is access is visible.
8671 const auto *CBMemLocationAA
= A
.getAAFor
<AAMemoryLocation
>(
8672 *this, IRPosition::callsite_function(*CB
), DepClassTy::OPTIONAL
);
8673 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8674 << " [" << CBMemLocationAA
<< "]\n");
8675 if (!CBMemLocationAA
) {
8676 updateStateAndAccessesMap(AccessedLocs
, NO_UNKOWN_MEM
, &I
, nullptr,
8677 Changed
, getAccessKindFromInst(&I
));
8678 return NO_UNKOWN_MEM
;
8681 if (CBMemLocationAA
->isAssumedReadNone())
8682 return NO_LOCATIONS
;
8684 if (CBMemLocationAA
->isAssumedInaccessibleMemOnly()) {
8685 updateStateAndAccessesMap(AccessedLocs
, NO_INACCESSIBLE_MEM
, &I
, nullptr,
8686 Changed
, getAccessKindFromInst(&I
));
8687 return AccessedLocs
.getAssumed();
8690 uint32_t CBAssumedNotAccessedLocs
=
8691 CBMemLocationAA
->getAssumedNotAccessedLocation();
8693 // Set the argmemonly and global bit as we handle them separately below.
8694 uint32_t CBAssumedNotAccessedLocsNoArgMem
=
8695 CBAssumedNotAccessedLocs
| NO_ARGUMENT_MEM
| NO_GLOBAL_MEM
;
8697 for (MemoryLocationsKind CurMLK
= 1; CurMLK
< NO_LOCATIONS
; CurMLK
*= 2) {
8698 if (CBAssumedNotAccessedLocsNoArgMem
& CurMLK
)
8700 updateStateAndAccessesMap(AccessedLocs
, CurMLK
, &I
, nullptr, Changed
,
8701 getAccessKindFromInst(&I
));
8704 // Now handle global memory if it might be accessed. This is slightly tricky
8705 // as NO_GLOBAL_MEM has multiple bits set.
8706 bool HasGlobalAccesses
= ((~CBAssumedNotAccessedLocs
) & NO_GLOBAL_MEM
);
8707 if (HasGlobalAccesses
) {
8708 auto AccessPred
= [&](const Instruction
*, const Value
*Ptr
,
8709 AccessKind Kind
, MemoryLocationsKind MLK
) {
8710 updateStateAndAccessesMap(AccessedLocs
, MLK
, &I
, Ptr
, Changed
,
8711 getAccessKindFromInst(&I
));
8714 if (!CBMemLocationAA
->checkForAllAccessesToMemoryKind(
8715 AccessPred
, inverseLocation(NO_GLOBAL_MEM
, false, false)))
8716 return AccessedLocs
.getWorstState();
8720 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8721 << getMemoryLocationsAsStr(AccessedLocs
.getAssumed()) << "\n");
8723 // Now handle argument memory if it might be accessed.
8724 bool HasArgAccesses
= ((~CBAssumedNotAccessedLocs
) & NO_ARGUMENT_MEM
);
8726 categorizeArgumentPointerLocations(A
, *CB
, AccessedLocs
, Changed
);
8729 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8730 << getMemoryLocationsAsStr(AccessedLocs
.getAssumed()) << "\n");
8732 return AccessedLocs
.getAssumed();
8735 if (const Value
*Ptr
= getPointerOperand(&I
, /* AllowVolatile */ true)) {
8737 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8738 << I
<< " [" << *Ptr
<< "]\n");
8739 categorizePtrValue(A
, I
, *Ptr
, AccessedLocs
, Changed
,
8740 Ptr
->getType()->getPointerAddressSpace());
8741 return AccessedLocs
.getAssumed();
8744 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8746 updateStateAndAccessesMap(AccessedLocs
, NO_UNKOWN_MEM
, &I
, nullptr, Changed
,
8747 getAccessKindFromInst(&I
));
8748 return AccessedLocs
.getAssumed();
8751 /// An AA to represent the memory behavior function attributes.
8752 struct AAMemoryLocationFunction final
: public AAMemoryLocationImpl
{
8753 AAMemoryLocationFunction(const IRPosition
&IRP
, Attributor
&A
)
8754 : AAMemoryLocationImpl(IRP
, A
) {}
8756 /// See AbstractAttribute::updateImpl(Attributor &A).
8757 ChangeStatus
updateImpl(Attributor
&A
) override
{
8759 const auto *MemBehaviorAA
=
8760 A
.getAAFor
<AAMemoryBehavior
>(*this, getIRPosition(), DepClassTy::NONE
);
8761 if (MemBehaviorAA
&& MemBehaviorAA
->isAssumedReadNone()) {
8762 if (MemBehaviorAA
->isKnownReadNone())
8763 return indicateOptimisticFixpoint();
8764 assert(isAssumedReadNone() &&
8765 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8766 A
.recordDependence(*MemBehaviorAA
, *this, DepClassTy::OPTIONAL
);
8767 return ChangeStatus::UNCHANGED
;
8770 // The current assumed state used to determine a change.
8771 auto AssumedState
= getAssumed();
8772 bool Changed
= false;
8774 auto CheckRWInst
= [&](Instruction
&I
) {
8775 MemoryLocationsKind MLK
= categorizeAccessedLocations(A
, I
, Changed
);
8776 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8777 << ": " << getMemoryLocationsAsStr(MLK
) << "\n");
8778 removeAssumedBits(inverseLocation(MLK
, false, false));
8779 // Stop once only the valid bit set in the *not assumed location*, thus
8780 // once we don't actually exclude any memory locations in the state.
8781 return getAssumedNotAccessedLocation() != VALID_STATE
;
8784 bool UsedAssumedInformation
= false;
8785 if (!A
.checkForAllReadWriteInstructions(CheckRWInst
, *this,
8786 UsedAssumedInformation
))
8787 return indicatePessimisticFixpoint();
8789 Changed
|= AssumedState
!= getAssumed();
8790 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
8793 /// See AbstractAttribute::trackStatistics()
8794 void trackStatistics() const override
{
8795 if (isAssumedReadNone())
8796 STATS_DECLTRACK_FN_ATTR(readnone
)
8797 else if (isAssumedArgMemOnly())
8798 STATS_DECLTRACK_FN_ATTR(argmemonly
)
8799 else if (isAssumedInaccessibleMemOnly())
8800 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly
)
8801 else if (isAssumedInaccessibleOrArgMemOnly())
8802 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly
)
8806 /// AAMemoryLocation attribute for call sites.
8807 struct AAMemoryLocationCallSite final
: AAMemoryLocationImpl
{
8808 AAMemoryLocationCallSite(const IRPosition
&IRP
, Attributor
&A
)
8809 : AAMemoryLocationImpl(IRP
, A
) {}
8811 /// See AbstractAttribute::updateImpl(...).
8812 ChangeStatus
updateImpl(Attributor
&A
) override
{
8813 // TODO: Once we have call site specific value information we can provide
8814 // call site specific liveness liveness information and then it makes
8815 // sense to specialize attributes for call sites arguments instead of
8816 // redirecting requests to the callee argument.
8817 Function
*F
= getAssociatedFunction();
8818 const IRPosition
&FnPos
= IRPosition::function(*F
);
8820 A
.getAAFor
<AAMemoryLocation
>(*this, FnPos
, DepClassTy::REQUIRED
);
8822 return indicatePessimisticFixpoint();
8823 bool Changed
= false;
8824 auto AccessPred
= [&](const Instruction
*I
, const Value
*Ptr
,
8825 AccessKind Kind
, MemoryLocationsKind MLK
) {
8826 updateStateAndAccessesMap(getState(), MLK
, I
, Ptr
, Changed
,
8827 getAccessKindFromInst(I
));
8830 if (!FnAA
->checkForAllAccessesToMemoryKind(AccessPred
, ALL_LOCATIONS
))
8831 return indicatePessimisticFixpoint();
8832 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
8835 /// See AbstractAttribute::trackStatistics()
8836 void trackStatistics() const override
{
8837 if (isAssumedReadNone())
8838 STATS_DECLTRACK_CS_ATTR(readnone
)
8843 /// ------------------ denormal-fp-math Attribute -------------------------
8846 struct AADenormalFPMathImpl
: public AADenormalFPMath
{
8847 AADenormalFPMathImpl(const IRPosition
&IRP
, Attributor
&A
)
8848 : AADenormalFPMath(IRP
, A
) {}
8850 const std::string
getAsStr(Attributor
*A
) const override
{
8851 std::string
Str("AADenormalFPMath[");
8852 raw_string_ostream
OS(Str
);
8854 DenormalState Known
= getKnown();
8855 if (Known
.Mode
.isValid())
8856 OS
<< "denormal-fp-math=" << Known
.Mode
;
8860 if (Known
.ModeF32
.isValid())
8861 OS
<< " denormal-fp-math-f32=" << Known
.ModeF32
;
8867 struct AADenormalFPMathFunction final
: AADenormalFPMathImpl
{
8868 AADenormalFPMathFunction(const IRPosition
&IRP
, Attributor
&A
)
8869 : AADenormalFPMathImpl(IRP
, A
) {}
8871 void initialize(Attributor
&A
) override
{
8872 const Function
*F
= getAnchorScope();
8873 DenormalMode Mode
= F
->getDenormalModeRaw();
8874 DenormalMode ModeF32
= F
->getDenormalModeF32Raw();
8876 // TODO: Handling this here prevents handling the case where a callee has a
8877 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8878 // a function with a fully fixed mode.
8879 if (ModeF32
== DenormalMode::getInvalid())
8881 Known
= DenormalState
{Mode
, ModeF32
};
8886 ChangeStatus
updateImpl(Attributor
&A
) override
{
8887 ChangeStatus Change
= ChangeStatus::UNCHANGED
;
8889 auto CheckCallSite
= [=, &Change
, &A
](AbstractCallSite CS
) {
8890 Function
*Caller
= CS
.getInstruction()->getFunction();
8891 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller
->getName()
8892 << "->" << getAssociatedFunction()->getName() << '\n');
8894 const auto *CallerInfo
= A
.getAAFor
<AADenormalFPMath
>(
8895 *this, IRPosition::function(*Caller
), DepClassTy::REQUIRED
);
8899 Change
= Change
| clampStateAndIndicateChange(this->getState(),
8900 CallerInfo
->getState());
8904 bool AllCallSitesKnown
= true;
8905 if (!A
.checkForAllCallSites(CheckCallSite
, *this, true, AllCallSitesKnown
))
8906 return indicatePessimisticFixpoint();
8908 if (Change
== ChangeStatus::CHANGED
&& isModeFixed())
8913 ChangeStatus
manifest(Attributor
&A
) override
{
8914 LLVMContext
&Ctx
= getAssociatedFunction()->getContext();
8916 SmallVector
<Attribute
, 2> AttrToAdd
;
8917 SmallVector
<StringRef
, 2> AttrToRemove
;
8918 if (Known
.Mode
== DenormalMode::getDefault()) {
8919 AttrToRemove
.push_back("denormal-fp-math");
8921 AttrToAdd
.push_back(
8922 Attribute::get(Ctx
, "denormal-fp-math", Known
.Mode
.str()));
8925 if (Known
.ModeF32
!= Known
.Mode
) {
8926 AttrToAdd
.push_back(
8927 Attribute::get(Ctx
, "denormal-fp-math-f32", Known
.ModeF32
.str()));
8929 AttrToRemove
.push_back("denormal-fp-math-f32");
8932 auto &IRP
= getIRPosition();
8934 // TODO: There should be a combined add and remove API.
8935 return A
.removeAttrs(IRP
, AttrToRemove
) |
8936 A
.manifestAttrs(IRP
, AttrToAdd
, /*ForceReplace=*/true);
8939 void trackStatistics() const override
{
8940 STATS_DECLTRACK_FN_ATTR(denormal_fp_math
)
8945 /// ------------------ Value Constant Range Attribute -------------------------
8948 struct AAValueConstantRangeImpl
: AAValueConstantRange
{
8949 using StateType
= IntegerRangeState
;
8950 AAValueConstantRangeImpl(const IRPosition
&IRP
, Attributor
&A
)
8951 : AAValueConstantRange(IRP
, A
) {}
8953 /// See AbstractAttribute::initialize(..).
8954 void initialize(Attributor
&A
) override
{
8955 if (A
.hasSimplificationCallback(getIRPosition())) {
8956 indicatePessimisticFixpoint();
8960 // Intersect a range given by SCEV.
8961 intersectKnown(getConstantRangeFromSCEV(A
, getCtxI()));
8963 // Intersect a range given by LVI.
8964 intersectKnown(getConstantRangeFromLVI(A
, getCtxI()));
8967 /// See AbstractAttribute::getAsStr().
8968 const std::string
getAsStr(Attributor
*A
) const override
{
8970 llvm::raw_string_ostream
OS(Str
);
8971 OS
<< "range(" << getBitWidth() << ")<";
8972 getKnown().print(OS
);
8974 getAssumed().print(OS
);
8979 /// Helper function to get a SCEV expr for the associated value at program
8981 const SCEV
*getSCEV(Attributor
&A
, const Instruction
*I
= nullptr) const {
8982 if (!getAnchorScope())
8985 ScalarEvolution
*SE
=
8986 A
.getInfoCache().getAnalysisResultForFunction
<ScalarEvolutionAnalysis
>(
8989 LoopInfo
*LI
= A
.getInfoCache().getAnalysisResultForFunction
<LoopAnalysis
>(
8995 const SCEV
*S
= SE
->getSCEV(&getAssociatedValue());
8999 return SE
->getSCEVAtScope(S
, LI
->getLoopFor(I
->getParent()));
9002 /// Helper function to get a range from SCEV for the associated value at
9003 /// program point \p I.
9004 ConstantRange
getConstantRangeFromSCEV(Attributor
&A
,
9005 const Instruction
*I
= nullptr) const {
9006 if (!getAnchorScope())
9007 return getWorstState(getBitWidth());
9009 ScalarEvolution
*SE
=
9010 A
.getInfoCache().getAnalysisResultForFunction
<ScalarEvolutionAnalysis
>(
9013 const SCEV
*S
= getSCEV(A
, I
);
9015 return getWorstState(getBitWidth());
9017 return SE
->getUnsignedRange(S
);
9020 /// Helper function to get a range from LVI for the associated value at
9021 /// program point \p I.
9023 getConstantRangeFromLVI(Attributor
&A
,
9024 const Instruction
*CtxI
= nullptr) const {
9025 if (!getAnchorScope())
9026 return getWorstState(getBitWidth());
9028 LazyValueInfo
*LVI
=
9029 A
.getInfoCache().getAnalysisResultForFunction
<LazyValueAnalysis
>(
9033 return getWorstState(getBitWidth());
9034 return LVI
->getConstantRange(&getAssociatedValue(),
9035 const_cast<Instruction
*>(CtxI
));
9038 /// Return true if \p CtxI is valid for querying outside analyses.
9039 /// This basically makes sure we do not ask intra-procedural analysis
9040 /// about a context in the wrong function or a context that violates
9041 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9042 /// if the original context of this AA is OK or should be considered invalid.
9043 bool isValidCtxInstructionForOutsideAnalysis(Attributor
&A
,
9044 const Instruction
*CtxI
,
9045 bool AllowAACtxI
) const {
9046 if (!CtxI
|| (!AllowAACtxI
&& CtxI
== getCtxI()))
9049 // Our context might be in a different function, neither intra-procedural
9050 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9051 if (!AA::isValidInScope(getAssociatedValue(), CtxI
->getFunction()))
9054 // If the context is not dominated by the value there are paths to the
9055 // context that do not define the value. This cannot be handled by
9056 // LazyValueInfo so we need to bail.
9057 if (auto *I
= dyn_cast
<Instruction
>(&getAssociatedValue())) {
9058 InformationCache
&InfoCache
= A
.getInfoCache();
9059 const DominatorTree
*DT
=
9060 InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(
9062 return DT
&& DT
->dominates(I
, CtxI
);
9068 /// See AAValueConstantRange::getKnownConstantRange(..).
9070 getKnownConstantRange(Attributor
&A
,
9071 const Instruction
*CtxI
= nullptr) const override
{
9072 if (!isValidCtxInstructionForOutsideAnalysis(A
, CtxI
,
9073 /* AllowAACtxI */ false))
9076 ConstantRange LVIR
= getConstantRangeFromLVI(A
, CtxI
);
9077 ConstantRange SCEVR
= getConstantRangeFromSCEV(A
, CtxI
);
9078 return getKnown().intersectWith(SCEVR
).intersectWith(LVIR
);
9081 /// See AAValueConstantRange::getAssumedConstantRange(..).
9083 getAssumedConstantRange(Attributor
&A
,
9084 const Instruction
*CtxI
= nullptr) const override
{
9085 // TODO: Make SCEV use Attributor assumption.
9086 // We may be able to bound a variable range via assumptions in
9087 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9088 // evolve to x^2 + x, then we can say that y is in [2, 12].
9089 if (!isValidCtxInstructionForOutsideAnalysis(A
, CtxI
,
9090 /* AllowAACtxI */ false))
9091 return getAssumed();
9093 ConstantRange LVIR
= getConstantRangeFromLVI(A
, CtxI
);
9094 ConstantRange SCEVR
= getConstantRangeFromSCEV(A
, CtxI
);
9095 return getAssumed().intersectWith(SCEVR
).intersectWith(LVIR
);
9098 /// Helper function to create MDNode for range metadata.
9100 getMDNodeForConstantRange(Type
*Ty
, LLVMContext
&Ctx
,
9101 const ConstantRange
&AssumedConstantRange
) {
9102 Metadata
*LowAndHigh
[] = {ConstantAsMetadata::get(ConstantInt::get(
9103 Ty
, AssumedConstantRange
.getLower())),
9104 ConstantAsMetadata::get(ConstantInt::get(
9105 Ty
, AssumedConstantRange
.getUpper()))};
9106 return MDNode::get(Ctx
, LowAndHigh
);
9109 /// Return true if \p Assumed is included in \p KnownRanges.
9110 static bool isBetterRange(const ConstantRange
&Assumed
, MDNode
*KnownRanges
) {
9112 if (Assumed
.isFullSet())
9118 // If multiple ranges are annotated in IR, we give up to annotate assumed
9121 // TODO: If there exists a known range which containts assumed range, we
9122 // can say assumed range is better.
9123 if (KnownRanges
->getNumOperands() > 2)
9126 ConstantInt
*Lower
=
9127 mdconst::extract
<ConstantInt
>(KnownRanges
->getOperand(0));
9128 ConstantInt
*Upper
=
9129 mdconst::extract
<ConstantInt
>(KnownRanges
->getOperand(1));
9131 ConstantRange
Known(Lower
->getValue(), Upper
->getValue());
9132 return Known
.contains(Assumed
) && Known
!= Assumed
;
9135 /// Helper function to set range metadata.
9137 setRangeMetadataIfisBetterRange(Instruction
*I
,
9138 const ConstantRange
&AssumedConstantRange
) {
9139 auto *OldRangeMD
= I
->getMetadata(LLVMContext::MD_range
);
9140 if (isBetterRange(AssumedConstantRange
, OldRangeMD
)) {
9141 if (!AssumedConstantRange
.isEmptySet()) {
9142 I
->setMetadata(LLVMContext::MD_range
,
9143 getMDNodeForConstantRange(I
->getType(), I
->getContext(),
9144 AssumedConstantRange
));
9151 /// See AbstractAttribute::manifest()
9152 ChangeStatus
manifest(Attributor
&A
) override
{
9153 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
9154 ConstantRange AssumedConstantRange
= getAssumedConstantRange(A
);
9155 assert(!AssumedConstantRange
.isFullSet() && "Invalid state");
9157 auto &V
= getAssociatedValue();
9158 if (!AssumedConstantRange
.isEmptySet() &&
9159 !AssumedConstantRange
.isSingleElement()) {
9160 if (Instruction
*I
= dyn_cast
<Instruction
>(&V
)) {
9161 assert(I
== getCtxI() && "Should not annotate an instruction which is "
9162 "not the context instruction");
9163 if (isa
<CallInst
>(I
) || isa
<LoadInst
>(I
))
9164 if (setRangeMetadataIfisBetterRange(I
, AssumedConstantRange
))
9165 Changed
= ChangeStatus::CHANGED
;
9173 struct AAValueConstantRangeArgument final
9174 : AAArgumentFromCallSiteArguments
<
9175 AAValueConstantRange
, AAValueConstantRangeImpl
, IntegerRangeState
,
9176 true /* BridgeCallBaseContext */> {
9177 using Base
= AAArgumentFromCallSiteArguments
<
9178 AAValueConstantRange
, AAValueConstantRangeImpl
, IntegerRangeState
,
9179 true /* BridgeCallBaseContext */>;
9180 AAValueConstantRangeArgument(const IRPosition
&IRP
, Attributor
&A
)
9183 /// See AbstractAttribute::trackStatistics()
9184 void trackStatistics() const override
{
9185 STATS_DECLTRACK_ARG_ATTR(value_range
)
9189 struct AAValueConstantRangeReturned
9190 : AAReturnedFromReturnedValues
<AAValueConstantRange
,
9191 AAValueConstantRangeImpl
,
9192 AAValueConstantRangeImpl::StateType
,
9193 /* PropogateCallBaseContext */ true> {
9195 AAReturnedFromReturnedValues
<AAValueConstantRange
,
9196 AAValueConstantRangeImpl
,
9197 AAValueConstantRangeImpl::StateType
,
9198 /* PropogateCallBaseContext */ true>;
9199 AAValueConstantRangeReturned(const IRPosition
&IRP
, Attributor
&A
)
9202 /// See AbstractAttribute::initialize(...).
9203 void initialize(Attributor
&A
) override
{
9204 if (!A
.isFunctionIPOAmendable(*getAssociatedFunction()))
9205 indicatePessimisticFixpoint();
9208 /// See AbstractAttribute::trackStatistics()
9209 void trackStatistics() const override
{
9210 STATS_DECLTRACK_FNRET_ATTR(value_range
)
9214 struct AAValueConstantRangeFloating
: AAValueConstantRangeImpl
{
9215 AAValueConstantRangeFloating(const IRPosition
&IRP
, Attributor
&A
)
9216 : AAValueConstantRangeImpl(IRP
, A
) {}
9218 /// See AbstractAttribute::initialize(...).
9219 void initialize(Attributor
&A
) override
{
9220 AAValueConstantRangeImpl::initialize(A
);
9224 Value
&V
= getAssociatedValue();
9226 if (auto *C
= dyn_cast
<ConstantInt
>(&V
)) {
9227 unionAssumed(ConstantRange(C
->getValue()));
9228 indicateOptimisticFixpoint();
9232 if (isa
<UndefValue
>(&V
)) {
9233 // Collapse the undef state to 0.
9234 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9235 indicateOptimisticFixpoint();
9239 if (isa
<CallBase
>(&V
))
9242 if (isa
<BinaryOperator
>(&V
) || isa
<CmpInst
>(&V
) || isa
<CastInst
>(&V
))
9245 // If it is a load instruction with range metadata, use it.
9246 if (LoadInst
*LI
= dyn_cast
<LoadInst
>(&V
))
9247 if (auto *RangeMD
= LI
->getMetadata(LLVMContext::MD_range
)) {
9248 intersectKnown(getConstantRangeFromMetadata(*RangeMD
));
9252 // We can work with PHI and select instruction as we traverse their operands
9254 if (isa
<SelectInst
>(V
) || isa
<PHINode
>(V
))
9257 // Otherwise we give up.
9258 indicatePessimisticFixpoint();
9260 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9261 << getAssociatedValue() << "\n");
9264 bool calculateBinaryOperator(
9265 Attributor
&A
, BinaryOperator
*BinOp
, IntegerRangeState
&T
,
9266 const Instruction
*CtxI
,
9267 SmallVectorImpl
<const AAValueConstantRange
*> &QuerriedAAs
) {
9268 Value
*LHS
= BinOp
->getOperand(0);
9269 Value
*RHS
= BinOp
->getOperand(1);
9271 // Simplify the operands first.
9272 bool UsedAssumedInformation
= false;
9273 const auto &SimplifiedLHS
= A
.getAssumedSimplified(
9274 IRPosition::value(*LHS
, getCallBaseContext()), *this,
9275 UsedAssumedInformation
, AA::Interprocedural
);
9276 if (!SimplifiedLHS
.has_value())
9278 if (!*SimplifiedLHS
)
9280 LHS
= *SimplifiedLHS
;
9282 const auto &SimplifiedRHS
= A
.getAssumedSimplified(
9283 IRPosition::value(*RHS
, getCallBaseContext()), *this,
9284 UsedAssumedInformation
, AA::Interprocedural
);
9285 if (!SimplifiedRHS
.has_value())
9287 if (!*SimplifiedRHS
)
9289 RHS
= *SimplifiedRHS
;
9291 // TODO: Allow non integers as well.
9292 if (!LHS
->getType()->isIntegerTy() || !RHS
->getType()->isIntegerTy())
9295 auto *LHSAA
= A
.getAAFor
<AAValueConstantRange
>(
9296 *this, IRPosition::value(*LHS
, getCallBaseContext()),
9297 DepClassTy::REQUIRED
);
9300 QuerriedAAs
.push_back(LHSAA
);
9301 auto LHSAARange
= LHSAA
->getAssumedConstantRange(A
, CtxI
);
9303 auto *RHSAA
= A
.getAAFor
<AAValueConstantRange
>(
9304 *this, IRPosition::value(*RHS
, getCallBaseContext()),
9305 DepClassTy::REQUIRED
);
9308 QuerriedAAs
.push_back(RHSAA
);
9309 auto RHSAARange
= RHSAA
->getAssumedConstantRange(A
, CtxI
);
9311 auto AssumedRange
= LHSAARange
.binaryOp(BinOp
->getOpcode(), RHSAARange
);
9313 T
.unionAssumed(AssumedRange
);
9315 // TODO: Track a known state too.
9317 return T
.isValidState();
9320 bool calculateCastInst(
9321 Attributor
&A
, CastInst
*CastI
, IntegerRangeState
&T
,
9322 const Instruction
*CtxI
,
9323 SmallVectorImpl
<const AAValueConstantRange
*> &QuerriedAAs
) {
9324 assert(CastI
->getNumOperands() == 1 && "Expected cast to be unary!");
9325 // TODO: Allow non integers as well.
9326 Value
*OpV
= CastI
->getOperand(0);
9328 // Simplify the operand first.
9329 bool UsedAssumedInformation
= false;
9330 const auto &SimplifiedOpV
= A
.getAssumedSimplified(
9331 IRPosition::value(*OpV
, getCallBaseContext()), *this,
9332 UsedAssumedInformation
, AA::Interprocedural
);
9333 if (!SimplifiedOpV
.has_value())
9335 if (!*SimplifiedOpV
)
9337 OpV
= *SimplifiedOpV
;
9339 if (!OpV
->getType()->isIntegerTy())
9342 auto *OpAA
= A
.getAAFor
<AAValueConstantRange
>(
9343 *this, IRPosition::value(*OpV
, getCallBaseContext()),
9344 DepClassTy::REQUIRED
);
9347 QuerriedAAs
.push_back(OpAA
);
9348 T
.unionAssumed(OpAA
->getAssumed().castOp(CastI
->getOpcode(),
9349 getState().getBitWidth()));
9350 return T
.isValidState();
9354 calculateCmpInst(Attributor
&A
, CmpInst
*CmpI
, IntegerRangeState
&T
,
9355 const Instruction
*CtxI
,
9356 SmallVectorImpl
<const AAValueConstantRange
*> &QuerriedAAs
) {
9357 Value
*LHS
= CmpI
->getOperand(0);
9358 Value
*RHS
= CmpI
->getOperand(1);
9360 // Simplify the operands first.
9361 bool UsedAssumedInformation
= false;
9362 const auto &SimplifiedLHS
= A
.getAssumedSimplified(
9363 IRPosition::value(*LHS
, getCallBaseContext()), *this,
9364 UsedAssumedInformation
, AA::Interprocedural
);
9365 if (!SimplifiedLHS
.has_value())
9367 if (!*SimplifiedLHS
)
9369 LHS
= *SimplifiedLHS
;
9371 const auto &SimplifiedRHS
= A
.getAssumedSimplified(
9372 IRPosition::value(*RHS
, getCallBaseContext()), *this,
9373 UsedAssumedInformation
, AA::Interprocedural
);
9374 if (!SimplifiedRHS
.has_value())
9376 if (!*SimplifiedRHS
)
9378 RHS
= *SimplifiedRHS
;
9380 // TODO: Allow non integers as well.
9381 if (!LHS
->getType()->isIntegerTy() || !RHS
->getType()->isIntegerTy())
9384 auto *LHSAA
= A
.getAAFor
<AAValueConstantRange
>(
9385 *this, IRPosition::value(*LHS
, getCallBaseContext()),
9386 DepClassTy::REQUIRED
);
9389 QuerriedAAs
.push_back(LHSAA
);
9390 auto *RHSAA
= A
.getAAFor
<AAValueConstantRange
>(
9391 *this, IRPosition::value(*RHS
, getCallBaseContext()),
9392 DepClassTy::REQUIRED
);
9395 QuerriedAAs
.push_back(RHSAA
);
9396 auto LHSAARange
= LHSAA
->getAssumedConstantRange(A
, CtxI
);
9397 auto RHSAARange
= RHSAA
->getAssumedConstantRange(A
, CtxI
);
9399 // If one of them is empty set, we can't decide.
9400 if (LHSAARange
.isEmptySet() || RHSAARange
.isEmptySet())
9403 bool MustTrue
= false, MustFalse
= false;
9405 auto AllowedRegion
=
9406 ConstantRange::makeAllowedICmpRegion(CmpI
->getPredicate(), RHSAARange
);
9408 if (AllowedRegion
.intersectWith(LHSAARange
).isEmptySet())
9411 if (LHSAARange
.icmp(CmpI
->getPredicate(), RHSAARange
))
9414 assert((!MustTrue
|| !MustFalse
) &&
9415 "Either MustTrue or MustFalse should be false!");
9418 T
.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9420 T
.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9422 T
.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9424 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI
<< " after "
9425 << (MustTrue
? "true" : (MustFalse
? "false" : "unknown"))
9426 << ": " << T
<< "\n\t" << *LHSAA
<< "\t<op>\n\t"
9429 // TODO: Track a known state too.
9430 return T
.isValidState();
9433 /// See AbstractAttribute::updateImpl(...).
9434 ChangeStatus
updateImpl(Attributor
&A
) override
{
9436 IntegerRangeState
T(getBitWidth());
9437 auto VisitValueCB
= [&](Value
&V
, const Instruction
*CtxI
) -> bool {
9438 Instruction
*I
= dyn_cast
<Instruction
>(&V
);
9439 if (!I
|| isa
<CallBase
>(I
)) {
9441 // Simplify the operand first.
9442 bool UsedAssumedInformation
= false;
9443 const auto &SimplifiedOpV
= A
.getAssumedSimplified(
9444 IRPosition::value(V
, getCallBaseContext()), *this,
9445 UsedAssumedInformation
, AA::Interprocedural
);
9446 if (!SimplifiedOpV
.has_value())
9448 if (!*SimplifiedOpV
)
9450 Value
*VPtr
= *SimplifiedOpV
;
9452 // If the value is not instruction, we query AA to Attributor.
9453 const auto *AA
= A
.getAAFor
<AAValueConstantRange
>(
9454 *this, IRPosition::value(*VPtr
, getCallBaseContext()),
9455 DepClassTy::REQUIRED
);
9457 // Clamp operator is not used to utilize a program point CtxI.
9459 T
.unionAssumed(AA
->getAssumedConstantRange(A
, CtxI
));
9463 return T
.isValidState();
9466 SmallVector
<const AAValueConstantRange
*, 4> QuerriedAAs
;
9467 if (auto *BinOp
= dyn_cast
<BinaryOperator
>(I
)) {
9468 if (!calculateBinaryOperator(A
, BinOp
, T
, CtxI
, QuerriedAAs
))
9470 } else if (auto *CmpI
= dyn_cast
<CmpInst
>(I
)) {
9471 if (!calculateCmpInst(A
, CmpI
, T
, CtxI
, QuerriedAAs
))
9473 } else if (auto *CastI
= dyn_cast
<CastInst
>(I
)) {
9474 if (!calculateCastInst(A
, CastI
, T
, CtxI
, QuerriedAAs
))
9477 // Give up with other instructions.
9478 // TODO: Add other instructions
9480 T
.indicatePessimisticFixpoint();
9484 // Catch circular reasoning in a pessimistic way for now.
9485 // TODO: Check how the range evolves and if we stripped anything, see also
9486 // AADereferenceable or AAAlign for similar situations.
9487 for (const AAValueConstantRange
*QueriedAA
: QuerriedAAs
) {
9488 if (QueriedAA
!= this)
9490 // If we are in a stady state we do not need to worry.
9491 if (T
.getAssumed() == getState().getAssumed())
9493 T
.indicatePessimisticFixpoint();
9496 return T
.isValidState();
9499 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9500 return indicatePessimisticFixpoint();
9502 // Ensure that long def-use chains can't cause circular reasoning either by
9503 // introducing a cutoff below.
9504 if (clampStateAndIndicateChange(getState(), T
) == ChangeStatus::UNCHANGED
)
9505 return ChangeStatus::UNCHANGED
;
9506 if (++NumChanges
> MaxNumChanges
) {
9507 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9508 << " but only " << MaxNumChanges
9509 << " are allowed to avoid cyclic reasoning.");
9510 return indicatePessimisticFixpoint();
9512 return ChangeStatus::CHANGED
;
9515 /// See AbstractAttribute::trackStatistics()
9516 void trackStatistics() const override
{
9517 STATS_DECLTRACK_FLOATING_ATTR(value_range
)
9520 /// Tracker to bail after too many widening steps of the constant range.
9523 /// Upper bound for the number of allowed changes (=widening steps) for the
9524 /// constant range before we give up.
9525 static constexpr int MaxNumChanges
= 5;
9528 struct AAValueConstantRangeFunction
: AAValueConstantRangeImpl
{
9529 AAValueConstantRangeFunction(const IRPosition
&IRP
, Attributor
&A
)
9530 : AAValueConstantRangeImpl(IRP
, A
) {}
9532 /// See AbstractAttribute::initialize(...).
9533 ChangeStatus
updateImpl(Attributor
&A
) override
{
9534 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9538 /// See AbstractAttribute::trackStatistics()
9539 void trackStatistics() const override
{ STATS_DECLTRACK_FN_ATTR(value_range
) }
9542 struct AAValueConstantRangeCallSite
: AAValueConstantRangeFunction
{
9543 AAValueConstantRangeCallSite(const IRPosition
&IRP
, Attributor
&A
)
9544 : AAValueConstantRangeFunction(IRP
, A
) {}
9546 /// See AbstractAttribute::trackStatistics()
9547 void trackStatistics() const override
{ STATS_DECLTRACK_CS_ATTR(value_range
) }
9550 struct AAValueConstantRangeCallSiteReturned
9551 : AACalleeToCallSite
<AAValueConstantRange
, AAValueConstantRangeImpl
,
9552 AAValueConstantRangeImpl::StateType
,
9553 /* IntroduceCallBaseContext */ true> {
9554 AAValueConstantRangeCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
9555 : AACalleeToCallSite
<AAValueConstantRange
, AAValueConstantRangeImpl
,
9556 AAValueConstantRangeImpl::StateType
,
9557 /* IntroduceCallBaseContext */ true>(IRP
, A
) {}
9559 /// See AbstractAttribute::initialize(...).
9560 void initialize(Attributor
&A
) override
{
9561 // If it is a load instruction with range metadata, use the metadata.
9562 if (CallInst
*CI
= dyn_cast
<CallInst
>(&getAssociatedValue()))
9563 if (auto *RangeMD
= CI
->getMetadata(LLVMContext::MD_range
))
9564 intersectKnown(getConstantRangeFromMetadata(*RangeMD
));
9566 AAValueConstantRangeImpl::initialize(A
);
9569 /// See AbstractAttribute::trackStatistics()
9570 void trackStatistics() const override
{
9571 STATS_DECLTRACK_CSRET_ATTR(value_range
)
9574 struct AAValueConstantRangeCallSiteArgument
: AAValueConstantRangeFloating
{
9575 AAValueConstantRangeCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
9576 : AAValueConstantRangeFloating(IRP
, A
) {}
9578 /// See AbstractAttribute::manifest()
9579 ChangeStatus
manifest(Attributor
&A
) override
{
9580 return ChangeStatus::UNCHANGED
;
9583 /// See AbstractAttribute::trackStatistics()
9584 void trackStatistics() const override
{
9585 STATS_DECLTRACK_CSARG_ATTR(value_range
)
9590 /// ------------------ Potential Values Attribute -------------------------
9593 struct AAPotentialConstantValuesImpl
: AAPotentialConstantValues
{
9594 using StateType
= PotentialConstantIntValuesState
;
9596 AAPotentialConstantValuesImpl(const IRPosition
&IRP
, Attributor
&A
)
9597 : AAPotentialConstantValues(IRP
, A
) {}
9599 /// See AbstractAttribute::initialize(..).
9600 void initialize(Attributor
&A
) override
{
9601 if (A
.hasSimplificationCallback(getIRPosition()))
9602 indicatePessimisticFixpoint();
9604 AAPotentialConstantValues::initialize(A
);
9607 bool fillSetWithConstantValues(Attributor
&A
, const IRPosition
&IRP
, SetTy
&S
,
9608 bool &ContainsUndef
, bool ForSelf
) {
9609 SmallVector
<AA::ValueAndContext
> Values
;
9610 bool UsedAssumedInformation
= false;
9611 if (!A
.getAssumedSimplifiedValues(IRP
, *this, Values
, AA::Interprocedural
,
9612 UsedAssumedInformation
)) {
9613 // Avoid recursion when the caller is computing constant values for this
9617 if (!IRP
.getAssociatedType()->isIntegerTy())
9619 auto *PotentialValuesAA
= A
.getAAFor
<AAPotentialConstantValues
>(
9620 *this, IRP
, DepClassTy::REQUIRED
);
9621 if (!PotentialValuesAA
|| !PotentialValuesAA
->getState().isValidState())
9623 ContainsUndef
= PotentialValuesAA
->getState().undefIsContained();
9624 S
= PotentialValuesAA
->getState().getAssumedSet();
9628 // Copy all the constant values, except UndefValue. ContainsUndef is true
9629 // iff Values contains only UndefValue instances. If there are other known
9630 // constants, then UndefValue is dropped.
9631 ContainsUndef
= false;
9632 for (auto &It
: Values
) {
9633 if (isa
<UndefValue
>(It
.getValue())) {
9634 ContainsUndef
= true;
9637 auto *CI
= dyn_cast
<ConstantInt
>(It
.getValue());
9640 S
.insert(CI
->getValue());
9642 ContainsUndef
&= S
.empty();
9647 /// See AbstractAttribute::getAsStr().
9648 const std::string
getAsStr(Attributor
*A
) const override
{
9650 llvm::raw_string_ostream
OS(Str
);
9655 /// See AbstractAttribute::updateImpl(...).
9656 ChangeStatus
updateImpl(Attributor
&A
) override
{
9657 return indicatePessimisticFixpoint();
9661 struct AAPotentialConstantValuesArgument final
9662 : AAArgumentFromCallSiteArguments
<AAPotentialConstantValues
,
9663 AAPotentialConstantValuesImpl
,
9664 PotentialConstantIntValuesState
> {
9665 using Base
= AAArgumentFromCallSiteArguments
<AAPotentialConstantValues
,
9666 AAPotentialConstantValuesImpl
,
9667 PotentialConstantIntValuesState
>;
9668 AAPotentialConstantValuesArgument(const IRPosition
&IRP
, Attributor
&A
)
9671 /// See AbstractAttribute::trackStatistics()
9672 void trackStatistics() const override
{
9673 STATS_DECLTRACK_ARG_ATTR(potential_values
)
9677 struct AAPotentialConstantValuesReturned
9678 : AAReturnedFromReturnedValues
<AAPotentialConstantValues
,
9679 AAPotentialConstantValuesImpl
> {
9680 using Base
= AAReturnedFromReturnedValues
<AAPotentialConstantValues
,
9681 AAPotentialConstantValuesImpl
>;
9682 AAPotentialConstantValuesReturned(const IRPosition
&IRP
, Attributor
&A
)
9685 void initialize(Attributor
&A
) override
{
9686 if (!A
.isFunctionIPOAmendable(*getAssociatedFunction()))
9687 indicatePessimisticFixpoint();
9688 Base::initialize(A
);
9691 /// See AbstractAttribute::trackStatistics()
9692 void trackStatistics() const override
{
9693 STATS_DECLTRACK_FNRET_ATTR(potential_values
)
9697 struct AAPotentialConstantValuesFloating
: AAPotentialConstantValuesImpl
{
9698 AAPotentialConstantValuesFloating(const IRPosition
&IRP
, Attributor
&A
)
9699 : AAPotentialConstantValuesImpl(IRP
, A
) {}
9701 /// See AbstractAttribute::initialize(..).
9702 void initialize(Attributor
&A
) override
{
9703 AAPotentialConstantValuesImpl::initialize(A
);
9707 Value
&V
= getAssociatedValue();
9709 if (auto *C
= dyn_cast
<ConstantInt
>(&V
)) {
9710 unionAssumed(C
->getValue());
9711 indicateOptimisticFixpoint();
9715 if (isa
<UndefValue
>(&V
)) {
9716 unionAssumedWithUndef();
9717 indicateOptimisticFixpoint();
9721 if (isa
<BinaryOperator
>(&V
) || isa
<ICmpInst
>(&V
) || isa
<CastInst
>(&V
))
9724 if (isa
<SelectInst
>(V
) || isa
<PHINode
>(V
) || isa
<LoadInst
>(V
))
9727 indicatePessimisticFixpoint();
9729 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9730 << getAssociatedValue() << "\n");
9733 static bool calculateICmpInst(const ICmpInst
*ICI
, const APInt
&LHS
,
9735 return ICmpInst::compare(LHS
, RHS
, ICI
->getPredicate());
9738 static APInt
calculateCastInst(const CastInst
*CI
, const APInt
&Src
,
9739 uint32_t ResultBitWidth
) {
9740 Instruction::CastOps CastOp
= CI
->getOpcode();
9743 llvm_unreachable("unsupported or not integer cast");
9744 case Instruction::Trunc
:
9745 return Src
.trunc(ResultBitWidth
);
9746 case Instruction::SExt
:
9747 return Src
.sext(ResultBitWidth
);
9748 case Instruction::ZExt
:
9749 return Src
.zext(ResultBitWidth
);
9750 case Instruction::BitCast
:
9755 static APInt
calculateBinaryOperator(const BinaryOperator
*BinOp
,
9756 const APInt
&LHS
, const APInt
&RHS
,
9757 bool &SkipOperation
, bool &Unsupported
) {
9758 Instruction::BinaryOps BinOpcode
= BinOp
->getOpcode();
9759 // Unsupported is set to true when the binary operator is not supported.
9760 // SkipOperation is set to true when UB occur with the given operand pair
9762 // TODO: we should look at nsw and nuw keywords to handle operations
9763 // that create poison or undef value.
9764 switch (BinOpcode
) {
9768 case Instruction::Add
:
9770 case Instruction::Sub
:
9772 case Instruction::Mul
:
9774 case Instruction::UDiv
:
9776 SkipOperation
= true;
9779 return LHS
.udiv(RHS
);
9780 case Instruction::SDiv
:
9782 SkipOperation
= true;
9785 return LHS
.sdiv(RHS
);
9786 case Instruction::URem
:
9788 SkipOperation
= true;
9791 return LHS
.urem(RHS
);
9792 case Instruction::SRem
:
9794 SkipOperation
= true;
9797 return LHS
.srem(RHS
);
9798 case Instruction::Shl
:
9799 return LHS
.shl(RHS
);
9800 case Instruction::LShr
:
9801 return LHS
.lshr(RHS
);
9802 case Instruction::AShr
:
9803 return LHS
.ashr(RHS
);
9804 case Instruction::And
:
9806 case Instruction::Or
:
9808 case Instruction::Xor
:
9813 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator
*BinOp
,
9814 const APInt
&LHS
, const APInt
&RHS
) {
9815 bool SkipOperation
= false;
9816 bool Unsupported
= false;
9818 calculateBinaryOperator(BinOp
, LHS
, RHS
, SkipOperation
, Unsupported
);
9821 // If SkipOperation is true, we can ignore this operand pair (L, R).
9823 unionAssumed(Result
);
9824 return isValidState();
9827 ChangeStatus
updateWithICmpInst(Attributor
&A
, ICmpInst
*ICI
) {
9828 auto AssumedBefore
= getAssumed();
9829 Value
*LHS
= ICI
->getOperand(0);
9830 Value
*RHS
= ICI
->getOperand(1);
9832 bool LHSContainsUndef
= false, RHSContainsUndef
= false;
9833 SetTy LHSAAPVS
, RHSAAPVS
;
9834 if (!fillSetWithConstantValues(A
, IRPosition::value(*LHS
), LHSAAPVS
,
9835 LHSContainsUndef
, /* ForSelf */ false) ||
9836 !fillSetWithConstantValues(A
, IRPosition::value(*RHS
), RHSAAPVS
,
9837 RHSContainsUndef
, /* ForSelf */ false))
9838 return indicatePessimisticFixpoint();
9840 // TODO: make use of undef flag to limit potential values aggressively.
9841 bool MaybeTrue
= false, MaybeFalse
= false;
9842 const APInt
Zero(RHS
->getType()->getIntegerBitWidth(), 0);
9843 if (LHSContainsUndef
&& RHSContainsUndef
) {
9844 // The result of any comparison between undefs can be soundly replaced
9846 unionAssumedWithUndef();
9847 } else if (LHSContainsUndef
) {
9848 for (const APInt
&R
: RHSAAPVS
) {
9849 bool CmpResult
= calculateICmpInst(ICI
, Zero
, R
);
9850 MaybeTrue
|= CmpResult
;
9851 MaybeFalse
|= !CmpResult
;
9852 if (MaybeTrue
& MaybeFalse
)
9853 return indicatePessimisticFixpoint();
9855 } else if (RHSContainsUndef
) {
9856 for (const APInt
&L
: LHSAAPVS
) {
9857 bool CmpResult
= calculateICmpInst(ICI
, L
, Zero
);
9858 MaybeTrue
|= CmpResult
;
9859 MaybeFalse
|= !CmpResult
;
9860 if (MaybeTrue
& MaybeFalse
)
9861 return indicatePessimisticFixpoint();
9864 for (const APInt
&L
: LHSAAPVS
) {
9865 for (const APInt
&R
: RHSAAPVS
) {
9866 bool CmpResult
= calculateICmpInst(ICI
, L
, R
);
9867 MaybeTrue
|= CmpResult
;
9868 MaybeFalse
|= !CmpResult
;
9869 if (MaybeTrue
& MaybeFalse
)
9870 return indicatePessimisticFixpoint();
9875 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9877 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
9878 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
9879 : ChangeStatus::CHANGED
;
9882 ChangeStatus
updateWithSelectInst(Attributor
&A
, SelectInst
*SI
) {
9883 auto AssumedBefore
= getAssumed();
9884 Value
*LHS
= SI
->getTrueValue();
9885 Value
*RHS
= SI
->getFalseValue();
9887 bool UsedAssumedInformation
= false;
9888 std::optional
<Constant
*> C
= A
.getAssumedConstant(
9889 *SI
->getCondition(), *this, UsedAssumedInformation
);
9891 // Check if we only need one operand.
9892 bool OnlyLeft
= false, OnlyRight
= false;
9893 if (C
&& *C
&& (*C
)->isOneValue())
9895 else if (C
&& *C
&& (*C
)->isZeroValue())
9898 bool LHSContainsUndef
= false, RHSContainsUndef
= false;
9899 SetTy LHSAAPVS
, RHSAAPVS
;
9901 !fillSetWithConstantValues(A
, IRPosition::value(*LHS
), LHSAAPVS
,
9902 LHSContainsUndef
, /* ForSelf */ false))
9903 return indicatePessimisticFixpoint();
9906 !fillSetWithConstantValues(A
, IRPosition::value(*RHS
), RHSAAPVS
,
9907 RHSContainsUndef
, /* ForSelf */ false))
9908 return indicatePessimisticFixpoint();
9910 if (OnlyLeft
|| OnlyRight
) {
9911 // select (true/false), lhs, rhs
9912 auto *OpAA
= OnlyLeft
? &LHSAAPVS
: &RHSAAPVS
;
9913 auto Undef
= OnlyLeft
? LHSContainsUndef
: RHSContainsUndef
;
9916 unionAssumedWithUndef();
9918 for (const auto &It
: *OpAA
)
9922 } else if (LHSContainsUndef
&& RHSContainsUndef
) {
9923 // select i1 *, undef , undef => undef
9924 unionAssumedWithUndef();
9926 for (const auto &It
: LHSAAPVS
)
9928 for (const auto &It
: RHSAAPVS
)
9931 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
9932 : ChangeStatus::CHANGED
;
9935 ChangeStatus
updateWithCastInst(Attributor
&A
, CastInst
*CI
) {
9936 auto AssumedBefore
= getAssumed();
9937 if (!CI
->isIntegerCast())
9938 return indicatePessimisticFixpoint();
9939 assert(CI
->getNumOperands() == 1 && "Expected cast to be unary!");
9940 uint32_t ResultBitWidth
= CI
->getDestTy()->getIntegerBitWidth();
9941 Value
*Src
= CI
->getOperand(0);
9943 bool SrcContainsUndef
= false;
9945 if (!fillSetWithConstantValues(A
, IRPosition::value(*Src
), SrcPVS
,
9946 SrcContainsUndef
, /* ForSelf */ false))
9947 return indicatePessimisticFixpoint();
9949 if (SrcContainsUndef
)
9950 unionAssumedWithUndef();
9952 for (const APInt
&S
: SrcPVS
) {
9953 APInt T
= calculateCastInst(CI
, S
, ResultBitWidth
);
9957 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
9958 : ChangeStatus::CHANGED
;
9961 ChangeStatus
updateWithBinaryOperator(Attributor
&A
, BinaryOperator
*BinOp
) {
9962 auto AssumedBefore
= getAssumed();
9963 Value
*LHS
= BinOp
->getOperand(0);
9964 Value
*RHS
= BinOp
->getOperand(1);
9966 bool LHSContainsUndef
= false, RHSContainsUndef
= false;
9967 SetTy LHSAAPVS
, RHSAAPVS
;
9968 if (!fillSetWithConstantValues(A
, IRPosition::value(*LHS
), LHSAAPVS
,
9969 LHSContainsUndef
, /* ForSelf */ false) ||
9970 !fillSetWithConstantValues(A
, IRPosition::value(*RHS
), RHSAAPVS
,
9971 RHSContainsUndef
, /* ForSelf */ false))
9972 return indicatePessimisticFixpoint();
9974 const APInt Zero
= APInt(LHS
->getType()->getIntegerBitWidth(), 0);
9976 // TODO: make use of undef flag to limit potential values aggressively.
9977 if (LHSContainsUndef
&& RHSContainsUndef
) {
9978 if (!calculateBinaryOperatorAndTakeUnion(BinOp
, Zero
, Zero
))
9979 return indicatePessimisticFixpoint();
9980 } else if (LHSContainsUndef
) {
9981 for (const APInt
&R
: RHSAAPVS
) {
9982 if (!calculateBinaryOperatorAndTakeUnion(BinOp
, Zero
, R
))
9983 return indicatePessimisticFixpoint();
9985 } else if (RHSContainsUndef
) {
9986 for (const APInt
&L
: LHSAAPVS
) {
9987 if (!calculateBinaryOperatorAndTakeUnion(BinOp
, L
, Zero
))
9988 return indicatePessimisticFixpoint();
9991 for (const APInt
&L
: LHSAAPVS
) {
9992 for (const APInt
&R
: RHSAAPVS
) {
9993 if (!calculateBinaryOperatorAndTakeUnion(BinOp
, L
, R
))
9994 return indicatePessimisticFixpoint();
9998 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
9999 : ChangeStatus::CHANGED
;
10002 ChangeStatus
updateWithInstruction(Attributor
&A
, Instruction
*Inst
) {
10003 auto AssumedBefore
= getAssumed();
10005 bool ContainsUndef
;
10006 if (!fillSetWithConstantValues(A
, IRPosition::value(*Inst
), Incoming
,
10007 ContainsUndef
, /* ForSelf */ true))
10008 return indicatePessimisticFixpoint();
10009 if (ContainsUndef
) {
10010 unionAssumedWithUndef();
10012 for (const auto &It
: Incoming
)
10015 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
10016 : ChangeStatus::CHANGED
;
10019 /// See AbstractAttribute::updateImpl(...).
10020 ChangeStatus
updateImpl(Attributor
&A
) override
{
10021 Value
&V
= getAssociatedValue();
10022 Instruction
*I
= dyn_cast
<Instruction
>(&V
);
10024 if (auto *ICI
= dyn_cast
<ICmpInst
>(I
))
10025 return updateWithICmpInst(A
, ICI
);
10027 if (auto *SI
= dyn_cast
<SelectInst
>(I
))
10028 return updateWithSelectInst(A
, SI
);
10030 if (auto *CI
= dyn_cast
<CastInst
>(I
))
10031 return updateWithCastInst(A
, CI
);
10033 if (auto *BinOp
= dyn_cast
<BinaryOperator
>(I
))
10034 return updateWithBinaryOperator(A
, BinOp
);
10036 if (isa
<PHINode
>(I
) || isa
<LoadInst
>(I
))
10037 return updateWithInstruction(A
, I
);
10039 return indicatePessimisticFixpoint();
10042 /// See AbstractAttribute::trackStatistics()
10043 void trackStatistics() const override
{
10044 STATS_DECLTRACK_FLOATING_ATTR(potential_values
)
10048 struct AAPotentialConstantValuesFunction
: AAPotentialConstantValuesImpl
{
10049 AAPotentialConstantValuesFunction(const IRPosition
&IRP
, Attributor
&A
)
10050 : AAPotentialConstantValuesImpl(IRP
, A
) {}
10052 /// See AbstractAttribute::initialize(...).
10053 ChangeStatus
updateImpl(Attributor
&A
) override
{
10055 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10059 /// See AbstractAttribute::trackStatistics()
10060 void trackStatistics() const override
{
10061 STATS_DECLTRACK_FN_ATTR(potential_values
)
10065 struct AAPotentialConstantValuesCallSite
: AAPotentialConstantValuesFunction
{
10066 AAPotentialConstantValuesCallSite(const IRPosition
&IRP
, Attributor
&A
)
10067 : AAPotentialConstantValuesFunction(IRP
, A
) {}
10069 /// See AbstractAttribute::trackStatistics()
10070 void trackStatistics() const override
{
10071 STATS_DECLTRACK_CS_ATTR(potential_values
)
10075 struct AAPotentialConstantValuesCallSiteReturned
10076 : AACalleeToCallSite
<AAPotentialConstantValues
,
10077 AAPotentialConstantValuesImpl
> {
10078 AAPotentialConstantValuesCallSiteReturned(const IRPosition
&IRP
,
10080 : AACalleeToCallSite
<AAPotentialConstantValues
,
10081 AAPotentialConstantValuesImpl
>(IRP
, A
) {}
10083 /// See AbstractAttribute::trackStatistics()
10084 void trackStatistics() const override
{
10085 STATS_DECLTRACK_CSRET_ATTR(potential_values
)
10089 struct AAPotentialConstantValuesCallSiteArgument
10090 : AAPotentialConstantValuesFloating
{
10091 AAPotentialConstantValuesCallSiteArgument(const IRPosition
&IRP
,
10093 : AAPotentialConstantValuesFloating(IRP
, A
) {}
10095 /// See AbstractAttribute::initialize(..).
10096 void initialize(Attributor
&A
) override
{
10097 AAPotentialConstantValuesImpl::initialize(A
);
10098 if (isAtFixpoint())
10101 Value
&V
= getAssociatedValue();
10103 if (auto *C
= dyn_cast
<ConstantInt
>(&V
)) {
10104 unionAssumed(C
->getValue());
10105 indicateOptimisticFixpoint();
10109 if (isa
<UndefValue
>(&V
)) {
10110 unionAssumedWithUndef();
10111 indicateOptimisticFixpoint();
10116 /// See AbstractAttribute::updateImpl(...).
10117 ChangeStatus
updateImpl(Attributor
&A
) override
{
10118 Value
&V
= getAssociatedValue();
10119 auto AssumedBefore
= getAssumed();
10120 auto *AA
= A
.getAAFor
<AAPotentialConstantValues
>(
10121 *this, IRPosition::value(V
), DepClassTy::REQUIRED
);
10123 return indicatePessimisticFixpoint();
10124 const auto &S
= AA
->getAssumed();
10126 return AssumedBefore
== getAssumed() ? ChangeStatus::UNCHANGED
10127 : ChangeStatus::CHANGED
;
10130 /// See AbstractAttribute::trackStatistics()
10131 void trackStatistics() const override
{
10132 STATS_DECLTRACK_CSARG_ATTR(potential_values
)
10137 /// ------------------------ NoUndef Attribute ---------------------------------
10138 bool AANoUndef::isImpliedByIR(Attributor
&A
, const IRPosition
&IRP
,
10139 Attribute::AttrKind ImpliedAttributeKind
,
10140 bool IgnoreSubsumingPositions
) {
10141 assert(ImpliedAttributeKind
== Attribute::NoUndef
&&
10142 "Unexpected attribute kind");
10143 if (A
.hasAttr(IRP
, {Attribute::NoUndef
}, IgnoreSubsumingPositions
,
10144 Attribute::NoUndef
))
10147 Value
&Val
= IRP
.getAssociatedValue();
10148 if (IRP
.getPositionKind() != IRPosition::IRP_RETURNED
&&
10149 isGuaranteedNotToBeUndefOrPoison(&Val
)) {
10150 LLVMContext
&Ctx
= Val
.getContext();
10151 A
.manifestAttrs(IRP
, Attribute::get(Ctx
, Attribute::NoUndef
));
10159 struct AANoUndefImpl
: AANoUndef
{
10160 AANoUndefImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoUndef(IRP
, A
) {}
10162 /// See AbstractAttribute::initialize(...).
10163 void initialize(Attributor
&A
) override
{
10164 Value
&V
= getAssociatedValue();
10165 if (isa
<UndefValue
>(V
))
10166 indicatePessimisticFixpoint();
10167 assert(!isImpliedByIR(A
, getIRPosition(), Attribute::NoUndef
));
10170 /// See followUsesInMBEC
10171 bool followUseInMBEC(Attributor
&A
, const Use
*U
, const Instruction
*I
,
10172 AANoUndef::StateType
&State
) {
10173 const Value
*UseV
= U
->get();
10174 const DominatorTree
*DT
= nullptr;
10175 AssumptionCache
*AC
= nullptr;
10176 InformationCache
&InfoCache
= A
.getInfoCache();
10177 if (Function
*F
= getAnchorScope()) {
10178 DT
= InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(*F
);
10179 AC
= InfoCache
.getAnalysisResultForFunction
<AssumptionAnalysis
>(*F
);
10181 State
.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV
, AC
, I
, DT
));
10182 bool TrackUse
= false;
10183 // Track use for instructions which must produce undef or poison bits when
10184 // at least one operand contains such bits.
10185 if (isa
<CastInst
>(*I
) || isa
<GetElementPtrInst
>(*I
))
10190 /// See AbstractAttribute::getAsStr().
10191 const std::string
getAsStr(Attributor
*A
) const override
{
10192 return getAssumed() ? "noundef" : "may-undef-or-poison";
10195 ChangeStatus
manifest(Attributor
&A
) override
{
10196 // We don't manifest noundef attribute for dead positions because the
10197 // associated values with dead positions would be replaced with undef
10199 bool UsedAssumedInformation
= false;
10200 if (A
.isAssumedDead(getIRPosition(), nullptr, nullptr,
10201 UsedAssumedInformation
))
10202 return ChangeStatus::UNCHANGED
;
10203 // A position whose simplified value does not have any value is
10204 // considered to be dead. We don't manifest noundef in such positions for
10205 // the same reason above.
10206 if (!A
.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation
,
10207 AA::Interprocedural
)
10209 return ChangeStatus::UNCHANGED
;
10210 return AANoUndef::manifest(A
);
10214 struct AANoUndefFloating
: public AANoUndefImpl
{
10215 AANoUndefFloating(const IRPosition
&IRP
, Attributor
&A
)
10216 : AANoUndefImpl(IRP
, A
) {}
10218 /// See AbstractAttribute::initialize(...).
10219 void initialize(Attributor
&A
) override
{
10220 AANoUndefImpl::initialize(A
);
10221 if (!getState().isAtFixpoint() && getAnchorScope() &&
10222 !getAnchorScope()->isDeclaration())
10223 if (Instruction
*CtxI
= getCtxI())
10224 followUsesInMBEC(*this, A
, getState(), *CtxI
);
10227 /// See AbstractAttribute::updateImpl(...).
10228 ChangeStatus
updateImpl(Attributor
&A
) override
{
10229 auto VisitValueCB
= [&](const IRPosition
&IRP
) -> bool {
10230 bool IsKnownNoUndef
;
10231 return AA::hasAssumedIRAttr
<Attribute::NoUndef
>(
10232 A
, this, IRP
, DepClassTy::REQUIRED
, IsKnownNoUndef
);
10236 bool UsedAssumedInformation
= false;
10237 Value
*AssociatedValue
= &getAssociatedValue();
10238 SmallVector
<AA::ValueAndContext
> Values
;
10239 if (!A
.getAssumedSimplifiedValues(getIRPosition(), *this, Values
,
10240 AA::AnyScope
, UsedAssumedInformation
))
10244 Values
.size() != 1 || Values
.front().getValue() != AssociatedValue
;
10247 // If we haven't stripped anything we might still be able to use a
10248 // different AA, but only if the IRP changes. Effectively when we
10249 // interpret this not as a call site value but as a floating/argument
10251 const IRPosition AVIRP
= IRPosition::value(*AssociatedValue
);
10252 if (AVIRP
== getIRPosition() || !VisitValueCB(AVIRP
))
10253 return indicatePessimisticFixpoint();
10254 return ChangeStatus::UNCHANGED
;
10257 for (const auto &VAC
: Values
)
10258 if (!VisitValueCB(IRPosition::value(*VAC
.getValue())))
10259 return indicatePessimisticFixpoint();
10261 return ChangeStatus::UNCHANGED
;
10264 /// See AbstractAttribute::trackStatistics()
10265 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(noundef
) }
10268 struct AANoUndefReturned final
10269 : AAReturnedFromReturnedValues
<AANoUndef
, AANoUndefImpl
> {
10270 AANoUndefReturned(const IRPosition
&IRP
, Attributor
&A
)
10271 : AAReturnedFromReturnedValues
<AANoUndef
, AANoUndefImpl
>(IRP
, A
) {}
10273 /// See AbstractAttribute::trackStatistics()
10274 void trackStatistics() const override
{ STATS_DECLTRACK_FNRET_ATTR(noundef
) }
10277 struct AANoUndefArgument final
10278 : AAArgumentFromCallSiteArguments
<AANoUndef
, AANoUndefImpl
> {
10279 AANoUndefArgument(const IRPosition
&IRP
, Attributor
&A
)
10280 : AAArgumentFromCallSiteArguments
<AANoUndef
, AANoUndefImpl
>(IRP
, A
) {}
10282 /// See AbstractAttribute::trackStatistics()
10283 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(noundef
) }
10286 struct AANoUndefCallSiteArgument final
: AANoUndefFloating
{
10287 AANoUndefCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
10288 : AANoUndefFloating(IRP
, A
) {}
10290 /// See AbstractAttribute::trackStatistics()
10291 void trackStatistics() const override
{ STATS_DECLTRACK_CSARG_ATTR(noundef
) }
10294 struct AANoUndefCallSiteReturned final
10295 : AACalleeToCallSite
<AANoUndef
, AANoUndefImpl
> {
10296 AANoUndefCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
10297 : AACalleeToCallSite
<AANoUndef
, AANoUndefImpl
>(IRP
, A
) {}
10299 /// See AbstractAttribute::trackStatistics()
10300 void trackStatistics() const override
{ STATS_DECLTRACK_CSRET_ATTR(noundef
) }
10303 /// ------------------------ NoFPClass Attribute -------------------------------
10305 struct AANoFPClassImpl
: AANoFPClass
{
10306 AANoFPClassImpl(const IRPosition
&IRP
, Attributor
&A
) : AANoFPClass(IRP
, A
) {}
10308 void initialize(Attributor
&A
) override
{
10309 const IRPosition
&IRP
= getIRPosition();
10311 Value
&V
= IRP
.getAssociatedValue();
10312 if (isa
<UndefValue
>(V
)) {
10313 indicateOptimisticFixpoint();
10317 SmallVector
<Attribute
> Attrs
;
10318 A
.getAttrs(getIRPosition(), {Attribute::NoFPClass
}, Attrs
, false);
10319 for (const auto &Attr
: Attrs
) {
10320 addKnownBits(Attr
.getNoFPClass());
10323 const DataLayout
&DL
= A
.getDataLayout();
10324 if (getPositionKind() != IRPosition::IRP_RETURNED
) {
10325 KnownFPClass KnownFPClass
= computeKnownFPClass(&V
, DL
);
10326 addKnownBits(~KnownFPClass
.KnownFPClasses
);
10329 if (Instruction
*CtxI
= getCtxI())
10330 followUsesInMBEC(*this, A
, getState(), *CtxI
);
10333 /// See followUsesInMBEC
10334 bool followUseInMBEC(Attributor
&A
, const Use
*U
, const Instruction
*I
,
10335 AANoFPClass::StateType
&State
) {
10336 const Value
*UseV
= U
->get();
10337 const DominatorTree
*DT
= nullptr;
10338 AssumptionCache
*AC
= nullptr;
10339 const TargetLibraryInfo
*TLI
= nullptr;
10340 InformationCache
&InfoCache
= A
.getInfoCache();
10342 if (Function
*F
= getAnchorScope()) {
10343 DT
= InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(*F
);
10344 AC
= InfoCache
.getAnalysisResultForFunction
<AssumptionAnalysis
>(*F
);
10345 TLI
= InfoCache
.getTargetLibraryInfoForFunction(*F
);
10348 const DataLayout
&DL
= A
.getDataLayout();
10350 KnownFPClass KnownFPClass
=
10351 computeKnownFPClass(UseV
, DL
,
10352 /*InterestedClasses=*/fcAllFlags
,
10353 /*Depth=*/0, TLI
, AC
, I
, DT
);
10354 State
.addKnownBits(~KnownFPClass
.KnownFPClasses
);
10356 bool TrackUse
= false;
10360 const std::string
getAsStr(Attributor
*A
) const override
{
10361 std::string Result
= "nofpclass";
10362 raw_string_ostream
OS(Result
);
10363 OS
<< getAssumedNoFPClass();
10367 void getDeducedAttributes(Attributor
&A
, LLVMContext
&Ctx
,
10368 SmallVectorImpl
<Attribute
> &Attrs
) const override
{
10369 Attrs
.emplace_back(Attribute::getWithNoFPClass(Ctx
, getAssumedNoFPClass()));
10373 struct AANoFPClassFloating
: public AANoFPClassImpl
{
10374 AANoFPClassFloating(const IRPosition
&IRP
, Attributor
&A
)
10375 : AANoFPClassImpl(IRP
, A
) {}
10377 /// See AbstractAttribute::updateImpl(...).
10378 ChangeStatus
updateImpl(Attributor
&A
) override
{
10379 SmallVector
<AA::ValueAndContext
> Values
;
10380 bool UsedAssumedInformation
= false;
10381 if (!A
.getAssumedSimplifiedValues(getIRPosition(), *this, Values
,
10382 AA::AnyScope
, UsedAssumedInformation
)) {
10383 Values
.push_back({getAssociatedValue(), getCtxI()});
10387 auto VisitValueCB
= [&](Value
&V
, const Instruction
*CtxI
) -> bool {
10388 const auto *AA
= A
.getAAFor
<AANoFPClass
>(*this, IRPosition::value(V
),
10389 DepClassTy::REQUIRED
);
10390 if (!AA
|| this == AA
) {
10391 T
.indicatePessimisticFixpoint();
10393 const AANoFPClass::StateType
&S
=
10394 static_cast<const AANoFPClass::StateType
&>(AA
->getState());
10397 return T
.isValidState();
10400 for (const auto &VAC
: Values
)
10401 if (!VisitValueCB(*VAC
.getValue(), VAC
.getCtxI()))
10402 return indicatePessimisticFixpoint();
10404 return clampStateAndIndicateChange(getState(), T
);
10407 /// See AbstractAttribute::trackStatistics()
10408 void trackStatistics() const override
{
10409 STATS_DECLTRACK_FNRET_ATTR(nofpclass
)
10413 struct AANoFPClassReturned final
10414 : AAReturnedFromReturnedValues
<AANoFPClass
, AANoFPClassImpl
,
10415 AANoFPClassImpl::StateType
, false, Attribute::None
, false> {
10416 AANoFPClassReturned(const IRPosition
&IRP
, Attributor
&A
)
10417 : AAReturnedFromReturnedValues
<AANoFPClass
, AANoFPClassImpl
,
10418 AANoFPClassImpl::StateType
, false, Attribute::None
, false>(
10421 /// See AbstractAttribute::trackStatistics()
10422 void trackStatistics() const override
{
10423 STATS_DECLTRACK_FNRET_ATTR(nofpclass
)
10427 struct AANoFPClassArgument final
10428 : AAArgumentFromCallSiteArguments
<AANoFPClass
, AANoFPClassImpl
> {
10429 AANoFPClassArgument(const IRPosition
&IRP
, Attributor
&A
)
10430 : AAArgumentFromCallSiteArguments
<AANoFPClass
, AANoFPClassImpl
>(IRP
, A
) {}
10432 /// See AbstractAttribute::trackStatistics()
10433 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(nofpclass
) }
10436 struct AANoFPClassCallSiteArgument final
: AANoFPClassFloating
{
10437 AANoFPClassCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
10438 : AANoFPClassFloating(IRP
, A
) {}
10440 /// See AbstractAttribute::trackStatistics()
10441 void trackStatistics() const override
{
10442 STATS_DECLTRACK_CSARG_ATTR(nofpclass
)
10446 struct AANoFPClassCallSiteReturned final
10447 : AACalleeToCallSite
<AANoFPClass
, AANoFPClassImpl
> {
10448 AANoFPClassCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
10449 : AACalleeToCallSite
<AANoFPClass
, AANoFPClassImpl
>(IRP
, A
) {}
10451 /// See AbstractAttribute::trackStatistics()
10452 void trackStatistics() const override
{
10453 STATS_DECLTRACK_CSRET_ATTR(nofpclass
)
10457 struct AACallEdgesImpl
: public AACallEdges
{
10458 AACallEdgesImpl(const IRPosition
&IRP
, Attributor
&A
) : AACallEdges(IRP
, A
) {}
10460 const SetVector
<Function
*> &getOptimisticEdges() const override
{
10461 return CalledFunctions
;
10464 bool hasUnknownCallee() const override
{ return HasUnknownCallee
; }
10466 bool hasNonAsmUnknownCallee() const override
{
10467 return HasUnknownCalleeNonAsm
;
10470 const std::string
getAsStr(Attributor
*A
) const override
{
10471 return "CallEdges[" + std::to_string(HasUnknownCallee
) + "," +
10472 std::to_string(CalledFunctions
.size()) + "]";
10475 void trackStatistics() const override
{}
10478 void addCalledFunction(Function
*Fn
, ChangeStatus
&Change
) {
10479 if (CalledFunctions
.insert(Fn
)) {
10480 Change
= ChangeStatus::CHANGED
;
10481 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn
->getName()
10486 void setHasUnknownCallee(bool NonAsm
, ChangeStatus
&Change
) {
10487 if (!HasUnknownCallee
)
10488 Change
= ChangeStatus::CHANGED
;
10489 if (NonAsm
&& !HasUnknownCalleeNonAsm
)
10490 Change
= ChangeStatus::CHANGED
;
10491 HasUnknownCalleeNonAsm
|= NonAsm
;
10492 HasUnknownCallee
= true;
10496 /// Optimistic set of functions that might be called by this position.
10497 SetVector
<Function
*> CalledFunctions
;
10499 /// Is there any call with a unknown callee.
10500 bool HasUnknownCallee
= false;
10502 /// Is there any call with a unknown callee, excluding any inline asm.
10503 bool HasUnknownCalleeNonAsm
= false;
10506 struct AACallEdgesCallSite
: public AACallEdgesImpl
{
10507 AACallEdgesCallSite(const IRPosition
&IRP
, Attributor
&A
)
10508 : AACallEdgesImpl(IRP
, A
) {}
10509 /// See AbstractAttribute::updateImpl(...).
10510 ChangeStatus
updateImpl(Attributor
&A
) override
{
10511 ChangeStatus Change
= ChangeStatus::UNCHANGED
;
10513 auto VisitValue
= [&](Value
&V
, const Instruction
*CtxI
) -> bool {
10514 if (Function
*Fn
= dyn_cast
<Function
>(&V
)) {
10515 addCalledFunction(Fn
, Change
);
10517 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V
<< "\n");
10518 setHasUnknownCallee(true, Change
);
10521 // Explore all values.
10525 SmallVector
<AA::ValueAndContext
> Values
;
10526 // Process any value that we might call.
10527 auto ProcessCalledOperand
= [&](Value
*V
, Instruction
*CtxI
) {
10528 if (isa
<Constant
>(V
)) {
10529 VisitValue(*V
, CtxI
);
10533 bool UsedAssumedInformation
= false;
10535 if (!A
.getAssumedSimplifiedValues(IRPosition::value(*V
), *this, Values
,
10536 AA::AnyScope
, UsedAssumedInformation
)) {
10537 Values
.push_back({*V
, CtxI
});
10539 for (auto &VAC
: Values
)
10540 VisitValue(*VAC
.getValue(), VAC
.getCtxI());
10543 CallBase
*CB
= cast
<CallBase
>(getCtxI());
10545 if (auto *IA
= dyn_cast
<InlineAsm
>(CB
->getCalledOperand())) {
10546 if (IA
->hasSideEffects() &&
10547 !hasAssumption(*CB
->getCaller(), "ompx_no_call_asm") &&
10548 !hasAssumption(*CB
, "ompx_no_call_asm")) {
10549 setHasUnknownCallee(false, Change
);
10554 if (CB
->isIndirectCall())
10555 if (auto *IndirectCallAA
= A
.getAAFor
<AAIndirectCallInfo
>(
10556 *this, getIRPosition(), DepClassTy::OPTIONAL
))
10557 if (IndirectCallAA
->foreachCallee(
10558 [&](Function
*Fn
) { return VisitValue(*Fn
, CB
); }))
10561 // The most simple case.
10562 ProcessCalledOperand(CB
->getCalledOperand(), CB
);
10564 // Process callback functions.
10565 SmallVector
<const Use
*, 4u> CallbackUses
;
10566 AbstractCallSite::getCallbackUses(*CB
, CallbackUses
);
10567 for (const Use
*U
: CallbackUses
)
10568 ProcessCalledOperand(U
->get(), CB
);
10574 struct AACallEdgesFunction
: public AACallEdgesImpl
{
10575 AACallEdgesFunction(const IRPosition
&IRP
, Attributor
&A
)
10576 : AACallEdgesImpl(IRP
, A
) {}
10578 /// See AbstractAttribute::updateImpl(...).
10579 ChangeStatus
updateImpl(Attributor
&A
) override
{
10580 ChangeStatus Change
= ChangeStatus::UNCHANGED
;
10582 auto ProcessCallInst
= [&](Instruction
&Inst
) {
10583 CallBase
&CB
= cast
<CallBase
>(Inst
);
10585 auto *CBEdges
= A
.getAAFor
<AACallEdges
>(
10586 *this, IRPosition::callsite_function(CB
), DepClassTy::REQUIRED
);
10589 if (CBEdges
->hasNonAsmUnknownCallee())
10590 setHasUnknownCallee(true, Change
);
10591 if (CBEdges
->hasUnknownCallee())
10592 setHasUnknownCallee(false, Change
);
10594 for (Function
*F
: CBEdges
->getOptimisticEdges())
10595 addCalledFunction(F
, Change
);
10600 // Visit all callable instructions.
10601 bool UsedAssumedInformation
= false;
10602 if (!A
.checkForAllCallLikeInstructions(ProcessCallInst
, *this,
10603 UsedAssumedInformation
,
10604 /* CheckBBLivenessOnly */ true)) {
10605 // If we haven't looked at all call like instructions, assume that there
10606 // are unknown callees.
10607 setHasUnknownCallee(true, Change
);
10614 /// -------------------AAInterFnReachability Attribute--------------------------
10616 struct AAInterFnReachabilityFunction
10617 : public CachedReachabilityAA
<AAInterFnReachability
, Function
> {
10618 using Base
= CachedReachabilityAA
<AAInterFnReachability
, Function
>;
10619 AAInterFnReachabilityFunction(const IRPosition
&IRP
, Attributor
&A
)
10622 bool instructionCanReach(
10623 Attributor
&A
, const Instruction
&From
, const Function
&To
,
10624 const AA::InstExclusionSetTy
*ExclusionSet
) const override
{
10625 assert(From
.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10626 auto *NonConstThis
= const_cast<AAInterFnReachabilityFunction
*>(this);
10628 RQITy
StackRQI(A
, From
, To
, ExclusionSet
, false);
10629 typename
RQITy::Reachable Result
;
10630 if (!NonConstThis
->checkQueryCache(A
, StackRQI
, Result
))
10631 return NonConstThis
->isReachableImpl(A
, StackRQI
,
10632 /*IsTemporaryRQI=*/true);
10633 return Result
== RQITy::Reachable::Yes
;
10636 bool isReachableImpl(Attributor
&A
, RQITy
&RQI
,
10637 bool IsTemporaryRQI
) override
{
10638 const Instruction
*EntryI
=
10639 &RQI
.From
->getFunction()->getEntryBlock().front();
10640 if (EntryI
!= RQI
.From
&&
10641 !instructionCanReach(A
, *EntryI
, *RQI
.To
, nullptr))
10642 return rememberResult(A
, RQITy::Reachable::No
, RQI
, false,
10645 auto CheckReachableCallBase
= [&](CallBase
*CB
) {
10646 auto *CBEdges
= A
.getAAFor
<AACallEdges
>(
10647 *this, IRPosition::callsite_function(*CB
), DepClassTy::OPTIONAL
);
10648 if (!CBEdges
|| !CBEdges
->getState().isValidState())
10650 // TODO Check To backwards in this case.
10651 if (CBEdges
->hasUnknownCallee())
10654 for (Function
*Fn
: CBEdges
->getOptimisticEdges()) {
10658 if (Fn
->isDeclaration()) {
10659 if (Fn
->hasFnAttribute(Attribute::NoCallback
))
10661 // TODO Check To backwards in this case.
10665 if (Fn
== getAnchorScope()) {
10666 if (EntryI
== RQI
.From
)
10671 const AAInterFnReachability
*InterFnReachability
=
10672 A
.getAAFor
<AAInterFnReachability
>(*this, IRPosition::function(*Fn
),
10673 DepClassTy::OPTIONAL
);
10675 const Instruction
&FnFirstInst
= Fn
->getEntryBlock().front();
10676 if (!InterFnReachability
||
10677 InterFnReachability
->instructionCanReach(A
, FnFirstInst
, *RQI
.To
,
10684 const auto *IntraFnReachability
= A
.getAAFor
<AAIntraFnReachability
>(
10685 *this, IRPosition::function(*RQI
.From
->getFunction()),
10686 DepClassTy::OPTIONAL
);
10688 // Determine call like instructions that we can reach from the inst.
10689 auto CheckCallBase
= [&](Instruction
&CBInst
) {
10690 // There are usually less nodes in the call graph, check inter function
10691 // reachability first.
10692 if (CheckReachableCallBase(cast
<CallBase
>(&CBInst
)))
10694 return IntraFnReachability
&& !IntraFnReachability
->isAssumedReachable(
10695 A
, *RQI
.From
, CBInst
, RQI
.ExclusionSet
);
10698 bool UsedExclusionSet
= /* conservative */ true;
10699 bool UsedAssumedInformation
= false;
10700 if (!A
.checkForAllCallLikeInstructions(CheckCallBase
, *this,
10701 UsedAssumedInformation
,
10702 /* CheckBBLivenessOnly */ true))
10703 return rememberResult(A
, RQITy::Reachable::Yes
, RQI
, UsedExclusionSet
,
10706 return rememberResult(A
, RQITy::Reachable::No
, RQI
, UsedExclusionSet
,
10710 void trackStatistics() const override
{}
10714 template <typename AAType
>
10715 static std::optional
<Constant
*>
10716 askForAssumedConstant(Attributor
&A
, const AbstractAttribute
&QueryingAA
,
10717 const IRPosition
&IRP
, Type
&Ty
) {
10718 if (!Ty
.isIntegerTy())
10721 // This will also pass the call base context.
10722 const auto *AA
= A
.getAAFor
<AAType
>(QueryingAA
, IRP
, DepClassTy::NONE
);
10726 std::optional
<Constant
*> COpt
= AA
->getAssumedConstant(A
);
10728 if (!COpt
.has_value()) {
10729 A
.recordDependence(*AA
, QueryingAA
, DepClassTy::OPTIONAL
);
10730 return std::nullopt
;
10732 if (auto *C
= *COpt
) {
10733 A
.recordDependence(*AA
, QueryingAA
, DepClassTy::OPTIONAL
);
10739 Value
*AAPotentialValues::getSingleValue(
10740 Attributor
&A
, const AbstractAttribute
&AA
, const IRPosition
&IRP
,
10741 SmallVectorImpl
<AA::ValueAndContext
> &Values
) {
10742 Type
&Ty
= *IRP
.getAssociatedType();
10743 std::optional
<Value
*> V
;
10744 for (auto &It
: Values
) {
10745 V
= AA::combineOptionalValuesInAAValueLatice(V
, It
.getValue(), &Ty
);
10746 if (V
.has_value() && !*V
)
10749 if (!V
.has_value())
10750 return UndefValue::get(&Ty
);
10755 struct AAPotentialValuesImpl
: AAPotentialValues
{
10756 using StateType
= PotentialLLVMValuesState
;
10758 AAPotentialValuesImpl(const IRPosition
&IRP
, Attributor
&A
)
10759 : AAPotentialValues(IRP
, A
) {}
10761 /// See AbstractAttribute::initialize(..).
10762 void initialize(Attributor
&A
) override
{
10763 if (A
.hasSimplificationCallback(getIRPosition())) {
10764 indicatePessimisticFixpoint();
10767 Value
*Stripped
= getAssociatedValue().stripPointerCasts();
10768 auto *CE
= dyn_cast
<ConstantExpr
>(Stripped
);
10769 if (isa
<Constant
>(Stripped
) &&
10770 (!CE
|| CE
->getOpcode() != Instruction::ICmp
)) {
10771 addValue(A
, getState(), *Stripped
, getCtxI(), AA::AnyScope
,
10773 indicateOptimisticFixpoint();
10776 AAPotentialValues::initialize(A
);
10779 /// See AbstractAttribute::getAsStr().
10780 const std::string
getAsStr(Attributor
*A
) const override
{
10782 llvm::raw_string_ostream
OS(Str
);
10787 template <typename AAType
>
10788 static std::optional
<Value
*> askOtherAA(Attributor
&A
,
10789 const AbstractAttribute
&AA
,
10790 const IRPosition
&IRP
, Type
&Ty
) {
10791 if (isa
<Constant
>(IRP
.getAssociatedValue()))
10792 return &IRP
.getAssociatedValue();
10793 std::optional
<Constant
*> C
= askForAssumedConstant
<AAType
>(A
, AA
, IRP
, Ty
);
10795 return std::nullopt
;
10797 if (auto *CC
= AA::getWithType(**C
, Ty
))
10802 virtual void addValue(Attributor
&A
, StateType
&State
, Value
&V
,
10803 const Instruction
*CtxI
, AA::ValueScope S
,
10804 Function
*AnchorScope
) const {
10806 IRPosition ValIRP
= IRPosition::value(V
);
10807 if (auto *CB
= dyn_cast_or_null
<CallBase
>(CtxI
)) {
10808 for (const auto &U
: CB
->args()) {
10811 ValIRP
= IRPosition::callsite_argument(*CB
, CB
->getArgOperandNo(&U
));
10817 if (ValIRP
.getAssociatedType()->isIntegerTy()) {
10818 Type
&Ty
= *getAssociatedType();
10819 std::optional
<Value
*> SimpleV
=
10820 askOtherAA
<AAValueConstantRange
>(A
, *this, ValIRP
, Ty
);
10821 if (SimpleV
.has_value() && !*SimpleV
) {
10822 auto *PotentialConstantsAA
= A
.getAAFor
<AAPotentialConstantValues
>(
10823 *this, ValIRP
, DepClassTy::OPTIONAL
);
10824 if (PotentialConstantsAA
&& PotentialConstantsAA
->isValidState()) {
10825 for (const auto &It
: PotentialConstantsAA
->getAssumedSet())
10826 State
.unionAssumed({{*ConstantInt::get(&Ty
, It
), nullptr}, S
});
10827 if (PotentialConstantsAA
->undefIsContained())
10828 State
.unionAssumed({{*UndefValue::get(&Ty
), nullptr}, S
});
10832 if (!SimpleV
.has_value())
10839 if (isa
<ConstantInt
>(VPtr
))
10841 if (!AA::isValidInScope(*VPtr
, AnchorScope
))
10842 S
= AA::ValueScope(S
| AA::Interprocedural
);
10844 State
.unionAssumed({{*VPtr
, CtxI
}, S
});
10847 /// Helper struct to tie a value+context pair together with the scope for
10848 /// which this is the simplified version.
10850 AA::ValueAndContext I
;
10853 bool operator==(const ItemInfo
&II
) const {
10854 return II
.I
== I
&& II
.S
== S
;
10856 bool operator<(const ItemInfo
&II
) const {
10863 bool recurseForValue(Attributor
&A
, const IRPosition
&IRP
, AA::ValueScope S
) {
10864 SmallMapVector
<AA::ValueAndContext
, int, 8> ValueScopeMap
;
10865 for (auto CS
: {AA::Intraprocedural
, AA::Interprocedural
}) {
10869 bool UsedAssumedInformation
= false;
10870 SmallVector
<AA::ValueAndContext
> Values
;
10871 if (!A
.getAssumedSimplifiedValues(IRP
, this, Values
, CS
,
10872 UsedAssumedInformation
))
10875 for (auto &It
: Values
)
10876 ValueScopeMap
[It
] += CS
;
10878 for (auto &It
: ValueScopeMap
)
10879 addValue(A
, getState(), *It
.first
.getValue(), It
.first
.getCtxI(),
10880 AA::ValueScope(It
.second
), getAnchorScope());
10885 void giveUpOnIntraprocedural(Attributor
&A
) {
10886 auto NewS
= StateType::getBestState(getState());
10887 for (const auto &It
: getAssumedSet()) {
10888 if (It
.second
== AA::Intraprocedural
)
10890 addValue(A
, NewS
, *It
.first
.getValue(), It
.first
.getCtxI(),
10891 AA::Interprocedural
, getAnchorScope());
10893 assert(!undefIsContained() && "Undef should be an explicit value!");
10894 addValue(A
, NewS
, getAssociatedValue(), getCtxI(), AA::Intraprocedural
,
10899 /// See AbstractState::indicatePessimisticFixpoint(...).
10900 ChangeStatus
indicatePessimisticFixpoint() override
{
10901 getState() = StateType::getBestState(getState());
10902 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope
});
10903 AAPotentialValues::indicateOptimisticFixpoint();
10904 return ChangeStatus::CHANGED
;
10907 /// See AbstractAttribute::updateImpl(...).
10908 ChangeStatus
updateImpl(Attributor
&A
) override
{
10909 return indicatePessimisticFixpoint();
10912 /// See AbstractAttribute::manifest(...).
10913 ChangeStatus
manifest(Attributor
&A
) override
{
10914 SmallVector
<AA::ValueAndContext
> Values
;
10915 for (AA::ValueScope S
: {AA::Interprocedural
, AA::Intraprocedural
}) {
10917 if (!getAssumedSimplifiedValues(A
, Values
, S
))
10919 Value
&OldV
= getAssociatedValue();
10920 if (isa
<UndefValue
>(OldV
))
10922 Value
*NewV
= getSingleValue(A
, *this, getIRPosition(), Values
);
10923 if (!NewV
|| NewV
== &OldV
)
10926 !AA::isValidAtPosition({*NewV
, *getCtxI()}, A
.getInfoCache()))
10928 if (A
.changeAfterManifest(getIRPosition(), *NewV
))
10929 return ChangeStatus::CHANGED
;
10931 return ChangeStatus::UNCHANGED
;
10934 bool getAssumedSimplifiedValues(
10935 Attributor
&A
, SmallVectorImpl
<AA::ValueAndContext
> &Values
,
10936 AA::ValueScope S
, bool RecurseForSelectAndPHI
= false) const override
{
10937 if (!isValidState())
10939 bool UsedAssumedInformation
= false;
10940 for (const auto &It
: getAssumedSet())
10941 if (It
.second
& S
) {
10942 if (RecurseForSelectAndPHI
&& (isa
<PHINode
>(It
.first
.getValue()) ||
10943 isa
<SelectInst
>(It
.first
.getValue()))) {
10944 if (A
.getAssumedSimplifiedValues(
10945 IRPosition::inst(*cast
<Instruction
>(It
.first
.getValue())),
10946 this, Values
, S
, UsedAssumedInformation
))
10949 Values
.push_back(It
.first
);
10951 assert(!undefIsContained() && "Undef should be an explicit value!");
10956 struct AAPotentialValuesFloating
: AAPotentialValuesImpl
{
10957 AAPotentialValuesFloating(const IRPosition
&IRP
, Attributor
&A
)
10958 : AAPotentialValuesImpl(IRP
, A
) {}
10960 /// See AbstractAttribute::updateImpl(...).
10961 ChangeStatus
updateImpl(Attributor
&A
) override
{
10962 auto AssumedBefore
= getAssumed();
10964 genericValueTraversal(A
, &getAssociatedValue());
10966 return (AssumedBefore
== getAssumed()) ? ChangeStatus::UNCHANGED
10967 : ChangeStatus::CHANGED
;
10970 /// Helper struct to remember which AAIsDead instances we actually used.
10971 struct LivenessInfo
{
10972 const AAIsDead
*LivenessAA
= nullptr;
10973 bool AnyDead
= false;
10976 /// Check if \p Cmp is a comparison we can simplify.
10978 /// We handle multiple cases, one in which at least one operand is an
10979 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
10980 /// operand. Return true if successful, in that case Worklist will be updated.
10981 bool handleCmp(Attributor
&A
, Value
&Cmp
, Value
*LHS
, Value
*RHS
,
10982 CmpInst::Predicate Pred
, ItemInfo II
,
10983 SmallVectorImpl
<ItemInfo
> &Worklist
) {
10985 // Simplify the operands first.
10986 bool UsedAssumedInformation
= false;
10987 SmallVector
<AA::ValueAndContext
> LHSValues
, RHSValues
;
10988 auto GetSimplifiedValues
= [&](Value
&V
,
10989 SmallVector
<AA::ValueAndContext
> &Values
) {
10990 if (!A
.getAssumedSimplifiedValues(
10991 IRPosition::value(V
, getCallBaseContext()), this, Values
,
10992 AA::Intraprocedural
, UsedAssumedInformation
)) {
10994 Values
.push_back(AA::ValueAndContext
{V
, II
.I
.getCtxI()});
10996 return Values
.empty();
10998 if (GetSimplifiedValues(*LHS
, LHSValues
))
11000 if (GetSimplifiedValues(*RHS
, RHSValues
))
11003 LLVMContext
&Ctx
= LHS
->getContext();
11005 InformationCache
&InfoCache
= A
.getInfoCache();
11006 Instruction
*CmpI
= dyn_cast
<Instruction
>(&Cmp
);
11007 Function
*F
= CmpI
? CmpI
->getFunction() : nullptr;
11009 F
? InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(*F
)
11012 F
? A
.getInfoCache().getTargetLibraryInfoForFunction(*F
) : nullptr;
11014 F
? InfoCache
.getAnalysisResultForFunction
<AssumptionAnalysis
>(*F
)
11017 const DataLayout
&DL
= A
.getDataLayout();
11018 SimplifyQuery
Q(DL
, TLI
, DT
, AC
, CmpI
);
11020 auto CheckPair
= [&](Value
&LHSV
, Value
&RHSV
) {
11021 if (isa
<UndefValue
>(LHSV
) || isa
<UndefValue
>(RHSV
)) {
11022 addValue(A
, getState(), *UndefValue::get(Cmp
.getType()),
11023 /* CtxI */ nullptr, II
.S
, getAnchorScope());
11027 // Handle the trivial case first in which we don't even need to think
11028 // about null or non-null.
11029 if (&LHSV
== &RHSV
&&
11030 (CmpInst::isTrueWhenEqual(Pred
) || CmpInst::isFalseWhenEqual(Pred
))) {
11031 Constant
*NewV
= ConstantInt::get(Type::getInt1Ty(Ctx
),
11032 CmpInst::isTrueWhenEqual(Pred
));
11033 addValue(A
, getState(), *NewV
, /* CtxI */ nullptr, II
.S
,
11038 auto *TypedLHS
= AA::getWithType(LHSV
, *LHS
->getType());
11039 auto *TypedRHS
= AA::getWithType(RHSV
, *RHS
->getType());
11040 if (TypedLHS
&& TypedRHS
) {
11041 Value
*NewV
= simplifyCmpInst(Pred
, TypedLHS
, TypedRHS
, Q
);
11042 if (NewV
&& NewV
!= &Cmp
) {
11043 addValue(A
, getState(), *NewV
, /* CtxI */ nullptr, II
.S
,
11049 // From now on we only handle equalities (==, !=).
11050 if (!CmpInst::isEquality(Pred
))
11053 bool LHSIsNull
= isa
<ConstantPointerNull
>(LHSV
);
11054 bool RHSIsNull
= isa
<ConstantPointerNull
>(RHSV
);
11055 if (!LHSIsNull
&& !RHSIsNull
)
11058 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11059 // non-nullptr operand and if we assume it's non-null we can conclude the
11060 // result of the comparison.
11061 assert((LHSIsNull
|| RHSIsNull
) &&
11062 "Expected nullptr versus non-nullptr comparison at this point");
11064 // The index is the operand that we assume is not null.
11065 unsigned PtrIdx
= LHSIsNull
;
11066 bool IsKnownNonNull
;
11067 bool IsAssumedNonNull
= AA::hasAssumedIRAttr
<Attribute::NonNull
>(
11068 A
, this, IRPosition::value(*(PtrIdx
? &RHSV
: &LHSV
)),
11069 DepClassTy::REQUIRED
, IsKnownNonNull
);
11070 if (!IsAssumedNonNull
)
11073 // The new value depends on the predicate, true for != and false for ==.
11075 ConstantInt::get(Type::getInt1Ty(Ctx
), Pred
== CmpInst::ICMP_NE
);
11076 addValue(A
, getState(), *NewV
, /* CtxI */ nullptr, II
.S
,
11081 for (auto &LHSValue
: LHSValues
)
11082 for (auto &RHSValue
: RHSValues
)
11083 if (!CheckPair(*LHSValue
.getValue(), *RHSValue
.getValue()))
11088 bool handleSelectInst(Attributor
&A
, SelectInst
&SI
, ItemInfo II
,
11089 SmallVectorImpl
<ItemInfo
> &Worklist
) {
11090 const Instruction
*CtxI
= II
.I
.getCtxI();
11091 bool UsedAssumedInformation
= false;
11093 std::optional
<Constant
*> C
=
11094 A
.getAssumedConstant(*SI
.getCondition(), *this, UsedAssumedInformation
);
11095 bool NoValueYet
= !C
.has_value();
11096 if (NoValueYet
|| isa_and_nonnull
<UndefValue
>(*C
))
11098 if (auto *CI
= dyn_cast_or_null
<ConstantInt
>(*C
)) {
11100 Worklist
.push_back({{*SI
.getFalseValue(), CtxI
}, II
.S
});
11102 Worklist
.push_back({{*SI
.getTrueValue(), CtxI
}, II
.S
});
11103 } else if (&SI
== &getAssociatedValue()) {
11104 // We could not simplify the condition, assume both values.
11105 Worklist
.push_back({{*SI
.getTrueValue(), CtxI
}, II
.S
});
11106 Worklist
.push_back({{*SI
.getFalseValue(), CtxI
}, II
.S
});
11108 std::optional
<Value
*> SimpleV
= A
.getAssumedSimplified(
11109 IRPosition::inst(SI
), *this, UsedAssumedInformation
, II
.S
);
11110 if (!SimpleV
.has_value())
11113 addValue(A
, getState(), **SimpleV
, CtxI
, II
.S
, getAnchorScope());
11121 bool handleLoadInst(Attributor
&A
, LoadInst
&LI
, ItemInfo II
,
11122 SmallVectorImpl
<ItemInfo
> &Worklist
) {
11123 SmallSetVector
<Value
*, 4> PotentialCopies
;
11124 SmallSetVector
<Instruction
*, 4> PotentialValueOrigins
;
11125 bool UsedAssumedInformation
= false;
11126 if (!AA::getPotentiallyLoadedValues(A
, LI
, PotentialCopies
,
11127 PotentialValueOrigins
, *this,
11128 UsedAssumedInformation
,
11129 /* OnlyExact */ true)) {
11130 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11131 "loaded values for load instruction "
11136 // Do not simplify loads that are only used in llvm.assume if we cannot also
11137 // remove all stores that may feed into the load. The reason is that the
11138 // assume is probably worth something as long as the stores are around.
11139 InformationCache
&InfoCache
= A
.getInfoCache();
11140 if (InfoCache
.isOnlyUsedByAssume(LI
)) {
11141 if (!llvm::all_of(PotentialValueOrigins
, [&](Instruction
*I
) {
11142 if (!I
|| isa
<AssumeInst
>(I
))
11144 if (auto *SI
= dyn_cast
<StoreInst
>(I
))
11145 return A
.isAssumedDead(SI
->getOperandUse(0), this,
11146 /* LivenessAA */ nullptr,
11147 UsedAssumedInformation
,
11148 /* CheckBBLivenessOnly */ false);
11149 return A
.isAssumedDead(*I
, this, /* LivenessAA */ nullptr,
11150 UsedAssumedInformation
,
11151 /* CheckBBLivenessOnly */ false);
11153 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11154 "and we cannot delete all the stores: "
11160 // Values have to be dynamically unique or we loose the fact that a
11161 // single llvm::Value might represent two runtime values (e.g.,
11162 // stack locations in different recursive calls).
11163 const Instruction
*CtxI
= II
.I
.getCtxI();
11164 bool ScopeIsLocal
= (II
.S
& AA::Intraprocedural
);
11165 bool AllLocal
= ScopeIsLocal
;
11166 bool DynamicallyUnique
= llvm::all_of(PotentialCopies
, [&](Value
*PC
) {
11167 AllLocal
&= AA::isValidInScope(*PC
, getAnchorScope());
11168 return AA::isDynamicallyUnique(A
, *this, *PC
);
11170 if (!DynamicallyUnique
) {
11171 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11172 "values are dynamically unique: "
11177 for (auto *PotentialCopy
: PotentialCopies
) {
11179 Worklist
.push_back({{*PotentialCopy
, CtxI
}, II
.S
});
11181 Worklist
.push_back({{*PotentialCopy
, CtxI
}, AA::Interprocedural
});
11184 if (!AllLocal
&& ScopeIsLocal
)
11185 addValue(A
, getState(), LI
, CtxI
, AA::Intraprocedural
, getAnchorScope());
11189 bool handlePHINode(
11190 Attributor
&A
, PHINode
&PHI
, ItemInfo II
,
11191 SmallVectorImpl
<ItemInfo
> &Worklist
,
11192 SmallMapVector
<const Function
*, LivenessInfo
, 4> &LivenessAAs
) {
11193 auto GetLivenessInfo
= [&](const Function
&F
) -> LivenessInfo
& {
11194 LivenessInfo
&LI
= LivenessAAs
[&F
];
11195 if (!LI
.LivenessAA
)
11196 LI
.LivenessAA
= A
.getAAFor
<AAIsDead
>(*this, IRPosition::function(F
),
11201 if (&PHI
== &getAssociatedValue()) {
11202 LivenessInfo
&LI
= GetLivenessInfo(*PHI
.getFunction());
11204 A
.getInfoCache().getAnalysisResultForFunction
<CycleAnalysis
>(
11205 *PHI
.getFunction());
11207 Cycle
*C
= nullptr;
11208 bool CyclePHI
= mayBeInCycle(CI
, &PHI
, /* HeaderOnly */ true, &C
);
11209 for (unsigned u
= 0, e
= PHI
.getNumIncomingValues(); u
< e
; u
++) {
11210 BasicBlock
*IncomingBB
= PHI
.getIncomingBlock(u
);
11211 if (LI
.LivenessAA
&&
11212 LI
.LivenessAA
->isEdgeDead(IncomingBB
, PHI
.getParent())) {
11216 Value
*V
= PHI
.getIncomingValue(u
);
11220 // If the incoming value is not the PHI but an instruction in the same
11221 // cycle we might have multiple versions of it flying around.
11222 if (CyclePHI
&& isa
<Instruction
>(V
) &&
11223 (!C
|| C
->contains(cast
<Instruction
>(V
)->getParent())))
11226 Worklist
.push_back({{*V
, IncomingBB
->getTerminator()}, II
.S
});
11231 bool UsedAssumedInformation
= false;
11232 std::optional
<Value
*> SimpleV
= A
.getAssumedSimplified(
11233 IRPosition::inst(PHI
), *this, UsedAssumedInformation
, II
.S
);
11234 if (!SimpleV
.has_value())
11238 addValue(A
, getState(), **SimpleV
, &PHI
, II
.S
, getAnchorScope());
11242 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11243 /// simplify any operand of the instruction \p I. Return true if successful,
11244 /// in that case Worklist will be updated.
11245 bool handleGenericInst(Attributor
&A
, Instruction
&I
, ItemInfo II
,
11246 SmallVectorImpl
<ItemInfo
> &Worklist
) {
11247 bool SomeSimplified
= false;
11248 bool UsedAssumedInformation
= false;
11250 SmallVector
<Value
*, 8> NewOps(I
.getNumOperands());
11252 for (Value
*Op
: I
.operands()) {
11253 const auto &SimplifiedOp
= A
.getAssumedSimplified(
11254 IRPosition::value(*Op
, getCallBaseContext()), *this,
11255 UsedAssumedInformation
, AA::Intraprocedural
);
11256 // If we are not sure about any operand we are not sure about the entire
11257 // instruction, we'll wait.
11258 if (!SimplifiedOp
.has_value())
11262 NewOps
[Idx
] = *SimplifiedOp
;
11266 SomeSimplified
|= (NewOps
[Idx
] != Op
);
11270 // We won't bother with the InstSimplify interface if we didn't simplify any
11271 // operand ourselves.
11272 if (!SomeSimplified
)
11275 InformationCache
&InfoCache
= A
.getInfoCache();
11276 Function
*F
= I
.getFunction();
11278 InfoCache
.getAnalysisResultForFunction
<DominatorTreeAnalysis
>(*F
);
11279 const auto *TLI
= A
.getInfoCache().getTargetLibraryInfoForFunction(*F
);
11280 auto *AC
= InfoCache
.getAnalysisResultForFunction
<AssumptionAnalysis
>(*F
);
11282 const DataLayout
&DL
= I
.getModule()->getDataLayout();
11283 SimplifyQuery
Q(DL
, TLI
, DT
, AC
, &I
);
11284 Value
*NewV
= simplifyInstructionWithOperands(&I
, NewOps
, Q
);
11285 if (!NewV
|| NewV
== &I
)
11288 LLVM_DEBUG(dbgs() << "Generic inst " << I
<< " assumed simplified to "
11290 Worklist
.push_back({{*NewV
, II
.I
.getCtxI()}, II
.S
});
11294 bool simplifyInstruction(
11295 Attributor
&A
, Instruction
&I
, ItemInfo II
,
11296 SmallVectorImpl
<ItemInfo
> &Worklist
,
11297 SmallMapVector
<const Function
*, LivenessInfo
, 4> &LivenessAAs
) {
11298 if (auto *CI
= dyn_cast
<CmpInst
>(&I
))
11299 return handleCmp(A
, *CI
, CI
->getOperand(0), CI
->getOperand(1),
11300 CI
->getPredicate(), II
, Worklist
);
11302 switch (I
.getOpcode()) {
11303 case Instruction::Select
:
11304 return handleSelectInst(A
, cast
<SelectInst
>(I
), II
, Worklist
);
11305 case Instruction::PHI
:
11306 return handlePHINode(A
, cast
<PHINode
>(I
), II
, Worklist
, LivenessAAs
);
11307 case Instruction::Load
:
11308 return handleLoadInst(A
, cast
<LoadInst
>(I
), II
, Worklist
);
11310 return handleGenericInst(A
, I
, II
, Worklist
);
11315 void genericValueTraversal(Attributor
&A
, Value
*InitialV
) {
11316 SmallMapVector
<const Function
*, LivenessInfo
, 4> LivenessAAs
;
11318 SmallSet
<ItemInfo
, 16> Visited
;
11319 SmallVector
<ItemInfo
, 16> Worklist
;
11320 Worklist
.push_back({{*InitialV
, getCtxI()}, AA::AnyScope
});
11324 ItemInfo II
= Worklist
.pop_back_val();
11325 Value
*V
= II
.I
.getValue();
11327 const Instruction
*CtxI
= II
.I
.getCtxI();
11328 AA::ValueScope S
= II
.S
;
11330 // Check if we should process the current value. To prevent endless
11331 // recursion keep a record of the values we followed!
11332 if (!Visited
.insert(II
).second
)
11335 // Make sure we limit the compile time for complex expressions.
11336 if (Iteration
++ >= MaxPotentialValuesIterations
) {
11337 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11338 << Iteration
<< "!\n");
11339 addValue(A
, getState(), *V
, CtxI
, S
, getAnchorScope());
11343 // Explicitly look through calls with a "returned" attribute if we do
11344 // not have a pointer as stripPointerCasts only works on them.
11345 Value
*NewV
= nullptr;
11346 if (V
->getType()->isPointerTy()) {
11347 NewV
= AA::getWithType(*V
->stripPointerCasts(), *V
->getType());
11349 if (auto *CB
= dyn_cast
<CallBase
>(V
))
11351 dyn_cast_if_present
<Function
>(CB
->getCalledOperand())) {
11352 for (Argument
&Arg
: Callee
->args())
11353 if (Arg
.hasReturnedAttr()) {
11354 NewV
= CB
->getArgOperand(Arg
.getArgNo());
11359 if (NewV
&& NewV
!= V
) {
11360 Worklist
.push_back({{*NewV
, CtxI
}, S
});
11364 if (auto *CE
= dyn_cast
<ConstantExpr
>(V
)) {
11365 if (CE
->getOpcode() == Instruction::ICmp
)
11366 if (handleCmp(A
, *CE
, CE
->getOperand(0), CE
->getOperand(1),
11367 CmpInst::Predicate(CE
->getPredicate()), II
, Worklist
))
11371 if (auto *I
= dyn_cast
<Instruction
>(V
)) {
11372 if (simplifyInstruction(A
, *I
, II
, Worklist
, LivenessAAs
))
11376 if (V
!= InitialV
|| isa
<Argument
>(V
))
11377 if (recurseForValue(A
, IRPosition::value(*V
), II
.S
))
11380 // If we haven't stripped anything we give up.
11381 if (V
== InitialV
&& CtxI
== getCtxI()) {
11382 indicatePessimisticFixpoint();
11386 addValue(A
, getState(), *V
, CtxI
, S
, getAnchorScope());
11387 } while (!Worklist
.empty());
11389 // If we actually used liveness information so we have to record a
11391 for (auto &It
: LivenessAAs
)
11392 if (It
.second
.AnyDead
)
11393 A
.recordDependence(*It
.second
.LivenessAA
, *this, DepClassTy::OPTIONAL
);
11396 /// See AbstractAttribute::trackStatistics()
11397 void trackStatistics() const override
{
11398 STATS_DECLTRACK_FLOATING_ATTR(potential_values
)
11402 struct AAPotentialValuesArgument final
: AAPotentialValuesImpl
{
11403 using Base
= AAPotentialValuesImpl
;
11404 AAPotentialValuesArgument(const IRPosition
&IRP
, Attributor
&A
)
11407 /// See AbstractAttribute::initialize(..).
11408 void initialize(Attributor
&A
) override
{
11409 auto &Arg
= cast
<Argument
>(getAssociatedValue());
11410 if (Arg
.hasPointeeInMemoryValueAttr())
11411 indicatePessimisticFixpoint();
11414 /// See AbstractAttribute::updateImpl(...).
11415 ChangeStatus
updateImpl(Attributor
&A
) override
{
11416 auto AssumedBefore
= getAssumed();
11418 unsigned ArgNo
= getCalleeArgNo();
11420 bool UsedAssumedInformation
= false;
11421 SmallVector
<AA::ValueAndContext
> Values
;
11422 auto CallSitePred
= [&](AbstractCallSite ACS
) {
11423 const auto CSArgIRP
= IRPosition::callsite_argument(ACS
, ArgNo
);
11424 if (CSArgIRP
.getPositionKind() == IRP_INVALID
)
11427 if (!A
.getAssumedSimplifiedValues(CSArgIRP
, this, Values
,
11428 AA::Interprocedural
,
11429 UsedAssumedInformation
))
11432 return isValidState();
11435 if (!A
.checkForAllCallSites(CallSitePred
, *this,
11436 /* RequireAllCallSites */ true,
11437 UsedAssumedInformation
))
11438 return indicatePessimisticFixpoint();
11440 Function
*Fn
= getAssociatedFunction();
11441 bool AnyNonLocal
= false;
11442 for (auto &It
: Values
) {
11443 if (isa
<Constant
>(It
.getValue())) {
11444 addValue(A
, getState(), *It
.getValue(), It
.getCtxI(), AA::AnyScope
,
11448 if (!AA::isDynamicallyUnique(A
, *this, *It
.getValue()))
11449 return indicatePessimisticFixpoint();
11451 if (auto *Arg
= dyn_cast
<Argument
>(It
.getValue()))
11452 if (Arg
->getParent() == Fn
) {
11453 addValue(A
, getState(), *It
.getValue(), It
.getCtxI(), AA::AnyScope
,
11457 addValue(A
, getState(), *It
.getValue(), It
.getCtxI(), AA::Interprocedural
,
11459 AnyNonLocal
= true;
11461 assert(!undefIsContained() && "Undef should be an explicit value!");
11463 giveUpOnIntraprocedural(A
);
11465 return (AssumedBefore
== getAssumed()) ? ChangeStatus::UNCHANGED
11466 : ChangeStatus::CHANGED
;
11469 /// See AbstractAttribute::trackStatistics()
11470 void trackStatistics() const override
{
11471 STATS_DECLTRACK_ARG_ATTR(potential_values
)
11475 struct AAPotentialValuesReturned
: public AAPotentialValuesFloating
{
11476 using Base
= AAPotentialValuesFloating
;
11477 AAPotentialValuesReturned(const IRPosition
&IRP
, Attributor
&A
)
11480 /// See AbstractAttribute::initialize(..).
11481 void initialize(Attributor
&A
) override
{
11482 Function
*F
= getAssociatedFunction();
11483 if (!F
|| F
->isDeclaration() || F
->getReturnType()->isVoidTy()) {
11484 indicatePessimisticFixpoint();
11488 for (Argument
&Arg
: F
->args())
11489 if (Arg
.hasReturnedAttr()) {
11490 addValue(A
, getState(), Arg
, nullptr, AA::AnyScope
, F
);
11491 ReturnedArg
= &Arg
;
11494 if (!A
.isFunctionIPOAmendable(*F
) ||
11495 A
.hasSimplificationCallback(getIRPosition())) {
11497 indicatePessimisticFixpoint();
11499 indicateOptimisticFixpoint();
11503 /// See AbstractAttribute::updateImpl(...).
11504 ChangeStatus
updateImpl(Attributor
&A
) override
{
11505 auto AssumedBefore
= getAssumed();
11506 bool UsedAssumedInformation
= false;
11508 SmallVector
<AA::ValueAndContext
> Values
;
11509 Function
*AnchorScope
= getAnchorScope();
11510 auto HandleReturnedValue
= [&](Value
&V
, Instruction
*CtxI
,
11512 for (AA::ValueScope S
: {AA::Interprocedural
, AA::Intraprocedural
}) {
11514 if (!A
.getAssumedSimplifiedValues(IRPosition::value(V
), this, Values
, S
,
11515 UsedAssumedInformation
,
11516 /* RecurseForSelectAndPHI */ true))
11520 for (const AA::ValueAndContext
&VAC
: Values
)
11521 addValue(A
, getState(), *VAC
.getValue(),
11522 VAC
.getCtxI() ? VAC
.getCtxI() : CtxI
, S
, AnchorScope
);
11528 HandleReturnedValue(*ReturnedArg
, nullptr, true);
11530 auto RetInstPred
= [&](Instruction
&RetI
) {
11531 bool AddValues
= true;
11532 if (isa
<PHINode
>(RetI
.getOperand(0)) ||
11533 isa
<SelectInst
>(RetI
.getOperand(0))) {
11534 addValue(A
, getState(), *RetI
.getOperand(0), &RetI
, AA::AnyScope
,
11538 return HandleReturnedValue(*RetI
.getOperand(0), &RetI
, AddValues
);
11541 if (!A
.checkForAllInstructions(RetInstPred
, *this, {Instruction::Ret
},
11542 UsedAssumedInformation
,
11543 /* CheckBBLivenessOnly */ true))
11544 return indicatePessimisticFixpoint();
11547 return (AssumedBefore
== getAssumed()) ? ChangeStatus::UNCHANGED
11548 : ChangeStatus::CHANGED
;
11551 void addValue(Attributor
&A
, StateType
&State
, Value
&V
,
11552 const Instruction
*CtxI
, AA::ValueScope S
,
11553 Function
*AnchorScope
) const override
{
11554 Function
*F
= getAssociatedFunction();
11555 if (auto *CB
= dyn_cast
<CallBase
>(&V
))
11556 if (CB
->getCalledOperand() == F
)
11558 Base::addValue(A
, State
, V
, CtxI
, S
, AnchorScope
);
11561 ChangeStatus
manifest(Attributor
&A
) override
{
11563 return ChangeStatus::UNCHANGED
;
11564 SmallVector
<AA::ValueAndContext
> Values
;
11565 if (!getAssumedSimplifiedValues(A
, Values
, AA::ValueScope::Intraprocedural
,
11566 /* RecurseForSelectAndPHI */ true))
11567 return ChangeStatus::UNCHANGED
;
11568 Value
*NewVal
= getSingleValue(A
, *this, getIRPosition(), Values
);
11570 return ChangeStatus::UNCHANGED
;
11572 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
11573 if (auto *Arg
= dyn_cast
<Argument
>(NewVal
)) {
11574 STATS_DECLTRACK(UniqueReturnValue
, FunctionReturn
,
11575 "Number of function with unique return");
11576 Changed
|= A
.manifestAttrs(
11577 IRPosition::argument(*Arg
),
11578 {Attribute::get(Arg
->getContext(), Attribute::Returned
)});
11579 STATS_DECLTRACK_ARG_ATTR(returned
);
11582 auto RetInstPred
= [&](Instruction
&RetI
) {
11583 Value
*RetOp
= RetI
.getOperand(0);
11584 if (isa
<UndefValue
>(RetOp
) || RetOp
== NewVal
)
11586 if (AA::isValidAtPosition({*NewVal
, RetI
}, A
.getInfoCache()))
11587 if (A
.changeUseAfterManifest(RetI
.getOperandUse(0), *NewVal
))
11588 Changed
= ChangeStatus::CHANGED
;
11591 bool UsedAssumedInformation
= false;
11592 (void)A
.checkForAllInstructions(RetInstPred
, *this, {Instruction::Ret
},
11593 UsedAssumedInformation
,
11594 /* CheckBBLivenessOnly */ true);
11598 ChangeStatus
indicatePessimisticFixpoint() override
{
11599 return AAPotentialValues::indicatePessimisticFixpoint();
11602 /// See AbstractAttribute::trackStatistics()
11603 void trackStatistics() const override
{
11604 STATS_DECLTRACK_FNRET_ATTR(potential_values
)}
11606 /// The argumented with an existing `returned` attribute.
11607 Argument
*ReturnedArg
= nullptr;
11610 struct AAPotentialValuesFunction
: AAPotentialValuesImpl
{
11611 AAPotentialValuesFunction(const IRPosition
&IRP
, Attributor
&A
)
11612 : AAPotentialValuesImpl(IRP
, A
) {}
11614 /// See AbstractAttribute::updateImpl(...).
11615 ChangeStatus
updateImpl(Attributor
&A
) override
{
11616 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11620 /// See AbstractAttribute::trackStatistics()
11621 void trackStatistics() const override
{
11622 STATS_DECLTRACK_FN_ATTR(potential_values
)
11626 struct AAPotentialValuesCallSite
: AAPotentialValuesFunction
{
11627 AAPotentialValuesCallSite(const IRPosition
&IRP
, Attributor
&A
)
11628 : AAPotentialValuesFunction(IRP
, A
) {}
11630 /// See AbstractAttribute::trackStatistics()
11631 void trackStatistics() const override
{
11632 STATS_DECLTRACK_CS_ATTR(potential_values
)
11636 struct AAPotentialValuesCallSiteReturned
: AAPotentialValuesImpl
{
11637 AAPotentialValuesCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
11638 : AAPotentialValuesImpl(IRP
, A
) {}
11640 /// See AbstractAttribute::updateImpl(...).
11641 ChangeStatus
updateImpl(Attributor
&A
) override
{
11642 auto AssumedBefore
= getAssumed();
11644 Function
*Callee
= getAssociatedFunction();
11646 return indicatePessimisticFixpoint();
11648 bool UsedAssumedInformation
= false;
11649 auto *CB
= cast
<CallBase
>(getCtxI());
11650 if (CB
->isMustTailCall() &&
11651 !A
.isAssumedDead(IRPosition::inst(*CB
), this, nullptr,
11652 UsedAssumedInformation
))
11653 return indicatePessimisticFixpoint();
11655 SmallVector
<AA::ValueAndContext
> Values
;
11656 if (!A
.getAssumedSimplifiedValues(IRPosition::returned(*Callee
), this,
11657 Values
, AA::Intraprocedural
,
11658 UsedAssumedInformation
))
11659 return indicatePessimisticFixpoint();
11661 Function
*Caller
= CB
->getCaller();
11663 bool AnyNonLocal
= false;
11664 for (auto &It
: Values
) {
11665 Value
*V
= It
.getValue();
11666 std::optional
<Value
*> CallerV
= A
.translateArgumentToCallSiteContent(
11667 V
, *CB
, *this, UsedAssumedInformation
);
11668 if (!CallerV
.has_value()) {
11669 // Nothing to do as long as no value was determined.
11672 V
= *CallerV
? *CallerV
: V
;
11673 if (AA::isDynamicallyUnique(A
, *this, *V
) &&
11674 AA::isValidInScope(*V
, Caller
)) {
11676 SmallVector
<AA::ValueAndContext
> ArgValues
;
11677 IRPosition IRP
= IRPosition::value(*V
);
11678 if (auto *Arg
= dyn_cast
<Argument
>(V
))
11679 if (Arg
->getParent() == CB
->getCalledOperand())
11680 IRP
= IRPosition::callsite_argument(*CB
, Arg
->getArgNo());
11681 if (recurseForValue(A
, IRP
, AA::AnyScope
))
11684 addValue(A
, getState(), *V
, CB
, AA::AnyScope
, getAnchorScope());
11686 AnyNonLocal
= true;
11692 if (!A
.getAssumedSimplifiedValues(IRPosition::returned(*Callee
), this,
11693 Values
, AA::Interprocedural
,
11694 UsedAssumedInformation
))
11695 return indicatePessimisticFixpoint();
11696 AnyNonLocal
= false;
11697 getState() = PotentialLLVMValuesState::getBestState();
11698 for (auto &It
: Values
) {
11699 Value
*V
= It
.getValue();
11700 if (!AA::isDynamicallyUnique(A
, *this, *V
))
11701 return indicatePessimisticFixpoint();
11702 if (AA::isValidInScope(*V
, Caller
)) {
11703 addValue(A
, getState(), *V
, CB
, AA::AnyScope
, getAnchorScope());
11705 AnyNonLocal
= true;
11706 addValue(A
, getState(), *V
, CB
, AA::Interprocedural
,
11711 giveUpOnIntraprocedural(A
);
11713 return (AssumedBefore
== getAssumed()) ? ChangeStatus::UNCHANGED
11714 : ChangeStatus::CHANGED
;
11717 ChangeStatus
indicatePessimisticFixpoint() override
{
11718 return AAPotentialValues::indicatePessimisticFixpoint();
11721 /// See AbstractAttribute::trackStatistics()
11722 void trackStatistics() const override
{
11723 STATS_DECLTRACK_CSRET_ATTR(potential_values
)
11727 struct AAPotentialValuesCallSiteArgument
: AAPotentialValuesFloating
{
11728 AAPotentialValuesCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
11729 : AAPotentialValuesFloating(IRP
, A
) {}
11731 /// See AbstractAttribute::trackStatistics()
11732 void trackStatistics() const override
{
11733 STATS_DECLTRACK_CSARG_ATTR(potential_values
)
11738 /// ---------------------- Assumption Propagation ------------------------------
11740 struct AAAssumptionInfoImpl
: public AAAssumptionInfo
{
11741 AAAssumptionInfoImpl(const IRPosition
&IRP
, Attributor
&A
,
11742 const DenseSet
<StringRef
> &Known
)
11743 : AAAssumptionInfo(IRP
, A
, Known
) {}
11745 /// See AbstractAttribute::manifest(...).
11746 ChangeStatus
manifest(Attributor
&A
) override
{
11747 // Don't manifest a universal set if it somehow made it here.
11748 if (getKnown().isUniversal())
11749 return ChangeStatus::UNCHANGED
;
11751 const IRPosition
&IRP
= getIRPosition();
11752 return A
.manifestAttrs(
11754 Attribute::get(IRP
.getAnchorValue().getContext(), AssumptionAttrKey
,
11755 llvm::join(getAssumed().getSet(), ",")),
11756 /* ForceReplace */ true);
11759 bool hasAssumption(const StringRef Assumption
) const override
{
11760 return isValidState() && setContains(Assumption
);
11763 /// See AbstractAttribute::getAsStr()
11764 const std::string
getAsStr(Attributor
*A
) const override
{
11765 const SetContents
&Known
= getKnown();
11766 const SetContents
&Assumed
= getAssumed();
11768 const std::string KnownStr
=
11769 llvm::join(Known
.getSet().begin(), Known
.getSet().end(), ",");
11770 const std::string AssumedStr
=
11771 (Assumed
.isUniversal())
11773 : llvm::join(Assumed
.getSet().begin(), Assumed
.getSet().end(), ",");
11775 return "Known [" + KnownStr
+ "]," + " Assumed [" + AssumedStr
+ "]";
11779 /// Propagates assumption information from parent functions to all of their
11780 /// successors. An assumption can be propagated if the containing function
11781 /// dominates the called function.
11783 /// We start with a "known" set of assumptions already valid for the associated
11784 /// function and an "assumed" set that initially contains all possible
11785 /// assumptions. The assumed set is inter-procedurally updated by narrowing its
11786 /// contents as concrete values are known. The concrete values are seeded by the
11787 /// first nodes that are either entries into the call graph, or contains no
11788 /// assumptions. Each node is updated as the intersection of the assumed state
11789 /// with all of its predecessors.
11790 struct AAAssumptionInfoFunction final
: AAAssumptionInfoImpl
{
11791 AAAssumptionInfoFunction(const IRPosition
&IRP
, Attributor
&A
)
11792 : AAAssumptionInfoImpl(IRP
, A
,
11793 getAssumptions(*IRP
.getAssociatedFunction())) {}
11795 /// See AbstractAttribute::updateImpl(...).
11796 ChangeStatus
updateImpl(Attributor
&A
) override
{
11797 bool Changed
= false;
11799 auto CallSitePred
= [&](AbstractCallSite ACS
) {
11800 const auto *AssumptionAA
= A
.getAAFor
<AAAssumptionInfo
>(
11801 *this, IRPosition::callsite_function(*ACS
.getInstruction()),
11802 DepClassTy::REQUIRED
);
11805 // Get the set of assumptions shared by all of this function's callers.
11806 Changed
|= getIntersection(AssumptionAA
->getAssumed());
11807 return !getAssumed().empty() || !getKnown().empty();
11810 bool UsedAssumedInformation
= false;
11811 // Get the intersection of all assumptions held by this node's predecessors.
11812 // If we don't know all the call sites then this is either an entry into the
11813 // call graph or an empty node. This node is known to only contain its own
11814 // assumptions and can be propagated to its successors.
11815 if (!A
.checkForAllCallSites(CallSitePred
, *this, true,
11816 UsedAssumedInformation
))
11817 return indicatePessimisticFixpoint();
11819 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
11822 void trackStatistics() const override
{}
11825 /// Assumption Info defined for call sites.
11826 struct AAAssumptionInfoCallSite final
: AAAssumptionInfoImpl
{
11828 AAAssumptionInfoCallSite(const IRPosition
&IRP
, Attributor
&A
)
11829 : AAAssumptionInfoImpl(IRP
, A
, getInitialAssumptions(IRP
)) {}
11831 /// See AbstractAttribute::initialize(...).
11832 void initialize(Attributor
&A
) override
{
11833 const IRPosition
&FnPos
= IRPosition::function(*getAnchorScope());
11834 A
.getAAFor
<AAAssumptionInfo
>(*this, FnPos
, DepClassTy::REQUIRED
);
11837 /// See AbstractAttribute::updateImpl(...).
11838 ChangeStatus
updateImpl(Attributor
&A
) override
{
11839 const IRPosition
&FnPos
= IRPosition::function(*getAnchorScope());
11840 auto *AssumptionAA
=
11841 A
.getAAFor
<AAAssumptionInfo
>(*this, FnPos
, DepClassTy::REQUIRED
);
11843 return indicatePessimisticFixpoint();
11844 bool Changed
= getIntersection(AssumptionAA
->getAssumed());
11845 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
11848 /// See AbstractAttribute::trackStatistics()
11849 void trackStatistics() const override
{}
11852 /// Helper to initialized the known set as all the assumptions this call and
11853 /// the callee contain.
11854 DenseSet
<StringRef
> getInitialAssumptions(const IRPosition
&IRP
) {
11855 const CallBase
&CB
= cast
<CallBase
>(IRP
.getAssociatedValue());
11856 auto Assumptions
= getAssumptions(CB
);
11857 if (const Function
*F
= CB
.getCaller())
11858 set_union(Assumptions
, getAssumptions(*F
));
11859 if (Function
*F
= IRP
.getAssociatedFunction())
11860 set_union(Assumptions
, getAssumptions(*F
));
11861 return Assumptions
;
11866 AACallGraphNode
*AACallEdgeIterator::operator*() const {
11867 return static_cast<AACallGraphNode
*>(const_cast<AACallEdges
*>(
11868 A
.getOrCreateAAFor
<AACallEdges
>(IRPosition::function(**I
))));
11871 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); }
11873 /// ------------------------ UnderlyingObjects ---------------------------------
11876 struct AAUnderlyingObjectsImpl
11877 : StateWrapper
<BooleanState
, AAUnderlyingObjects
> {
11878 using BaseTy
= StateWrapper
<BooleanState
, AAUnderlyingObjects
>;
11879 AAUnderlyingObjectsImpl(const IRPosition
&IRP
, Attributor
&A
) : BaseTy(IRP
) {}
11881 /// See AbstractAttribute::getAsStr().
11882 const std::string
getAsStr(Attributor
*A
) const override
{
11883 return std::string("UnderlyingObjects ") +
11885 ? (std::string("inter #") +
11886 std::to_string(InterAssumedUnderlyingObjects
.size()) +
11887 " objs" + std::string(", intra #") +
11888 std::to_string(IntraAssumedUnderlyingObjects
.size()) +
11893 /// See AbstractAttribute::trackStatistics()
11894 void trackStatistics() const override
{}
11896 /// See AbstractAttribute::updateImpl(...).
11897 ChangeStatus
updateImpl(Attributor
&A
) override
{
11898 auto &Ptr
= getAssociatedValue();
11900 auto DoUpdate
= [&](SmallSetVector
<Value
*, 8> &UnderlyingObjects
,
11901 AA::ValueScope Scope
) {
11902 bool UsedAssumedInformation
= false;
11903 SmallPtrSet
<Value
*, 8> SeenObjects
;
11904 SmallVector
<AA::ValueAndContext
> Values
;
11906 if (!A
.getAssumedSimplifiedValues(IRPosition::value(Ptr
), *this, Values
,
11907 Scope
, UsedAssumedInformation
))
11908 return UnderlyingObjects
.insert(&Ptr
);
11910 bool Changed
= false;
11912 for (unsigned I
= 0; I
< Values
.size(); ++I
) {
11913 auto &VAC
= Values
[I
];
11914 auto *Obj
= VAC
.getValue();
11915 Value
*UO
= getUnderlyingObject(Obj
);
11916 if (UO
&& UO
!= VAC
.getValue() && SeenObjects
.insert(UO
).second
) {
11917 const auto *OtherAA
= A
.getAAFor
<AAUnderlyingObjects
>(
11918 *this, IRPosition::value(*UO
), DepClassTy::OPTIONAL
);
11919 auto Pred
= [&Values
](Value
&V
) {
11920 Values
.emplace_back(V
, nullptr);
11924 if (!OtherAA
|| !OtherAA
->forallUnderlyingObjects(Pred
, Scope
))
11926 "The forall call should not return false at this position");
11931 if (isa
<SelectInst
>(Obj
)) {
11932 Changed
|= handleIndirect(A
, *Obj
, UnderlyingObjects
, Scope
);
11935 if (auto *PHI
= dyn_cast
<PHINode
>(Obj
)) {
11936 // Explicitly look through PHIs as we do not care about dynamically
11938 for (unsigned u
= 0, e
= PHI
->getNumIncomingValues(); u
< e
; u
++) {
11939 Changed
|= handleIndirect(A
, *PHI
->getIncomingValue(u
),
11940 UnderlyingObjects
, Scope
);
11945 Changed
|= UnderlyingObjects
.insert(Obj
);
11951 bool Changed
= false;
11952 Changed
|= DoUpdate(IntraAssumedUnderlyingObjects
, AA::Intraprocedural
);
11953 Changed
|= DoUpdate(InterAssumedUnderlyingObjects
, AA::Interprocedural
);
11955 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
11958 bool forallUnderlyingObjects(
11959 function_ref
<bool(Value
&)> Pred
,
11960 AA::ValueScope Scope
= AA::Interprocedural
) const override
{
11961 if (!isValidState())
11962 return Pred(getAssociatedValue());
11964 auto &AssumedUnderlyingObjects
= Scope
== AA::Intraprocedural
11965 ? IntraAssumedUnderlyingObjects
11966 : InterAssumedUnderlyingObjects
;
11967 for (Value
*Obj
: AssumedUnderlyingObjects
)
11975 /// Handle the case where the value is not the actual underlying value, such
11976 /// as a phi node or a select instruction.
11977 bool handleIndirect(Attributor
&A
, Value
&V
,
11978 SmallSetVector
<Value
*, 8> &UnderlyingObjects
,
11979 AA::ValueScope Scope
) {
11980 bool Changed
= false;
11981 const auto *AA
= A
.getAAFor
<AAUnderlyingObjects
>(
11982 *this, IRPosition::value(V
), DepClassTy::OPTIONAL
);
11983 auto Pred
= [&](Value
&V
) {
11984 Changed
|= UnderlyingObjects
.insert(&V
);
11987 if (!AA
|| !AA
->forallUnderlyingObjects(Pred
, Scope
))
11989 "The forall call should not return false at this position");
11993 /// All the underlying objects collected so far via intra procedural scope.
11994 SmallSetVector
<Value
*, 8> IntraAssumedUnderlyingObjects
;
11995 /// All the underlying objects collected so far via inter procedural scope.
11996 SmallSetVector
<Value
*, 8> InterAssumedUnderlyingObjects
;
11999 struct AAUnderlyingObjectsFloating final
: AAUnderlyingObjectsImpl
{
12000 AAUnderlyingObjectsFloating(const IRPosition
&IRP
, Attributor
&A
)
12001 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12004 struct AAUnderlyingObjectsArgument final
: AAUnderlyingObjectsImpl
{
12005 AAUnderlyingObjectsArgument(const IRPosition
&IRP
, Attributor
&A
)
12006 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12009 struct AAUnderlyingObjectsCallSite final
: AAUnderlyingObjectsImpl
{
12010 AAUnderlyingObjectsCallSite(const IRPosition
&IRP
, Attributor
&A
)
12011 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12014 struct AAUnderlyingObjectsCallSiteArgument final
: AAUnderlyingObjectsImpl
{
12015 AAUnderlyingObjectsCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
12016 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12019 struct AAUnderlyingObjectsReturned final
: AAUnderlyingObjectsImpl
{
12020 AAUnderlyingObjectsReturned(const IRPosition
&IRP
, Attributor
&A
)
12021 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12024 struct AAUnderlyingObjectsCallSiteReturned final
: AAUnderlyingObjectsImpl
{
12025 AAUnderlyingObjectsCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
12026 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12029 struct AAUnderlyingObjectsFunction final
: AAUnderlyingObjectsImpl
{
12030 AAUnderlyingObjectsFunction(const IRPosition
&IRP
, Attributor
&A
)
12031 : AAUnderlyingObjectsImpl(IRP
, A
) {}
12035 /// ------------------------ Global Value Info -------------------------------
12037 struct AAGlobalValueInfoFloating
: public AAGlobalValueInfo
{
12038 AAGlobalValueInfoFloating(const IRPosition
&IRP
, Attributor
&A
)
12039 : AAGlobalValueInfo(IRP
, A
) {}
12041 /// See AbstractAttribute::initialize(...).
12042 void initialize(Attributor
&A
) override
{}
12044 bool checkUse(Attributor
&A
, const Use
&U
, bool &Follow
,
12045 SmallVectorImpl
<const Value
*> &Worklist
) {
12046 Instruction
*UInst
= dyn_cast
<Instruction
>(U
.getUser());
12052 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U
.get() << " in "
12053 << *UInst
<< "\n");
12055 if (auto *Cmp
= dyn_cast
<ICmpInst
>(U
.getUser())) {
12056 int Idx
= &Cmp
->getOperandUse(0) == &U
;
12057 if (isa
<Constant
>(Cmp
->getOperand(Idx
)))
12059 return U
== &getAnchorValue();
12062 // Explicitly catch return instructions.
12063 if (isa
<ReturnInst
>(UInst
)) {
12064 auto CallSitePred
= [&](AbstractCallSite ACS
) {
12065 Worklist
.push_back(ACS
.getInstruction());
12068 bool UsedAssumedInformation
= false;
12069 // TODO: We should traverse the uses or add a "non-call-site" CB.
12070 if (!A
.checkForAllCallSites(CallSitePred
, *UInst
->getFunction(),
12071 /*RequireAllCallSites=*/true, this,
12072 UsedAssumedInformation
))
12077 // For now we only use special logic for call sites. However, the tracker
12078 // itself knows about a lot of other non-capturing cases already.
12079 auto *CB
= dyn_cast
<CallBase
>(UInst
);
12082 // Direct calls are OK uses.
12083 if (CB
->isCallee(&U
))
12085 // Non-argument uses are scary.
12086 if (!CB
->isArgOperand(&U
))
12088 // TODO: Iterate callees.
12089 auto *Fn
= dyn_cast
<Function
>(CB
->getCalledOperand());
12090 if (!Fn
|| !A
.isFunctionIPOAmendable(*Fn
))
12093 unsigned ArgNo
= CB
->getArgOperandNo(&U
);
12094 Worklist
.push_back(Fn
->getArg(ArgNo
));
12098 ChangeStatus
updateImpl(Attributor
&A
) override
{
12099 unsigned NumUsesBefore
= Uses
.size();
12101 SmallPtrSet
<const Value
*, 8> Visited
;
12102 SmallVector
<const Value
*> Worklist
;
12103 Worklist
.push_back(&getAnchorValue());
12105 auto UsePred
= [&](const Use
&U
, bool &Follow
) -> bool {
12107 switch (DetermineUseCaptureKind(U
, nullptr)) {
12108 case UseCaptureKind::NO_CAPTURE
:
12109 return checkUse(A
, U
, Follow
, Worklist
);
12110 case UseCaptureKind::MAY_CAPTURE
:
12111 return checkUse(A
, U
, Follow
, Worklist
);
12112 case UseCaptureKind::PASSTHROUGH
:
12118 auto EquivalentUseCB
= [&](const Use
&OldU
, const Use
&NewU
) {
12119 Uses
.insert(&OldU
);
12123 while (!Worklist
.empty()) {
12124 const Value
*V
= Worklist
.pop_back_val();
12125 if (!Visited
.insert(V
).second
)
12127 if (!A
.checkForAllUses(UsePred
, *this, *V
,
12128 /* CheckBBLivenessOnly */ true,
12129 DepClassTy::OPTIONAL
,
12130 /* IgnoreDroppableUses */ true, EquivalentUseCB
)) {
12131 return indicatePessimisticFixpoint();
12135 return Uses
.size() == NumUsesBefore
? ChangeStatus::UNCHANGED
12136 : ChangeStatus::CHANGED
;
12139 bool isPotentialUse(const Use
&U
) const override
{
12140 return !isValidState() || Uses
.contains(&U
);
12143 /// See AbstractAttribute::manifest(...).
12144 ChangeStatus
manifest(Attributor
&A
) override
{
12145 return ChangeStatus::UNCHANGED
;
12148 /// See AbstractAttribute::getAsStr().
12149 const std::string
getAsStr(Attributor
*A
) const override
{
12150 return "[" + std::to_string(Uses
.size()) + " uses]";
12153 void trackStatistics() const override
{
12154 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked
);
12158 /// Set of (transitive) uses of this GlobalValue.
12159 SmallPtrSet
<const Use
*, 8> Uses
;
12163 /// ------------------------ Indirect Call Info -------------------------------
12165 struct AAIndirectCallInfoCallSite
: public AAIndirectCallInfo
{
12166 AAIndirectCallInfoCallSite(const IRPosition
&IRP
, Attributor
&A
)
12167 : AAIndirectCallInfo(IRP
, A
) {}
12169 /// See AbstractAttribute::initialize(...).
12170 void initialize(Attributor
&A
) override
{
12171 auto *MD
= getCtxI()->getMetadata(LLVMContext::MD_callees
);
12172 if (!MD
&& !A
.isClosedWorldModule())
12176 for (const auto &Op
: MD
->operands())
12177 if (Function
*Callee
= mdconst::dyn_extract_or_null
<Function
>(Op
))
12178 PotentialCallees
.insert(Callee
);
12179 } else if (A
.isClosedWorldModule()) {
12180 ArrayRef
<Function
*> IndirectlyCallableFunctions
=
12181 A
.getInfoCache().getIndirectlyCallableFunctions(A
);
12182 PotentialCallees
.insert(IndirectlyCallableFunctions
.begin(),
12183 IndirectlyCallableFunctions
.end());
12186 if (PotentialCallees
.empty())
12187 indicateOptimisticFixpoint();
12190 ChangeStatus
updateImpl(Attributor
&A
) override
{
12191 CallBase
*CB
= cast
<CallBase
>(getCtxI());
12192 const Use
&CalleeUse
= CB
->getCalledOperandUse();
12193 Value
*FP
= CB
->getCalledOperand();
12195 SmallSetVector
<Function
*, 4> AssumedCalleesNow
;
12196 bool AllCalleesKnownNow
= AllCalleesKnown
;
12198 auto CheckPotentialCalleeUse
= [&](Function
&PotentialCallee
,
12199 bool &UsedAssumedInformation
) {
12200 const auto *GIAA
= A
.getAAFor
<AAGlobalValueInfo
>(
12201 *this, IRPosition::value(PotentialCallee
), DepClassTy::OPTIONAL
);
12202 if (!GIAA
|| GIAA
->isPotentialUse(CalleeUse
))
12204 UsedAssumedInformation
= !GIAA
->isAtFixpoint();
12208 auto AddPotentialCallees
= [&]() {
12209 for (auto *PotentialCallee
: PotentialCallees
) {
12210 bool UsedAssumedInformation
= false;
12211 if (CheckPotentialCalleeUse(*PotentialCallee
, UsedAssumedInformation
))
12212 AssumedCalleesNow
.insert(PotentialCallee
);
12216 // Use simplification to find potential callees, if !callees was present,
12217 // fallback to that set if necessary.
12218 bool UsedAssumedInformation
= false;
12219 SmallVector
<AA::ValueAndContext
> Values
;
12220 if (!A
.getAssumedSimplifiedValues(IRPosition::value(*FP
), this, Values
,
12221 AA::ValueScope::AnyScope
,
12222 UsedAssumedInformation
)) {
12223 if (PotentialCallees
.empty())
12224 return indicatePessimisticFixpoint();
12225 AddPotentialCallees();
12228 // Try to find a reason for \p Fn not to be a potential callee. If none was
12229 // found, add it to the assumed callees set.
12230 auto CheckPotentialCallee
= [&](Function
&Fn
) {
12231 if (!PotentialCallees
.empty() && !PotentialCallees
.count(&Fn
))
12234 auto &CachedResult
= FilterResults
[&Fn
];
12235 if (CachedResult
.has_value())
12236 return CachedResult
.value();
12238 bool UsedAssumedInformation
= false;
12239 if (!CheckPotentialCalleeUse(Fn
, UsedAssumedInformation
)) {
12240 if (!UsedAssumedInformation
)
12241 CachedResult
= false;
12245 int NumFnArgs
= Fn
.arg_size();
12246 int NumCBArgs
= CB
->arg_size();
12248 // Check if any excess argument (which we fill up with poison) is known to
12250 for (int I
= NumCBArgs
; I
< NumFnArgs
; ++I
) {
12251 bool IsKnown
= false;
12252 if (AA::hasAssumedIRAttr
<Attribute::NoUndef
>(
12253 A
, this, IRPosition::argument(*Fn
.getArg(I
)),
12254 DepClassTy::OPTIONAL
, IsKnown
)) {
12256 CachedResult
= false;
12261 CachedResult
= true;
12265 // Check simplification result, prune known UB callees, also restrict it to
12266 // the !callees set, if present.
12267 for (auto &VAC
: Values
) {
12268 if (isa
<UndefValue
>(VAC
.getValue()))
12270 if (isa
<ConstantPointerNull
>(VAC
.getValue()) &&
12271 VAC
.getValue()->getType()->getPointerAddressSpace() == 0)
12273 // TODO: Check for known UB, e.g., poison + noundef.
12274 if (auto *VACFn
= dyn_cast
<Function
>(VAC
.getValue())) {
12275 if (CheckPotentialCallee(*VACFn
))
12276 AssumedCalleesNow
.insert(VACFn
);
12279 if (!PotentialCallees
.empty()) {
12280 AddPotentialCallees();
12283 AllCalleesKnownNow
= false;
12286 if (AssumedCalleesNow
== AssumedCallees
&&
12287 AllCalleesKnown
== AllCalleesKnownNow
)
12288 return ChangeStatus::UNCHANGED
;
12290 std::swap(AssumedCallees
, AssumedCalleesNow
);
12291 AllCalleesKnown
= AllCalleesKnownNow
;
12292 return ChangeStatus::CHANGED
;
12295 /// See AbstractAttribute::manifest(...).
12296 ChangeStatus
manifest(Attributor
&A
) override
{
12297 // If we can't specialize at all, give up now.
12298 if (!AllCalleesKnown
&& AssumedCallees
.empty())
12299 return ChangeStatus::UNCHANGED
;
12301 CallBase
*CB
= cast
<CallBase
>(getCtxI());
12302 bool UsedAssumedInformation
= false;
12303 if (A
.isAssumedDead(*CB
, this, /*LivenessAA=*/nullptr,
12304 UsedAssumedInformation
))
12305 return ChangeStatus::UNCHANGED
;
12307 ChangeStatus Changed
= ChangeStatus::UNCHANGED
;
12308 Value
*FP
= CB
->getCalledOperand();
12309 if (FP
->getType()->getPointerAddressSpace())
12310 FP
= new AddrSpaceCastInst(FP
, PointerType::get(FP
->getType(), 0),
12311 FP
->getName() + ".as0", CB
);
12313 bool CBIsVoid
= CB
->getType()->isVoidTy();
12314 Instruction
*IP
= CB
;
12315 FunctionType
*CSFT
= CB
->getFunctionType();
12316 SmallVector
<Value
*> CSArgs(CB
->arg_begin(), CB
->arg_end());
12318 // If we know all callees and there are none, the call site is (effectively)
12320 if (AssumedCallees
.empty()) {
12321 assert(AllCalleesKnown
&&
12322 "Expected all callees to be known if there are none.");
12323 A
.changeToUnreachableAfterManifest(CB
);
12324 return ChangeStatus::CHANGED
;
12327 // Special handling for the single callee case.
12328 if (AllCalleesKnown
&& AssumedCallees
.size() == 1) {
12329 auto *NewCallee
= AssumedCallees
.front();
12330 if (isLegalToPromote(*CB
, NewCallee
)) {
12331 promoteCall(*CB
, NewCallee
, nullptr);
12332 return ChangeStatus::CHANGED
;
12334 Instruction
*NewCall
= CallInst::Create(FunctionCallee(CSFT
, NewCallee
),
12335 CSArgs
, CB
->getName(), CB
);
12337 A
.changeAfterManifest(IRPosition::callsite_returned(*CB
), *NewCall
);
12338 A
.deleteAfterManifest(*CB
);
12339 return ChangeStatus::CHANGED
;
12342 // For each potential value we create a conditional
12345 // if (ptr == value) value(args);
12349 bool SpecializedForAnyCallees
= false;
12350 bool SpecializedForAllCallees
= AllCalleesKnown
;
12351 ICmpInst
*LastCmp
= nullptr;
12352 SmallVector
<Function
*, 8> SkippedAssumedCallees
;
12353 SmallVector
<std::pair
<CallInst
*, Instruction
*>> NewCalls
;
12354 for (Function
*NewCallee
: AssumedCallees
) {
12355 if (!A
.shouldSpecializeCallSiteForCallee(*this, *CB
, *NewCallee
)) {
12356 SkippedAssumedCallees
.push_back(NewCallee
);
12357 SpecializedForAllCallees
= false;
12360 SpecializedForAnyCallees
= true;
12362 LastCmp
= new ICmpInst(IP
, llvm::CmpInst::ICMP_EQ
, FP
, NewCallee
);
12363 Instruction
*ThenTI
=
12364 SplitBlockAndInsertIfThen(LastCmp
, IP
, /* Unreachable */ false);
12365 BasicBlock
*CBBB
= CB
->getParent();
12366 auto *SplitTI
= cast
<BranchInst
>(LastCmp
->getNextNode());
12367 BasicBlock
*ElseBB
;
12369 ElseBB
= BasicBlock::Create(ThenTI
->getContext(), "",
12370 ThenTI
->getFunction(), CBBB
);
12371 IP
= BranchInst::Create(CBBB
, ElseBB
);
12372 SplitTI
->replaceUsesOfWith(CBBB
, ElseBB
);
12374 ElseBB
= IP
->getParent();
12375 ThenTI
->replaceUsesOfWith(ElseBB
, CBBB
);
12377 CastInst
*RetBC
= nullptr;
12378 CallInst
*NewCall
= nullptr;
12379 if (isLegalToPromote(*CB
, NewCallee
)) {
12380 auto *CBClone
= cast
<CallBase
>(CB
->clone());
12381 CBClone
->insertBefore(ThenTI
);
12382 NewCall
= &cast
<CallInst
>(promoteCall(*CBClone
, NewCallee
, &RetBC
));
12384 NewCall
= CallInst::Create(FunctionCallee(CSFT
, NewCallee
), CSArgs
,
12385 CB
->getName(), ThenTI
);
12387 NewCalls
.push_back({NewCall
, RetBC
});
12390 auto AttachCalleeMetadata
= [&](CallBase
&IndirectCB
) {
12391 if (!AllCalleesKnown
)
12392 return ChangeStatus::UNCHANGED
;
12393 MDBuilder
MDB(IndirectCB
.getContext());
12394 MDNode
*Callees
= MDB
.createCallees(SkippedAssumedCallees
);
12395 IndirectCB
.setMetadata(LLVMContext::MD_callees
, Callees
);
12396 return ChangeStatus::CHANGED
;
12399 if (!SpecializedForAnyCallees
)
12400 return AttachCalleeMetadata(*CB
);
12402 // Check if we need the fallback indirect call still.
12403 if (SpecializedForAllCallees
) {
12404 LastCmp
->replaceAllUsesWith(ConstantInt::getTrue(LastCmp
->getContext()));
12405 LastCmp
->eraseFromParent();
12406 new UnreachableInst(IP
->getContext(), IP
);
12407 IP
->eraseFromParent();
12409 auto *CBClone
= cast
<CallInst
>(CB
->clone());
12410 CBClone
->setName(CB
->getName());
12411 CBClone
->insertBefore(IP
);
12412 NewCalls
.push_back({CBClone
, nullptr});
12413 AttachCalleeMetadata(*CBClone
);
12416 // Check if we need a PHI to merge the results.
12418 auto *PHI
= PHINode::Create(CB
->getType(), NewCalls
.size(),
12419 CB
->getName() + ".phi",
12420 &*CB
->getParent()->getFirstInsertionPt());
12421 for (auto &It
: NewCalls
) {
12422 CallBase
*NewCall
= It
.first
;
12423 Instruction
*CallRet
= It
.second
? It
.second
: It
.first
;
12424 if (CallRet
->getType() == CB
->getType())
12425 PHI
->addIncoming(CallRet
, CallRet
->getParent());
12426 else if (NewCall
->getType()->isVoidTy())
12427 PHI
->addIncoming(PoisonValue::get(CB
->getType()),
12428 NewCall
->getParent());
12430 llvm_unreachable("Call return should match or be void!");
12432 A
.changeAfterManifest(IRPosition::callsite_returned(*CB
), *PHI
);
12435 A
.deleteAfterManifest(*CB
);
12436 Changed
= ChangeStatus::CHANGED
;
12441 /// See AbstractAttribute::getAsStr().
12442 const std::string
getAsStr(Attributor
*A
) const override
{
12443 return std::string(AllCalleesKnown
? "eliminate" : "specialize") +
12444 " indirect call site with " + std::to_string(AssumedCallees
.size()) +
12448 void trackStatistics() const override
{
12449 if (AllCalleesKnown
) {
12451 Eliminated
, CallSites
,
12452 "Number of indirect call sites eliminated via specialization")
12454 STATS_DECLTRACK(Specialized
, CallSites
,
12455 "Number of indirect call sites specialized")
12459 bool foreachCallee(function_ref
<bool(Function
*)> CB
) const override
{
12460 return isValidState() && AllCalleesKnown
&& all_of(AssumedCallees
, CB
);
12464 /// Map to remember filter results.
12465 DenseMap
<Function
*, std::optional
<bool>> FilterResults
;
12467 /// If the !callee metadata was present, this set will contain all potential
12468 /// callees (superset).
12469 SmallSetVector
<Function
*, 4> PotentialCallees
;
12471 /// This set contains all currently assumed calllees, which might grow over
12473 SmallSetVector
<Function
*, 4> AssumedCallees
;
12475 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12476 /// if there could be others.
12477 bool AllCalleesKnown
= true;
12481 /// ------------------------ Address Space ------------------------------------
12483 struct AAAddressSpaceImpl
: public AAAddressSpace
{
12484 AAAddressSpaceImpl(const IRPosition
&IRP
, Attributor
&A
)
12485 : AAAddressSpace(IRP
, A
) {}
12487 int32_t getAddressSpace() const override
{
12488 assert(isValidState() && "the AA is invalid");
12489 return AssumedAddressSpace
;
12492 /// See AbstractAttribute::initialize(...).
12493 void initialize(Attributor
&A
) override
{
12494 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12495 "Associated value is not a pointer");
12498 ChangeStatus
updateImpl(Attributor
&A
) override
{
12499 int32_t OldAddressSpace
= AssumedAddressSpace
;
12500 auto *AUO
= A
.getOrCreateAAFor
<AAUnderlyingObjects
>(getIRPosition(), this,
12501 DepClassTy::REQUIRED
);
12502 auto Pred
= [&](Value
&Obj
) {
12503 if (isa
<UndefValue
>(&Obj
))
12505 return takeAddressSpace(Obj
.getType()->getPointerAddressSpace());
12508 if (!AUO
->forallUnderlyingObjects(Pred
))
12509 return indicatePessimisticFixpoint();
12511 return OldAddressSpace
== AssumedAddressSpace
? ChangeStatus::UNCHANGED
12512 : ChangeStatus::CHANGED
;
12515 /// See AbstractAttribute::manifest(...).
12516 ChangeStatus
manifest(Attributor
&A
) override
{
12517 Value
*AssociatedValue
= &getAssociatedValue();
12518 Value
*OriginalValue
= peelAddrspacecast(AssociatedValue
);
12519 if (getAddressSpace() == NoAddressSpace
||
12520 static_cast<uint32_t>(getAddressSpace()) ==
12521 getAssociatedType()->getPointerAddressSpace())
12522 return ChangeStatus::UNCHANGED
;
12524 Type
*NewPtrTy
= PointerType::get(getAssociatedType()->getContext(),
12525 static_cast<uint32_t>(getAddressSpace()));
12526 bool UseOriginalValue
=
12527 OriginalValue
->getType()->getPointerAddressSpace() ==
12528 static_cast<uint32_t>(getAddressSpace());
12530 bool Changed
= false;
12532 auto MakeChange
= [&](Instruction
*I
, Use
&U
) {
12534 if (UseOriginalValue
) {
12535 A
.changeUseAfterManifest(U
, *OriginalValue
);
12538 Instruction
*CastInst
= new AddrSpaceCastInst(OriginalValue
, NewPtrTy
);
12539 CastInst
->insertBefore(cast
<Instruction
>(I
));
12540 A
.changeUseAfterManifest(U
, *CastInst
);
12543 auto Pred
= [&](const Use
&U
, bool &) {
12544 if (U
.get() != AssociatedValue
)
12546 auto *Inst
= dyn_cast
<Instruction
>(U
.getUser());
12549 // This is a WA to make sure we only change uses from the corresponding
12550 // CGSCC if the AA is run on CGSCC instead of the entire module.
12551 if (!A
.isRunOn(Inst
->getFunction()))
12553 if (isa
<LoadInst
>(Inst
))
12554 MakeChange(Inst
, const_cast<Use
&>(U
));
12555 if (auto *SI
= dyn_cast
<StoreInst
>(Inst
)) {
12556 // We only make changes if the use is the pointer operand.
12557 if (U
.getOperandNo() == 1)
12558 MakeChange(Inst
, const_cast<Use
&>(U
));
12563 // It doesn't matter if we can't check all uses as we can simply
12564 // conservatively ignore those that can not be visited.
12565 (void)A
.checkForAllUses(Pred
, *this, getAssociatedValue(),
12566 /* CheckBBLivenessOnly */ true);
12568 return Changed
? ChangeStatus::CHANGED
: ChangeStatus::UNCHANGED
;
12571 /// See AbstractAttribute::getAsStr().
12572 const std::string
getAsStr(Attributor
*A
) const override
{
12573 if (!isValidState())
12574 return "addrspace(<invalid>)";
12575 return "addrspace(" +
12576 (AssumedAddressSpace
== NoAddressSpace
12578 : std::to_string(AssumedAddressSpace
)) +
12583 int32_t AssumedAddressSpace
= NoAddressSpace
;
12585 bool takeAddressSpace(int32_t AS
) {
12586 if (AssumedAddressSpace
== NoAddressSpace
) {
12587 AssumedAddressSpace
= AS
;
12590 return AssumedAddressSpace
== AS
;
12593 static Value
*peelAddrspacecast(Value
*V
) {
12594 if (auto *I
= dyn_cast
<AddrSpaceCastInst
>(V
))
12595 return peelAddrspacecast(I
->getPointerOperand());
12596 if (auto *C
= dyn_cast
<ConstantExpr
>(V
))
12597 if (C
->getOpcode() == Instruction::AddrSpaceCast
)
12598 return peelAddrspacecast(C
->getOperand(0));
12603 struct AAAddressSpaceFloating final
: AAAddressSpaceImpl
{
12604 AAAddressSpaceFloating(const IRPosition
&IRP
, Attributor
&A
)
12605 : AAAddressSpaceImpl(IRP
, A
) {}
12607 void trackStatistics() const override
{
12608 STATS_DECLTRACK_FLOATING_ATTR(addrspace
);
12612 struct AAAddressSpaceReturned final
: AAAddressSpaceImpl
{
12613 AAAddressSpaceReturned(const IRPosition
&IRP
, Attributor
&A
)
12614 : AAAddressSpaceImpl(IRP
, A
) {}
12616 /// See AbstractAttribute::initialize(...).
12617 void initialize(Attributor
&A
) override
{
12618 // TODO: we don't rewrite function argument for now because it will need to
12619 // rewrite the function signature and all call sites.
12620 (void)indicatePessimisticFixpoint();
12623 void trackStatistics() const override
{
12624 STATS_DECLTRACK_FNRET_ATTR(addrspace
);
12628 struct AAAddressSpaceCallSiteReturned final
: AAAddressSpaceImpl
{
12629 AAAddressSpaceCallSiteReturned(const IRPosition
&IRP
, Attributor
&A
)
12630 : AAAddressSpaceImpl(IRP
, A
) {}
12632 void trackStatistics() const override
{
12633 STATS_DECLTRACK_CSRET_ATTR(addrspace
);
12637 struct AAAddressSpaceArgument final
: AAAddressSpaceImpl
{
12638 AAAddressSpaceArgument(const IRPosition
&IRP
, Attributor
&A
)
12639 : AAAddressSpaceImpl(IRP
, A
) {}
12641 void trackStatistics() const override
{ STATS_DECLTRACK_ARG_ATTR(addrspace
); }
12644 struct AAAddressSpaceCallSiteArgument final
: AAAddressSpaceImpl
{
12645 AAAddressSpaceCallSiteArgument(const IRPosition
&IRP
, Attributor
&A
)
12646 : AAAddressSpaceImpl(IRP
, A
) {}
12648 /// See AbstractAttribute::initialize(...).
12649 void initialize(Attributor
&A
) override
{
12650 // TODO: we don't rewrite call site argument for now because it will need to
12651 // rewrite the function signature of the callee.
12652 (void)indicatePessimisticFixpoint();
12655 void trackStatistics() const override
{
12656 STATS_DECLTRACK_CSARG_ATTR(addrspace
);
12661 const char AANoUnwind::ID
= 0;
12662 const char AANoSync::ID
= 0;
12663 const char AANoFree::ID
= 0;
12664 const char AANonNull::ID
= 0;
12665 const char AAMustProgress::ID
= 0;
12666 const char AANoRecurse::ID
= 0;
12667 const char AANonConvergent::ID
= 0;
12668 const char AAWillReturn::ID
= 0;
12669 const char AAUndefinedBehavior::ID
= 0;
12670 const char AANoAlias::ID
= 0;
12671 const char AAIntraFnReachability::ID
= 0;
12672 const char AANoReturn::ID
= 0;
12673 const char AAIsDead::ID
= 0;
12674 const char AADereferenceable::ID
= 0;
12675 const char AAAlign::ID
= 0;
12676 const char AAInstanceInfo::ID
= 0;
12677 const char AANoCapture::ID
= 0;
12678 const char AAValueSimplify::ID
= 0;
12679 const char AAHeapToStack::ID
= 0;
12680 const char AAPrivatizablePtr::ID
= 0;
12681 const char AAMemoryBehavior::ID
= 0;
12682 const char AAMemoryLocation::ID
= 0;
12683 const char AAValueConstantRange::ID
= 0;
12684 const char AAPotentialConstantValues::ID
= 0;
12685 const char AAPotentialValues::ID
= 0;
12686 const char AANoUndef::ID
= 0;
12687 const char AANoFPClass::ID
= 0;
12688 const char AACallEdges::ID
= 0;
12689 const char AAInterFnReachability::ID
= 0;
12690 const char AAPointerInfo::ID
= 0;
12691 const char AAAssumptionInfo::ID
= 0;
12692 const char AAUnderlyingObjects::ID
= 0;
12693 const char AAAddressSpace::ID
= 0;
12694 const char AAIndirectCallInfo::ID
= 0;
12695 const char AAGlobalValueInfo::ID
= 0;
12696 const char AADenormalFPMath::ID
= 0;
12698 // Macro magic to create the static generator function for attributes that
12699 // follow the naming scheme.
12701 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
12702 case IRPosition::PK: \
12703 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
12705 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
12706 case IRPosition::PK: \
12707 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
12711 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12712 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12713 CLASS *AA = nullptr; \
12714 switch (IRP.getPositionKind()) { \
12715 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12716 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12717 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12718 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12719 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
12720 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
12721 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12722 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12727 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12728 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12729 CLASS *AA = nullptr; \
12730 switch (IRP.getPositionKind()) { \
12731 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12732 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
12733 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
12734 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12735 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12736 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12737 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12738 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12743 #define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
12744 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12745 CLASS *AA = nullptr; \
12746 switch (IRP.getPositionKind()) { \
12747 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
12749 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
12755 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12756 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12757 CLASS *AA = nullptr; \
12758 switch (IRP.getPositionKind()) { \
12759 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12760 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12761 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12762 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12763 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12764 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
12765 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12766 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12771 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12772 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12773 CLASS *AA = nullptr; \
12774 switch (IRP.getPositionKind()) { \
12775 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12776 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
12777 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
12778 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12779 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
12780 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
12781 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
12782 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12787 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
12788 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
12789 CLASS *AA = nullptr; \
12790 switch (IRP.getPositionKind()) { \
12791 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
12792 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
12793 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
12794 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
12795 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
12796 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
12797 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
12798 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
12803 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind
)
12804 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync
)
12805 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse
)
12806 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn
)
12807 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn
)
12808 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation
)
12809 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges
)
12810 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo
)
12811 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMustProgress
)
12813 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull
)
12814 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias
)
12815 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr
)
12816 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable
)
12817 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign
)
12818 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo
)
12819 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture
)
12820 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange
)
12821 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues
)
12822 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues
)
12823 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef
)
12824 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass
)
12825 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo
)
12826 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace
)
12828 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify
)
12829 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead
)
12830 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree
)
12831 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects
)
12833 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_CALL_SITE
, CallSite
,
12834 AAIndirectCallInfo
)
12835 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_FLOAT
, Floating
,
12838 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack
)
12839 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior
)
12840 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent
)
12841 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability
)
12842 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability
)
12843 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADenormalFPMath
)
12845 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior
)
12847 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
12848 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
12849 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
12850 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
12851 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
12852 #undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
12853 #undef SWITCH_PK_CREATE
12854 #undef SWITCH_PK_INV