[AMDGPU] Test codegen'ing True16 additions.
[llvm-project.git] / llvm / lib / Transforms / IPO / AttributorAttributes.cpp
blob03b5dc3899ac8f8bb7520abc1969f21c081bd353
1 //===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // See the Attributor.h file comment and the class descriptions in that file for
10 // more information.
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"
73 #include <cassert>
74 #include <numeric>
75 #include <optional>
76 #include <string>
78 using namespace llvm;
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."),
85 cl::init(false));
87 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
88 cl::Hidden);
90 template <>
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),
100 cl::init(7));
102 static cl::opt<int> MaxPotentialValuesIterations(
103 "attributor-max-potential-values-iterations", cl::Hidden,
104 cl::desc(
105 "Maximum number of iterations we keep dismantling potential values."),
106 cl::init(64));
108 STATISTIC(NumAAs, "Number of abstract attributes created");
110 // Some helper macros to deal with statistics tracking.
112 // Usage:
113 // For simple IR attribute tracking overload trackStatistics in the abstract
114 // attribute and choose the right STATS_DECLTRACK_********* macro,
115 // e.g.,:
116 // void trackStatistics() const override {
117 // STATS_DECLTRACK_ARG_ATTR(returned)
118 // }
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.
156 namespace llvm {
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)
199 #undef PIPE_OPERATOR
201 template <>
202 ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
203 const DerefState &R) {
204 ChangeStatus CS0 =
205 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
206 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
207 return CS0 | CS1;
210 } // namespace llvm
212 static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
213 bool HeaderOnly, Cycle **CPtr = nullptr) {
214 if (!CI)
215 return true;
216 auto *BB = I->getParent();
217 auto *C = CI->getCycle(BB);
218 if (!C)
219 return false;
220 if (CPtr)
221 *CPtr = C;
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.
228 if (!Ty->isSized())
229 return false;
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))
234 return false;
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))
246 return true;
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))
255 return false;
256 if (StartPos != Layout->getElementOffsetInBits(I))
257 return false;
258 StartPos += DL.getTypeAllocSizeInBits(ElTy);
261 return true;
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())
270 return nullptr;
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();
288 return nullptr;
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
298 /// already exist.
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");
306 if (Offset) {
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");
333 return Ptr;
336 static const Value *
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
348 : DepClassTy::NONE);
349 if (!ValueConstantRangeAA)
350 return false;
351 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
352 : ValueConstantRangeAA->getKnown();
353 if (Range.isFullSet())
354 return false;
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.
358 if (GetMinOffset)
359 ROffset = Range.getSignedMin();
360 else
361 ROffset = Range.getSignedMax();
362 return true;
365 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
366 /* AllowInvariant */ true,
367 AttributorAnalysis);
370 static const Value *
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);
375 const Value *Base =
376 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
377 /* GetMinOffset */ true, AllowNonInbounds);
379 BytesOffset = OffsetAPInt.getSExtValue();
380 return Base;
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)) {
410 bool IsKnown;
411 return AA::hasAssumedIRAttr<IRAttributeKind>(
412 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
415 const AAType *AA =
416 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
417 if (!AA)
418 return false;
419 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
420 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
421 const StateType &AAS = AA->getState();
422 if (!T)
423 T = StateType::getBestState(AAS);
424 *T &= AAS;
425 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
426 << "\n");
427 return T->isValidState();
430 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
431 AA::ValueScope::Intraprocedural,
432 RecurseForSelectAndPHI))
433 S.indicatePessimisticFixpoint();
434 else if (T)
435 S ^= *T;
438 namespace {
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>(
453 A, *this, S,
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,
466 StateType &S) {
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)
486 return false;
488 // If possible, use the hasAssumedIRAttr interface.
489 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
490 bool IsKnown;
491 return AA::hasAssumedIRAttr<IRAttributeKind>(
492 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
495 const AAType *AA =
496 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
497 if (!AA)
498 return false;
499 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
500 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
501 << "\n");
502 const StateType &AAS = AA->getState();
503 if (!T)
504 T = StateType::getBestState(AAS);
505 *T &= AAS;
506 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
507 << "\n");
508 return T->isValidState();
511 bool UsedAssumedInformation = false;
512 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
513 UsedAssumedInformation))
514 S.indicatePessimisticFixpoint();
515 else if (T)
516 S ^= *T;
519 /// This function is the bridge between argument position and the call base
520 /// context.
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();
530 if (!CBContext)
531 return false;
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)) {
539 bool IsKnown;
540 return AA::hasAssumedIRAttr<IRAttributeKind>(
541 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
544 const auto *AA =
545 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
546 if (!AA)
547 return false;
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
553 << "\n");
555 // NOTE: If we want to do call site grouping it should happen here.
556 State ^= CBArgumentState;
557 return true;
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) {
574 bool Success =
575 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
576 IRAttributeKind>(
577 A, *this, this->getIRPosition(), S);
578 if (Success)
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
610 << "\n");
612 ChangeStatus Changed = ChangeStatus::UNCHANGED;
613 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
614 for (const Function *Callee : Callees) {
615 IRPosition FnPos =
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)) {
623 bool IsKnown;
624 if (!AA::hasAssumedIRAttr<IRAttributeKind>(
625 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
626 return false;
627 continue;
630 const AAType *AA =
631 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
632 if (!AA)
633 return false;
634 Changed |= clampStateAndIndicateChange(S, AA->getState());
635 if (S.isAtFixpoint())
636 return S.isValidState();
638 return true;
640 if (!A.checkForAllCallees(CalleePred, *this, CB))
641 return S.indicatePessimisticFixpoint();
642 return Changed;
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,
652 StateType &State) {
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())
660 Uses.insert(&Us);
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,
676 Instruction &CtxI) {
677 MustBeExecutedContextExplorer *Explorer =
678 A.getInfoCache().getMustBeExecutedContextExplorer();
679 if (!Explorer)
680 return;
682 // Container for (transitive) uses of the associated value.
683 SetVector<const Use *> Uses;
684 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses())
685 Uses.insert(&U);
687 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
689 if (S.isAtFixpoint())
690 return;
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);
697 return true;
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}
708 // ...
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) {
717 // if(a)
718 // if (b) {
719 // *ptr = 0;
720 // } else {
721 // *ptr = 1;
722 // }
723 // else {
724 // if (b) {
725 // *ptr = 0;
726 // } else {
727 // *ptr = 1;
728 // }
729 // }
730 // }
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();)
748 It = Uses.erase(It);
750 ParentState &= ChildState;
753 // Use only known state.
754 S += ParentState;
757 } // namespace
759 /// ------------------------ PointerInfo ---------------------------------------
761 namespace llvm {
762 namespace AA {
763 namespace PointerInfo {
765 struct State;
767 } // namespace PointerInfo
768 } // namespace AA
770 /// Helper for AA::PointerInfo::Access DenseMap/Set usage.
771 template <>
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) {
799 return A == 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);
814 } // namespace llvm
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) {
823 State R;
824 R.indicatePessimisticFixpoint();
825 return R;
828 State() = default;
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) {
852 if (this == &R)
853 return *this;
854 BS = R.BS;
855 AccessList = R.AccessList;
856 OffsetBins = R.OffsetBins;
857 RemoteIMap = R.RemoteIMap;
858 return *this;
861 State &operator=(State &&R) {
862 if (this == &R)
863 return *this;
864 std::swap(BS, R.BS);
865 std::swap(AccessList, R.AccessList);
866 std::swap(OffsetBins, R.OffsetBins);
867 std::swap(RemoteIMap, R.RemoteIMap);
868 return *this;
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];
894 protected:
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(
913 AA::RangeTy Range,
914 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
915 if (!isValidState())
916 return false;
918 for (const auto &It : OffsetBins) {
919 AA::RangeTy ItRange = It.getFirst();
920 if (!Range.mayOverlap(ItRange))
921 continue;
922 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
923 for (auto Index : It.getSecond()) {
924 auto &Access = AccessList[Index];
925 if (!CB(Access, IsExact))
926 return false;
929 return true;
932 /// See AAPointerInfo::forallInterferingAccesses.
933 bool forallInterferingAccesses(
934 Instruction &I,
935 function_ref<bool(const AAPointerInfo::Access &, bool)> CB,
936 AA::RangeTy &Range) const {
937 if (!isValidState())
938 return false;
940 auto LocalList = RemoteIMap.find(&I);
941 if (LocalList == RemoteIMap.end()) {
942 return true;
945 for (unsigned Index : LocalList->getSecond()) {
946 for (auto &R : AccessList[Index]) {
947 Range &= R;
948 if (Range.offsetAndSizeAreUnknown())
949 break;
952 return forallInterferingAccesses(Range, CB);
955 private:
956 /// State to track fixpoint and validity.
957 BooleanState BS;
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) {
973 AccExists = true;
974 AccIndex = Index;
975 break;
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);
989 if (!AccExists) {
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;
1003 Current &= Acc;
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);
1030 AddToBins(ToAdd);
1031 return ChangeStatus::CHANGED;
1034 namespace {
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.
1039 struct OffsetInfo {
1040 using VecTy = SmallVector<int64_t>;
1041 using const_iterator = VecTy::const_iterator;
1042 VecTy Offsets;
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 {
1057 if (isUnassigned())
1058 return false;
1059 if (Offsets.size() == 1)
1060 return Offsets.front() == AA::RangeTy::Unknown;
1061 return false;
1064 void setUnknown() {
1065 Offsets.clear();
1066 Offsets.push_back(AA::RangeTy::Unknown);
1069 void addToAll(int64_t Inc) {
1070 for (auto &Offset : Offsets) {
1071 Offset += Inc;
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); }
1082 #ifndef NDEBUG
1083 static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) {
1084 ListSeparator LS;
1085 OS << "[";
1086 for (auto Offset : OI) {
1087 OS << LS << Offset;
1089 OS << "]";
1090 return OS;
1092 #endif // NDEBUG
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")
1104 : "<invalid>");
1107 /// See AbstractAttribute::manifest(...).
1108 ChangeStatus manifest(Attributor &A) override {
1109 return AAPointerInfo::manifest(A);
1112 bool forallInterferingAccesses(
1113 AA::RangeTy Range,
1114 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1115 const override {
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,
1123 AA::RangeTy &Range,
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();
1131 bool IsKnownNoSync;
1132 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1133 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1134 IsKnownNoSync);
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
1162 // aligned region.
1163 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1164 if (IsThreadLocalObj || AllInSameNoSyncFn)
1165 return true;
1166 const auto *FnExecDomainAA =
1167 I.getFunction() == &Scope
1168 ? ExecDomainAA
1169 : A.lookupAAFor<AAExecutionDomain>(
1170 IRPosition::function(*I.getFunction()), &QueryingAA,
1171 DepClassTy::NONE);
1172 if (!FnExecDomainAA)
1173 return false;
1174 if (InstIsExecutedInAlignedRegion ||
1175 (FindInterferingWrites &&
1176 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1177 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1178 return true;
1180 if (InstIsExecutedByInitialThreadOnly &&
1181 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1182 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1183 return true;
1185 return false;
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,
1201 IsKnownNoRecurse);
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) {
1212 if (!AA::isGPU(M))
1213 return false;
1214 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1215 case AA::GPUAddressSpace::Shared:
1216 case AA::GPUAddressSpace::Constant:
1217 case AA::GPUAddressSpace::Local:
1218 return true;
1219 default:
1220 return false;
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()))
1262 return true;
1264 bool Dominates = FindInterferingWrites && DT && Exact &&
1265 Acc.isMustAccess() &&
1266 (Acc.getRemoteInst()->getFunction() == &Scope) &&
1267 DT->dominates(Acc.getRemoteInst(), &I);
1268 if (Dominates)
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});
1276 return true;
1278 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1279 return false;
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))
1297 return true;
1298 if (!CanIgnoreThreading(Acc))
1299 return false;
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.
1309 if (!ReadChecked) {
1310 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1311 &ExclusionSet, IsLiveInCalleeCB))
1312 ReadChecked = true;
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
1341 // itself either.
1342 bool Inserted = ExclusionSet.insert(&I).second;
1344 if (!FnReachabilityAA ||
1345 !FnReachabilityAA->instructionCanReach(
1346 A, *LeastDominatingWriteInst,
1347 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1348 WriteChecked = true;
1350 if (Inserted)
1351 ExclusionSet.erase(&I);
1354 if (ReadChecked && WriteChecked)
1355 return true;
1357 if (!DT || !UseDominanceReasoning)
1358 return false;
1359 if (!DominatingWrites.count(&Acc))
1360 return false;
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))
1370 return false;
1373 return true;
1376 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1377 const AAPointerInfo &OtherAA,
1378 CallBase &CB) {
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())
1393 continue;
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());
1405 return Changed;
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()
1425 : RAcc.getRanges();
1426 if (!NewRanges.isUnknown()) {
1427 NewRanges.addToAllOffsets(Offset);
1429 Changed |=
1430 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
1431 RAcc.getType(), RAcc.getRemoteInst());
1435 return Changed;
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()
1452 << "\n";
1453 if (!Acc.isWrittenValueYetUndetermined()) {
1454 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1455 O << " - c: func " << Acc.getWrittenValue()->getName()
1456 << "\n";
1457 else if (Acc.getWrittenValue())
1458 O << " - c: " << *Acc.getWrittenValue() << "\n";
1459 else
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,
1476 Type &Ty) {
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);
1495 } else {
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;
1521 return true;
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,
1543 OffsetInfo &UsrOI,
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)) {
1555 UsrOI.setUnknown();
1556 return true;
1559 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1560 << (VariableOffsets.empty() ? "" : "not") << " constant "
1561 << *GEP << "\n");
1563 auto Union = PtrOI;
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()) {
1573 UsrOI.setUnknown();
1574 return true;
1577 // UndefValue is treated as a zero, which leaves Union as is.
1578 if (PotentialConstantsAA->undefIsContained())
1579 continue;
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())
1587 return false;
1589 OffsetInfo Product;
1590 for (const auto &ConstOffset : AssumedSet) {
1591 auto CopyPerOffset = Union;
1592 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1593 VI.second.getZExtValue());
1594 Product.merge(CopyPerOffset);
1596 Union = Product;
1599 UsrOI = std::move(Union);
1600 return true;
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!");
1625 UsrOI = PtrOI;
1626 Follow = true;
1627 return true;
1630 const auto *F = getAnchorScope();
1631 const auto *CI =
1632 F ? A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(*F)
1633 : nullptr;
1634 const auto *TLI =
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
1641 << "\n");
1642 assert(OffsetInfoMap.count(CurPtr) &&
1643 "The current pointer offset should have been seeded!");
1645 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1646 if (CE->isCast())
1647 return HandlePassthroughUser(Usr, CurPtr, Follow);
1648 if (CE->isCompare())
1649 return true;
1650 if (!isa<GEPOperator>(CE)) {
1651 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1652 << "\n");
1653 return false;
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())
1663 return true;
1665 if (PtrOI.isUnknown()) {
1666 Follow = true;
1667 UsrOI.setUnknown();
1668 return true;
1671 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1672 return true;
1674 if (isa<PtrToIntInst>(Usr))
1675 return false;
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();
1695 UsrOI.setUnknown();
1696 return true;
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)");
1704 return true;
1707 // Check if the PHI operand can be traced back to AssociatedValue.
1708 APInt Offset(
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");
1717 UsrOI.setUnknown();
1718 Follow = true;
1719 return true;
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);
1738 LLVM_DEBUG(
1739 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1740 << *CurPtr << " in " << *Usr << "\n");
1741 UsrOI.setUnknown();
1742 Follow = true;
1743 return true;
1746 UsrOI.merge(PtrOI);
1747 Follow = true;
1748 return true;
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);
1757 else
1758 AK = AccessKind(AK | AccessKind::AK_MAY);
1759 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1760 OffsetInfoMap[CurPtr].Offsets, Changed,
1761 *LoadI->getType()))
1762 return false;
1764 auto IsAssumption = [](Instruction &I) {
1765 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1766 return II->isAssumeLikeIntrinsic();
1767 return false;
1770 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1771 // Check if the assumption and the load are executed together without
1772 // memory modification.
1773 do {
1774 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1775 return true;
1776 FromI = FromI->getNextNonDebugInstruction();
1777 } while (FromI && FromI != ToI);
1778 return false;
1781 BasicBlock *BB = LoadI->getParent();
1782 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1783 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1784 return false;
1785 BasicBlock *IntrBB = IntrI.getParent();
1786 if (IntrI.getParent() == BB) {
1787 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI))
1788 return false;
1789 } else {
1790 auto PredIt = pred_begin(IntrBB);
1791 if (PredIt == pred_end(IntrBB))
1792 return false;
1793 if ((*PredIt) != BB)
1794 return false;
1795 if (++PredIt != pred_end(IntrBB))
1796 return false;
1797 for (auto *SuccBB : successors(BB)) {
1798 if (SuccBB == IntrBB)
1799 continue;
1800 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1801 continue;
1802 return false;
1804 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(),
1805 BB->getTerminator()))
1806 return false;
1807 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1808 return false;
1810 return true;
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())
1817 continue;
1818 for (const Use &CmpU : CmpI->uses()) {
1819 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1820 if (!IsValidAssume(*IntrI))
1821 continue;
1822 int Idx = CmpI->getOperandUse(0) == LoadU;
1823 Assumption = {CmpI->getOperand(Idx), IntrI};
1824 break;
1828 if (Assumption.first)
1829 break;
1832 // Check if we found an assumption associated with this load.
1833 if (!Assumption.first || !Assumption.second)
1834 return true;
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)
1842 Content =
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) {
1854 LLVM_DEBUG(
1855 dbgs()
1856 << "[AAPointerInfo] Escaping use in store like instruction " << I
1857 << "\n");
1858 return false;
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);
1866 else
1867 AK = AccessKind(AK | AccessKind::AK_MAY);
1868 bool UsedAssumedInformation = false;
1869 std::optional<Value *> Content = nullptr;
1870 if (ValueOp)
1871 Content = A.getAssumedSimplified(
1872 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1873 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1874 Changed, ValueTy);
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()},
1888 AccessKind::AK_RW);
1890 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1891 if (CB->isLifetimeStartOrEnd())
1892 return true;
1893 if (getFreedOperand(CB, TLI) == U)
1894 return true;
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);
1900 if (!CSArgPI)
1901 return false;
1902 Changed =
1903 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) |
1904 Changed;
1905 return isValidState();
1907 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1908 << "\n");
1909 // TODO: Allow some call uses
1910 return false;
1913 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1914 return false;
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)) {
1919 LLVM_DEBUG({
1920 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1921 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1922 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1923 << "\n";
1926 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1928 OffsetInfoMap[NewU] = OffsetInfoMap[OldU];
1929 return true;
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();
1938 LLVM_DEBUG({
1939 dbgs() << "Accesses by bin after update:\n";
1940 dumpState(dbgs());
1943 return Changed;
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
1980 // accessed.
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;
1984 if (Length)
1985 LengthVal = Length->getSExtValue();
1986 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1987 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1988 if (ArgNo > 1) {
1989 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1990 << *MI << "\n");
1991 return indicatePessimisticFixpoint();
1992 } else {
1993 auto Kind =
1994 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1995 Changed =
1996 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1998 LLVM_DEBUG({
1999 dbgs() << "Accesses by bin after update:\n";
2000 dumpState(dbgs());
2003 return Changed;
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();
2011 if (Arg) {
2012 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2013 auto *ArgAA =
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);
2031 auto Kind =
2032 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2033 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2034 nullptr);
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());
2052 } // namespace
2054 /// -----------------------NoUnwind Function Attribute--------------------------
2056 namespace {
2057 struct AANoUnwindImpl : AANoUnwind {
2058 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2060 /// See AbstractAttribute::initialize(...).
2061 void initialize(Attributor &A) override {
2062 bool IsKnown;
2063 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2064 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2065 (void)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 {
2074 auto Opcodes = {
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))
2081 return 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,
2087 IsKnownNoUnwind);
2089 return false;
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); }
2118 } // namespace
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:
2128 return true;
2129 case Intrinsic::amdgcn_s_barrier:
2130 if (ExecutedAligned)
2131 return true;
2132 break;
2133 default:
2134 break;
2136 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2139 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) {
2140 if (!I->isAtomic())
2141 return false;
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();
2156 break;
2157 case Instruction::Store:
2158 Ordering = cast<StoreInst>(I)->getOrdering();
2159 break;
2160 case Instruction::Load:
2161 Ordering = cast<LoadInst>(I)->getOrdering();
2162 break;
2163 default:
2164 llvm_unreachable(
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();
2178 return false;
2181 namespace {
2182 struct AANoSyncImpl : AANoSync {
2183 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2185 /// See AbstractAttribute::initialize(...).
2186 void initialize(Attributor &A) override {
2187 bool IsKnown;
2188 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2189 DepClassTy::NONE, IsKnown));
2190 (void)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())
2211 return true;
2213 bool IsKnown;
2214 CallBase &CB = cast<CallBase>(I);
2215 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
2216 A, this, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL,
2217 IsKnown))
2218 return true;
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); }
2250 } // namespace
2252 /// ------------------------ No-Free Attributes ----------------------------
2254 namespace {
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 {
2260 bool IsKnown;
2261 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2262 DepClassTy::NONE, IsKnown));
2263 (void)IsKnown;
2266 /// See AbstractAttribute::updateImpl(...).
2267 ChangeStatus updateImpl(Attributor &A) override {
2268 auto CheckForNoFree = [&](Instruction &I) {
2269 bool IsKnown;
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();
2317 bool IsKnown;
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))
2328 return false;
2329 if (!CB->isArgOperand(&U))
2330 return true;
2331 unsigned ArgNo = CB->getArgOperandNo(&U);
2333 bool IsKnown;
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)) {
2341 Follow = true;
2342 return true;
2344 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) ||
2345 isa<ReturnInst>(UserI))
2346 return true;
2348 // Unknown user.
2349 return false;
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();
2379 if (!Arg)
2380 return indicatePessimisticFixpoint();
2381 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2382 bool IsKnown;
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) }
2425 } // namespace
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))
2438 return true;
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()});
2453 } else {
2454 bool UsedAssumedInformation = false;
2455 if (!A.checkForAllInstructions(
2456 [&](Instruction &I) {
2457 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2458 return true;
2460 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2461 UsedAssumedInformation))
2462 return false;
2465 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2466 return !isKnownNonZero(VAC.getValue(), A.getDataLayout(), 0, AC,
2467 VAC.getCtxI(), DT);
2469 return false;
2471 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2472 Attribute::NonNull)});
2473 return true;
2476 namespace {
2477 static int64_t getKnownNonNullAndDerefBytesForUse(
2478 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2479 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2480 TrackUse = false;
2482 const Value *UseV = U->get();
2483 if (!UseV->getType()->isPointerTy())
2484 return 0;
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)) {
2490 TrackUse = true;
2491 return 0;
2494 if (isa<GetElementPtrInst>(I)) {
2495 TrackUse = true;
2496 return 0;
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})) {
2508 IsNonNull |=
2509 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2510 return RK.ArgValue;
2512 return 0;
2515 if (CB->isCallee(U)) {
2516 IsNonNull |= !NullPointerIsDefined;
2517 return 0;
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;
2528 auto *DerefAA =
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())
2535 return 0;
2537 int64_t Offset;
2538 const Value *Base =
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);
2555 return 0;
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();
2566 return;
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);
2581 return TrackUse;
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);
2603 bool Stripped;
2604 bool UsedAssumedInformation = false;
2605 Value *AssociatedValue = &getAssociatedValue();
2606 SmallVector<AA::ValueAndContext> Values;
2607 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2608 AA::AnyScope, UsedAssumedInformation))
2609 Stripped = false;
2610 else
2611 Stripped =
2612 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2614 if (!Stripped) {
2615 bool IsKnown;
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,
2620 IsKnown);
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
2635 // value.
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) }
2698 } // namespace
2700 /// ------------------------ Must-Progress Attributes --------------------------
2701 namespace {
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 {
2708 bool IsKnown;
2709 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2710 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2711 (void)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 {
2726 bool IsKnown;
2727 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
2728 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2729 if (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,
2745 AllCallSitesKnown))
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);
2781 } // namespace
2783 /// ------------------------ No-Recurse Attributes ----------------------------
2785 namespace {
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 {
2791 bool IsKnown;
2792 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2793 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2794 (void)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>(
2814 A, this,
2815 IRPosition::function(*ACS.getInstruction()->getFunction()),
2816 DepClassTy::NONE, IsKnownNoRecurse))
2817 return false;
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); }
2853 } // namespace
2855 /// ------------------------ No-Convergent Attribute --------------------------
2857 namespace {
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
2875 // convergent.
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()) {
2880 return false;
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) }
2909 } // namespace
2911 /// -------------------- Undefined-Behavior Attributes ------------------------
2913 namespace {
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())
2927 return true;
2929 // Skip instructions that are already saved.
2930 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2931 return true;
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.
2936 Value *PtrOp =
2937 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2938 assert(PtrOp &&
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)
2946 return true;
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);
2954 return true;
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);
2966 else
2967 KnownUBInsts.insert(&I);
2968 return true;
2971 auto InspectBrInstForUB = [&](Instruction &I) {
2972 // A conditional branch instruction is considered UB if it has `undef`
2973 // condition.
2975 // Skip instructions that are already saved.
2976 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2977 return true;
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())
2984 return true;
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)
2991 return true;
2992 AssumedNoUBInsts.insert(&I);
2993 return true;
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))
3001 return true;
3003 // Check nonnull and noundef argument attribute violation for each
3004 // callsite.
3005 CallBase &CB = cast<CallBase>(I);
3006 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3007 if (!Callee)
3008 return true;
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
3014 // considered UB.
3015 if (idx >= Callee->arg_size())
3016 break;
3017 Value *ArgVal = CB.getArgOperand(idx);
3018 if (!ArgVal)
3019 continue;
3020 // Here, we handle three cases.
3021 // (1) Not having a value means it is dead. (we can replace the value
3022 // with undef)
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)
3031 continue;
3032 bool UsedAssumedInformation = false;
3033 std::optional<Value *> SimplifiedVal =
3034 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3035 UsedAssumedInformation, AA::Interprocedural);
3036 if (UsedAssumedInformation)
3037 continue;
3038 if (SimplifiedVal && !*SimplifiedVal)
3039 return true;
3040 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3041 KnownUBInsts.insert(&I);
3042 continue;
3044 if (!ArgVal->getType()->isPointerTy() ||
3045 !isa<ConstantPointerNull>(**SimplifiedVal))
3046 continue;
3047 bool IsKnownNonNull;
3048 AA::hasAssumedIRAttr<Attribute::NonNull>(
3049 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3050 if (IsKnownNonNull)
3051 KnownUBInsts.insert(&I);
3053 return true;
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)
3063 return true;
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`
3071 // attribute yet.
3073 // When the returned position has noundef attriubte, UB occurs in the
3074 // following cases.
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
3078 // poison).
3079 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3080 bool IsKnownNonNull;
3081 AA::hasAssumedIRAttr<Attribute::NonNull>(
3082 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3083 IsKnownNonNull);
3084 if (IsKnownNonNull)
3085 KnownUBInsts.insert(&I);
3088 return true;
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);
3112 if (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
3134 // for UB.
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())
3145 return false;
3146 return !AssumedNoUBInsts.count(I);
3147 } break;
3148 default:
3149 return false;
3151 return false;
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.
3190 protected:
3191 /// A set of all live instructions _known_ to cause UB.
3192 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3194 private:
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,
3208 Instruction *I) {
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.
3215 if (!SimplifiedV) {
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;
3221 if (!*SimplifiedV)
3222 return nullptr;
3223 V = *SimplifiedV;
3225 if (isa<UndefValue>(V)) {
3226 KnownUBInsts.insert(I);
3227 return std::nullopt;
3229 return V;
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();
3245 } // namespace
3247 /// ------------------------ Will-Return Attributes ----------------------------
3249 namespace {
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.
3261 if (!SE || !LI) {
3262 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3263 if (SCCI.hasCycle())
3264 return true;
3265 return false;
3268 // If there's irreducible control, the function may contain non-loop cycles.
3269 if (mayContainIrreducibleControl(F, LI))
3270 return true;
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))
3275 return true;
3277 return false;
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 {
3286 bool IsKnown;
3287 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>(
3288 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3289 (void)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}))
3295 return false;
3297 bool IsKnown;
3298 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3299 return IsKnown || !KnownOnly;
3300 return false;
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));
3310 bool IsKnown;
3311 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
3312 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3313 if (IsKnown)
3314 return true;
3315 } else {
3316 return false;
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); }
3372 } // namespace
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 {
3382 Yes,
3385 /// Start here,
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.
3395 unsigned Hash = 0;
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
3410 /// cache.
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) {}
3426 namespace llvm {
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}))
3444 return false;
3445 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3449 #define DefineKeys(ToTy) \
3450 template <> \
3451 ReachabilityQueryInfo<ToTy> \
3452 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3453 ReachabilityQueryInfo<ToTy>( \
3454 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3455 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3456 template <> \
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)
3464 #undef DefineKeys
3466 } // namespace llvm
3468 namespace {
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;
3488 return 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.
3499 if (IsTemporaryRQI)
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
3505 // there is none.
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;
3543 return true;
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;
3553 return true;
3557 auto It = QueryCache.find(&StackRQI);
3558 if (It != QueryCache.end()) {
3559 Result = (*It)->Result;
3560 return true;
3563 // Insert a temporary for recursive queries. We will replace it with a
3564 // permanent entry later.
3565 QueryCache.insert(&StackRQI);
3566 return false;
3569 private:
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)
3578 : Base(IRP, 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);
3587 if (&From == &To)
3588 return true;
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
3600 // of them changed.
3601 auto *LivenessAA =
3602 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3603 if (LivenessAA &&
3604 llvm::all_of(DeadEdges,
3605 [&](const auto &DeadEdge) {
3606 return LivenessAA->isEdgeDead(DeadEdge.first,
3607 DeadEdge.second);
3608 }) &&
3609 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3610 return LivenessAA->isAssumedDead(BB);
3611 })) {
3612 return ChangeStatus::UNCHANGED;
3614 DeadEdges.clear();
3615 DeadBlocks.clear();
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;
3630 break;
3632 IP = IP->getNextNode();
3634 return IP == &To;
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
3643 // possible.
3644 if (FromBB == ToBB &&
3645 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3646 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3647 IsTemporaryRQI);
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,
3653 IsTemporaryRQI);
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(),
3665 RQI.ExclusionSet))
3666 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3668 auto *LivenessAA =
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,
3673 IsTemporaryRQI);
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)
3684 continue;
3685 for (const BasicBlock *SuccBB : successors(BB)) {
3686 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3687 LocalDeadEdges.insert({BB, SuccBB});
3688 continue;
3690 // We checked before if we just need to reach the ToBB block.
3691 if (SuccBB == ToBB)
3692 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3693 IsTemporaryRQI);
3694 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3695 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3696 IsTemporaryRQI);
3698 if (ExclusionBlocks.count(SuccBB)) {
3699 UsedExclusionSet = true;
3700 continue;
3702 Worklist.push_back(SuccBB);
3706 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end());
3707 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3708 IsTemporaryRQI);
3711 /// See AbstractAttribute::trackStatistics()
3712 void trackStatistics() const override {}
3714 private:
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;
3726 } // namespace
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))
3738 return true;
3739 } else {
3740 IgnoreSubsumingPositions = true;
3743 if (isa<UndefValue>(Val))
3744 return true;
3746 if (isa<ConstantPointerNull>(Val) &&
3747 !NullPointerIsDefined(IRP.getAnchorScope(),
3748 Val->getType()->getPointerAddressSpace()))
3749 return true;
3751 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3752 IgnoreSubsumingPositions, Attribute::NoAlias))
3753 return true;
3755 return false;
3758 namespace {
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.
3801 bool IsKnownNoSycn;
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.
3808 bool IsKnown;
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
3813 // synchronization.
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)
3844 return false;
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())
3849 return false;
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);
3857 return false;
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() &&
3864 IsReadOnly) {
3865 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3866 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3867 return false;
3870 // We have to utilize actual alias analysis queries so we need the object.
3871 if (!AAR)
3872 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3873 *getAnchorScope());
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");
3882 return IsAliasing;
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
3892 // value.
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
3904 // callsite.
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
3911 // with the value.
3912 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3913 return true;
3915 if (ScopeFn) {
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))
3925 return true;
3929 if (!AA::isPotentiallyReachable(
3930 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3931 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3932 return true;
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:
3940 return true;
3941 case UseCaptureKind::MAY_CAPTURE:
3942 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI
3943 << "\n");
3944 return false;
3945 case UseCaptureKind::PASSTHROUGH:
3946 Follow = true;
3947 return true;
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())) {
3959 LLVM_DEBUG(
3960 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3961 << " cannot be noalias as it is potentially captured\n");
3962 return false;
3965 if (NoCaptureAA)
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))
3974 return false;
3976 return true;
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
3982 // argument.
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)) {
4002 LLVM_DEBUG(
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))
4025 return true;
4027 /// For now, we can only deduce noalias if we have call sites.
4028 /// FIXME: add more support.
4029 if (!isa<CallBase>(&RV))
4030 return false;
4032 const IRPosition &RVPos = IRPosition::value(RV);
4033 bool IsKnownNoAlias;
4034 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4035 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4036 return false;
4038 bool IsKnownNoCapture;
4039 const AANoCapture *NoCaptureAA = nullptr;
4040 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
4041 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4042 &NoCaptureAA);
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); }
4066 } // namespace
4068 /// -------------------AAIsDead Function Attribute-----------------------
4070 namespace {
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())
4105 return true;
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()))
4111 return false;
4112 bool UsedAssumedInformation = false;
4113 std::optional<Constant *> C =
4114 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4115 if (!C || *C)
4116 return true;
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
4123 // correctness.
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))
4132 return true;
4134 auto *CB = dyn_cast<CallBase>(I);
4135 if (!CB || isa<IntrinsicInst>(CB))
4136 return false;
4138 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4140 bool IsKnownNoUnwind;
4141 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4142 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4143 return false;
4145 bool IsKnown;
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();
4160 return;
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();
4167 else
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))
4176 return false;
4177 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4178 return true;
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())
4185 return false;
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
4189 // cached ones.
4190 bool UsedAssumedInformation = false;
4191 if (!AssumeOnlyInst) {
4192 PotentialCopies.clear();
4193 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4194 UsedAssumedInformation)) {
4195 LLVM_DEBUG(
4196 dbgs()
4197 << "[AAIsDead] Could not determine potential copies of store!\n");
4198 return false;
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))
4208 return true;
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)) {
4213 if (AssumeOnlyInst)
4214 AssumeOnlyInst->insert(&UserI);
4215 return true;
4217 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4218 })) {
4219 return true;
4222 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4223 << " is assumed live!\n");
4224 return false;
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))
4232 if (isValidState())
4233 return "assumed-dead-store";
4234 if (isa_and_nonnull<FenceInst>(I))
4235 if (isValidState())
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();
4249 } else {
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
4269 // still needed.
4270 if (auto *SI = dyn_cast<StoreInst>(I)) {
4271 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4272 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4273 (void)IsDead;
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)
4302 private:
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();
4346 if (!Arg)
4347 return indicatePessimisticFixpoint();
4348 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4349 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4350 if (!ArgAA)
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();
4385 return;
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();
4401 return Changed;
4404 /// See AbstractAttribute::trackStatistics()
4405 void trackStatistics() const override {
4406 if (IsAssumedSideEffectFree)
4407 STATS_DECLTRACK_CSRET_ATTR(IsDead)
4408 else
4409 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4412 /// See AbstractAttribute::getAsStr().
4413 const std::string getAsStr(Attributor *A) const override {
4414 return isAssumedDead()
4415 ? "assumed-dead"
4416 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4419 private:
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())
4436 return false;
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);
4456 return true;
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())
4483 return false;
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);
4518 if (!CB)
4519 continue;
4520 bool IsKnownNoReturn;
4521 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>(
4522 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4523 IsKnownNoReturn);
4524 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4525 continue;
4527 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4528 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4529 else
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;
4543 return HasChanged;
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.");
4570 if (!getAssumed())
4571 return false;
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.");
4585 if (!getAssumed())
4586 return false;
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()))
4591 return true;
4593 // If it is not after a liveness barrier it is live.
4594 const Instruction *PrevI = I->getPrevNode();
4595 while (PrevI) {
4596 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4597 return true;
4598 PrevI = PrevI->getPrevNode();
4600 return false;
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)
4612 return false;
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);
4623 return true;
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;
4640 static bool
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());
4652 else
4653 AliveSuccessors.push_back(CB.getNextNode());
4654 return false;
4657 static bool
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());
4669 } else {
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;
4676 } else {
4677 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4680 return UsedAssumedInformation;
4683 static bool
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());
4690 } else {
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());
4699 } else {
4700 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4701 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4702 UsedAssumedInformation = false;
4705 return UsedAssumedInformation;
4708 static bool
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());
4720 return false;
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);
4735 return true;
4737 return false;
4740 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4741 return CheckForConstantInt(VAC.getValue());
4742 })) {
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())) {
4751 ++MatchedCases;
4752 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4756 // If all potential values have been matched, we will not visit the default
4757 // case.
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
4793 // though.
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".
4802 default:
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());
4807 break;
4808 case Instruction::Call:
4809 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4810 *this, AliveSuccessors);
4811 break;
4812 case Instruction::Invoke:
4813 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4814 *this, AliveSuccessors);
4815 break;
4816 case Instruction::Br:
4817 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4818 *this, AliveSuccessors);
4819 break;
4820 case Instruction::Switch:
4821 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4822 *this, AliveSuccessors);
4823 break;
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);
4844 } else {
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);
4859 })) {
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
4869 // dead.
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();
4876 return Change;
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 {}
4902 } // namespace
4904 /// -------------------- Dereferenceable Argument Attribute --------------------
4906 namespace {
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()
4936 /// {
4937 StateType &getState() override { return *this; }
4938 const StateType &getState() const override { return *this; }
4939 /// }
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())
4946 return;
4948 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4949 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4950 return;
4952 int64_t Offset;
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);
4971 return TrackUse;
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;
4985 return Change;
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()));
4997 else
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;
5008 if (A)
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 {
5027 bool Stripped;
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()});
5033 Stripped = false;
5034 } else {
5035 Stripped = Values.size() != 1 ||
5036 Values.front().getValue() != &getAssociatedValue();
5039 const DataLayout &DL = A.getDataLayout();
5040 DerefState T;
5042 auto VisitValueCB = [&](const Value &V) -> bool {
5043 unsigned IdxWidth =
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;
5057 DerefBytes =
5058 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5059 T.GlobalState.indicatePessimisticFixpoint();
5060 } else {
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();
5070 if (OffsetSExt < 0)
5071 OffsetSExt = 0;
5073 T.takeAssumedDerefBytesMinimum(
5074 std::max(int64_t(0), DerefBytes - OffsetSExt));
5076 if (this == AA) {
5077 if (!Stripped) {
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
5087 // can accelerate.
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> {
5111 using Base =
5112 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5113 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5114 : Base(IRP, 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> {
5126 using Base =
5127 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5128 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5129 : Base(IRP, 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)
5153 : Base(IRP, A) {}
5155 /// See AbstractAttribute::trackStatistics()
5156 void trackStatistics() const override {
5157 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5160 } // namespace
5162 // ------------------------ Align Argument Attribute ------------------------
5164 namespace {
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
5169 // feed into.
5170 if (isa<CastInst>(I)) {
5171 // Follow all but ptr2int casts.
5172 TrackUse = !isa<PtrToIntInst>(I);
5173 return 0;
5175 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5176 if (GEP->hasAllConstantIndices())
5177 TrackUse = true;
5178 return 0;
5181 MaybeAlign MA;
5182 if (const auto *CB = dyn_cast<CallBase>(I)) {
5183 if (CB->isBundleOperand(U) || CB->isCallee(U))
5184 return 0;
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);
5191 if (AlignAA)
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())
5206 return 0;
5208 unsigned Alignment = MA->value();
5209 int64_t Offset;
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);
5222 return Alignment;
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)
5285 Attrs.emplace_back(
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);
5298 return TrackUse;
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();
5316 bool Stripped;
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()});
5322 Stripped = false;
5323 } else {
5324 Stripped = Values.size() != 1 ||
5325 Values.front().getValue() != &getAssociatedValue();
5328 StateType T;
5329 auto VisitValueCB = [&](Value &V) -> bool {
5330 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V))
5331 return true;
5332 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5333 DepClassTy::REQUIRED);
5334 if (!AA || (!Stripped && this == AA)) {
5335 int64_t Offset;
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.
5345 uint32_t gcd =
5346 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5347 Alignment = llvm::bit_floor(gcd);
5348 } else {
5349 Alignment = V.getPointerAlignment(DL).value();
5351 // Use only IR information if we did not strip anything.
5352 T.takeKnownMaximum(Alignment);
5353 T.indicatePessimisticFixpoint();
5354 } else {
5355 // Use abstract attribute information.
5356 const AAAlign::StateType &DS = AA->getState();
5357 T ^= DS;
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;
5423 return Changed;
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);
5434 if (ArgAlignAA)
5435 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5437 return Changed;
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)
5449 : Base(IRP, A) {}
5451 /// See AbstractAttribute::trackStatistics()
5452 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5454 } // namespace
5456 /// ------------------ Function No-Return Attribute ----------------------------
5457 namespace {
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 {
5463 bool IsKnown;
5464 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>(
5465 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5466 (void)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); }
5503 } // namespace
5505 /// ----------------------- Instance Info ---------------------------------
5507 namespace {
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();
5519 else
5520 indicateOptimisticFixpoint();
5521 return;
5523 if (auto *CB = dyn_cast<CallBase>(&V))
5524 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5525 !CB->mayReadFromMemory()) {
5526 indicateOptimisticFixpoint();
5527 return;
5529 if (auto *I = dyn_cast<Instruction>(&V)) {
5530 const auto *CI =
5531 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5532 *I->getFunction());
5533 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5534 indicatePessimisticFixpoint();
5535 return;
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())
5551 return Changed;
5553 if (!Scope)
5554 return indicateOptimisticFixpoint();
5556 bool IsKnownNoRecurse;
5557 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
5558 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5559 IsKnownNoRecurse))
5560 return Changed;
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)) {
5566 Follow = true;
5567 return true;
5569 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5570 (isa<StoreInst>(UserI) &&
5571 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5572 return true;
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())
5578 return true;
5579 if (!CB->isArgOperand(&U))
5580 return false;
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())
5586 return false;
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; }))
5592 return false;
5593 return true;
5595 return false;
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))
5603 return true;
5605 return false;
5608 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5609 DepClassTy::OPTIONAL,
5610 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5611 return indicatePessimisticFixpoint();
5613 return Changed;
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();
5649 if (!Arg)
5650 return indicatePessimisticFixpoint();
5651 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5652 auto *ArgAA =
5653 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5654 if (!ArgAA)
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) {}
5683 } // namespace
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)) {
5698 return true;
5701 if (A.hasAttr(IRP, {Attribute::NoCapture},
5702 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture))
5703 return true;
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));
5712 return true;
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));
5722 return true;
5726 return false;
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,
5733 const Function &F,
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
5738 // ptr2int anymore.
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);
5744 return;
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.
5750 if (ReadOnly)
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))
5762 return;
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);
5768 else if (ReadOnly)
5769 State.addKnownBits(NO_CAPTURE);
5770 else
5771 State.addKnownBits(NOT_CAPTURED_IN_RET);
5772 break;
5776 namespace {
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 {
5783 bool IsKnown;
5784 assert(!AA::hasAssumedIRAttr<Attribute::NoCapture>(
5785 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5786 (void)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())
5796 return;
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,
5822 bool &Follow) {
5823 Instruction *UInst = cast<Instruction>(U.getUser());
5824 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5825 << *UInst << "\n");
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,
5831 /* Return */ true);
5834 // For stores we already checked if we can follow them, if they make it
5835 // here we give up.
5836 if (isa<StoreInst>(UInst))
5837 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5838 /* Return */ true);
5840 // Explicitly catch return instructions.
5841 if (isa<ReturnInst>(UInst)) {
5842 if (UInst->getFunction() == getAnchorScope())
5843 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5844 /* Return */ true);
5845 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5846 /* Return */ 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,
5854 /* Return */ 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,
5864 &ArgNoCaptureAA);
5865 if (IsAssumedNoCapture)
5866 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5867 /* Return */ false);
5868 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5869 Follow = true;
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,
5876 /* Return */ true);
5879 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5880 /// \p CapturedInRet, then return true if we should continue updating the
5881 /// state.
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");
5886 if (CapturedInMem)
5887 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
5888 if (CapturedInInt)
5889 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
5890 if (CapturedInRet)
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();
5900 if (!V)
5901 return indicatePessimisticFixpoint();
5903 const Function *F =
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.
5911 bool IsKnown;
5912 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
5913 T.addKnownBits(NOT_CAPTURED_IN_MEM);
5914 if (IsKnown)
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))
5927 return false;
5928 bool SeenConstant = false;
5929 for (const AA::ValueAndContext &VAC : Values) {
5930 if (isa<Constant>(VAC.getValue())) {
5931 if (SeenConstant)
5932 return false;
5933 SeenConstant = true;
5934 } else if (!isa<Argument>(VAC.getValue()) ||
5935 VAC.getValue() == getAssociatedArgument())
5936 return false;
5938 return true;
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:
5967 return true;
5968 case UseCaptureKind::MAY_CAPTURE:
5969 return checkUse(A, T, U, Follow);
5970 case UseCaptureKind::PASSTHROUGH:
5971 Follow = true;
5972 return true;
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();
6010 if (!Arg)
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,
6017 &ArgAA))
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)
6077 } // namespace
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))
6086 return false;
6088 LLVM_DEBUG({
6089 if (SimplifiedAssociatedValue)
6090 dbgs() << "[ValueSimplify] is assumed to be "
6091 << **SimplifiedAssociatedValue << "\n";
6092 else
6093 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6095 return true;
6098 namespace {
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 {
6113 LLVM_DEBUG({
6114 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6115 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6116 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6118 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6119 : "not-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,
6136 bool Check) {
6137 if (auto *TypedV = AA::getWithType(V, Ty))
6138 return TypedV;
6139 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6140 return Check ? &V
6141 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(&V, &Ty,
6142 "", CtxI);
6143 return nullptr;
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
6149 /// modified.
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)))
6158 return nullptr;
6159 for (Value *Op : I.operands()) {
6160 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6161 if (!NewOp) {
6162 assert(Check && "Manifest of new value unexpectedly failed!");
6163 return nullptr;
6165 if (!Check)
6166 VMap[Op] = NewOp;
6168 if (Check)
6169 return &I;
6171 Instruction *CloneI = I.clone();
6172 // TODO: Try to salvage debug information here.
6173 CloneI->setDebugLoc(DebugLoc());
6174 VMap[&I] = CloneI;
6175 CloneI->insertBefore(CtxI);
6176 RemapInstruction(CloneI, VMap);
6177 return CloneI;
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
6183 /// modified.
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))
6189 return NewV;
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;
6196 if (*SimpleV)
6197 EffectiveV = *SimpleV;
6198 if (auto *C = dyn_cast<Constant>(EffectiveV))
6199 return C;
6200 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6201 A.getInfoCache()))
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);
6206 return nullptr;
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);
6224 return nullptr;
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();
6233 if (Simplify)
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())
6242 return false;
6244 // This will also pass the call base context.
6245 const auto *AA =
6246 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6247 if (!AA)
6248 return false;
6250 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6252 if (!COpt) {
6253 SimplifiedAssociatedValue = std::nullopt;
6254 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6255 return true;
6257 if (auto *C = *COpt) {
6258 SimplifiedAssociatedValue = C;
6259 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6260 return true;
6262 return false;
6265 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6266 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6267 return true;
6268 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6269 return true;
6270 return false;
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
6278 // valid.
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.
6321 bool IsKnown;
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)
6334 return false;
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);
6343 if (!SimpleArgOp)
6344 return true;
6345 if (!*SimpleArgOp)
6346 return false;
6347 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6348 return false;
6349 return unionAssumed(*SimpleArgOp);
6352 // Generate a answer specific to a call site context.
6353 bool Success;
6354 bool UsedAssumedInformation = false;
6355 if (hasCallBaseContext() &&
6356 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6357 Success = PredForCallSite(
6358 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6359 else
6360 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6361 UsedAssumedInformation);
6363 if (!Success)
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())
6386 return nullptr;
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(
6397 A, *this,
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 {
6466 llvm_unreachable(
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()),
6495 Arg.getArgNo());
6496 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT &&
6497 checkAndUpdate(A, *this, IRP))
6498 indicateOptimisticFixpoint();
6499 else
6500 indicatePessimisticFixpoint();
6501 return;
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())
6527 return Changed;
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)
6543 } // namespace
6545 /// ----------------------- Heap-To-Stack Conversion ---------------------------
6546 namespace {
6547 struct AAHeapToStackFunction final : public AAHeapToStack {
6549 struct AllocationInfo {
6550 /// The call that allocates the memory.
6551 CallBase *const CB;
6553 /// The library function id for the allocation.
6554 LibFunc LibraryFunctionId = NotLibFunc;
6556 /// The status wrt. a rewrite.
6557 enum {
6558 STACK_DUE_TO_USE,
6559 STACK_DUE_TO_FREE,
6560 INVALID,
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.
6577 CallBase *const CB;
6578 /// The value freed by the call.
6579 Value *FreedOp;
6581 /// Flag to indicate if we don't know all objects this deallocation might
6582 /// free.
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
6594 // sets.
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);
6609 if (!CB)
6610 return true;
6611 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6612 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6613 return true;
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;
6623 if (TLI)
6624 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6627 return true;
6630 bool UsedAssumedInformation = false;
6631 bool Success = A.checkForAllCallLikeInstructions(
6632 AllocationIdentifierCB, *this, UsedAssumedInformation,
6633 /* CheckBBLivenessOnly */ false,
6634 /* CheckPotentiallyDead */ true);
6635 (void)Success;
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),
6643 SCB);
6644 for (const auto &It : DeallocationInfos)
6645 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6646 SCB);
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;
6654 else
6655 ++NumH2SMallocs;
6657 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6658 std::to_string(NumInvalidMallocs);
6661 /// See AbstractAttribute::trackStatistics().
6662 void trackStatistics() const override {
6663 STATS_DECL(
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 {
6672 if (isValidState())
6673 if (AllocationInfo *AI =
6674 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6675 return AI->Status != AllocationInfo::INVALID;
6676 return false;
6679 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6680 if (!isValidState())
6681 return false;
6683 for (const auto &It : AllocationInfos) {
6684 AllocationInfo &AI = *It.second;
6685 if (AI.Status == AllocationInfo::INVALID)
6686 continue;
6688 if (AI.PotentialFreeCalls.count(&CB))
6689 return true;
6692 return false;
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)
6706 continue;
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
6715 << "\n");
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);
6726 else
6727 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6729 const DataLayout &DL = A.getInfoCache().getDL();
6730 Value *Size;
6731 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6732 if (SizeAPI) {
6733 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6734 } else {
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;
6744 Instruction *IP =
6745 AI.MoveAllocaIntoEntry ? &F->getEntryBlock().front() : AI.CB;
6747 Align Alignment(1);
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!");
6754 Alignment =
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);
6770 assert(InitVal &&
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);
6779 } else {
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;
6794 return HasChanged;
6797 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6798 Value &V) {
6799 bool UsedAssumedInformation = false;
6800 std::optional<Constant *> SimpleV =
6801 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6802 if (!SimpleV)
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))
6815 if (*SimpleV)
6816 return *SimpleV;
6817 return V;
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
6826 /// information.
6827 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6829 /// Collection of all free-like calls in a function with associated
6830 /// information.
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();
6850 LoopInfo *LI =
6851 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6852 std::optional<bool> MayContainIrreducibleControl;
6853 auto IsInLoop = [&](BasicBlock &BB) {
6854 if (&F->getEntryBlock() == &BB)
6855 return false;
6856 if (!MayContainIrreducibleControl.has_value())
6857 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6858 if (*MayContainIrreducibleControl)
6859 return true;
6860 if (!LI)
6861 return true;
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
6875 // them.
6876 if (DI.MightFreeUnknownObjects)
6877 continue;
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))
6883 continue;
6885 // Use the non-optimistic version to get the freed object.
6886 Value *Obj = getUnderlyingObject(DI.FreedOp);
6887 if (!Obj) {
6888 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6889 DI.MightFreeUnknownObjects = true;
6890 continue;
6893 // Free of null and undef can be ignored as no-ops (or UB in the latter
6894 // case).
6895 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj))
6896 continue;
6898 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
6899 if (!ObjCB) {
6900 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6901 << "\n");
6902 DI.MightFreeUnknownObjects = true;
6903 continue;
6906 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
6907 if (!AI) {
6908 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6909 << "\n");
6910 DI.MightFreeUnknownObjects = true;
6911 continue;
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) {
6923 bool IsKnownNoSycn;
6924 if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
6925 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
6926 LLVM_DEBUG(
6927 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6928 "other threads and function is not nosync:\n");
6929 return false;
6932 if (!HasUpdatedFrees)
6933 UpdateFrees();
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");
6939 return false;
6941 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
6942 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
6943 if (!DI) {
6944 LLVM_DEBUG(
6945 dbgs() << "[H2S] unique free call was not known as deallocation call "
6946 << *UniqueFree << "\n");
6947 return false;
6949 if (DI->MightFreeUnknownObjects) {
6950 LLVM_DEBUG(
6951 dbgs() << "[H2S] unique free call might free unknown allocations\n");
6952 return false;
6954 if (DI->PotentialAllocationCalls.empty())
6955 return true;
6956 if (DI->PotentialAllocationCalls.size() > 1) {
6957 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
6958 << DI->PotentialAllocationCalls.size()
6959 << " different allocations\n");
6960 return false;
6962 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
6963 LLVM_DEBUG(
6964 dbgs()
6965 << "[H2S] unique free call not known to free this allocation but "
6966 << **DI->PotentialAllocationCalls.begin() << "\n");
6967 return false;
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)) {
6974 LLVM_DEBUG(
6975 dbgs()
6976 << "[H2S] unique free call might not be executed with the allocation "
6977 << *UniqueFree << "\n");
6978 return false;
6981 return true;
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))
6990 return true;
6991 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
6992 if (SI->getValueOperand() == U.get()) {
6993 LLVM_DEBUG(dbgs()
6994 << "[H2S] escaping store to memory: " << *UserI << "\n");
6995 ValidUsesOnly = false;
6996 } else {
6997 // A store into the malloc'ed memory is fine.
6999 return true;
7001 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7002 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7003 return true;
7004 if (DeallocationInfos.count(CB)) {
7005 AI.PotentialFreeCalls.insert(CB);
7006 return true;
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.
7017 bool IsKnownNoFree;
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) {
7028 return 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;
7041 return true;
7044 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7045 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7046 Follow = true;
7047 return true;
7049 // Unknown user for which we can not track uses further (in a way that
7050 // makes sense).
7051 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7052 ValidUsesOnly = false;
7053 return true;
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);
7063 return false;
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)
7072 continue;
7074 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7075 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7076 if (!APAlign) {
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
7080 << "\n");
7081 AI.Status = AllocationInfo::INVALID;
7082 Changed = ChangeStatus::CHANGED;
7083 continue;
7085 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7086 !APAlign->isPowerOf2()) {
7087 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7088 << "\n");
7089 AI.Status = AllocationInfo::INVALID;
7090 Changed = ChangeStatus::CHANGED;
7091 continue;
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)) {
7099 LLVM_DEBUG({
7100 if (!Size)
7101 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7102 else
7103 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7104 << MaxHeapToStackSize << "\n";
7107 AI.Status = AllocationInfo::INVALID;
7108 Changed = ChangeStatus::CHANGED;
7109 continue;
7113 switch (AI.Status) {
7114 case AllocationInfo::STACK_DUE_TO_USE:
7115 if (UsesCheck(AI))
7116 break;
7117 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7118 [[fallthrough]];
7119 case AllocationInfo::STACK_DUE_TO_FREE:
7120 if (FreeCheck(AI))
7121 break;
7122 AI.Status = AllocationInfo::INVALID;
7123 Changed = ChangeStatus::CHANGED;
7124 break;
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;
7140 return Changed;
7142 } // namespace
7144 /// ----------------------- Privatizable Pointers ------------------------------
7145 namespace {
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
7158 /// none.
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) {
7165 if (!T0)
7166 return T1;
7167 if (!T1)
7168 return T0;
7169 if (T0 == T1)
7170 return T0;
7171 return nullptr;
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]";
7182 protected:
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)
7219 return false;
7221 // Check that all call sites agree on a type.
7222 auto *PrivCSArgAA =
7223 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7224 if (!PrivCSArgAA)
7225 return false;
7226 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7228 LLVM_DEBUG({
7229 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7230 if (CSTy && *CSTy)
7231 (*CSTy)->print(dbgs());
7232 else if (CSTy)
7233 dbgs() << "<nullptr>";
7234 else
7235 dbgs() << "<none>";
7238 Ty = combineTypes(Ty, CSTy);
7240 LLVM_DEBUG({
7241 dbgs() << " : New Type: ";
7242 if (Ty && *Ty)
7243 (*Ty)->print(dbgs());
7244 else if (Ty)
7245 dbgs() << "<nullptr>";
7246 else
7247 dbgs() << "<none>";
7248 dbgs() << "\n";
7251 return !Ty || *Ty;
7254 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7255 UsedAssumedInformation))
7256 return nullptr;
7257 return Ty;
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
7269 // alignment.
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
7281 // signature.
7282 SmallVector<Type *, 16> ReplacementTypes;
7283 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7285 // Verify callee and caller agree on how the promoted argument would be
7286 // passed.
7287 Function &Fn = *getIRPosition().getAnchorScope();
7288 const auto *TTI =
7289 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7290 if (!TTI) {
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(
7299 CB->getCaller(),
7300 dyn_cast_if_present<Function>(CB->getCalledOperand()),
7301 ReplacementTypes);
7303 bool UsedAssumedInformation = false;
7304 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7305 UsedAssumedInformation)) {
7306 LLVM_DEBUG(
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);
7332 LLVM_DEBUG({
7333 dbgs()
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 "
7338 "callback ("
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))
7348 continue;
7349 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7350 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7351 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7352 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7353 if (!CBArgPrivTy)
7354 continue;
7355 if (*CBArgPrivTy == PrivatizableType)
7356 continue;
7359 LLVM_DEBUG({
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 "
7364 "callback ("
7365 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7366 << ").\n[AAPrivatizablePtr] for which the argument "
7367 "privatization is not compatible.\n";
7369 return false;
7372 return true;
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());
7385 LLVM_DEBUG({
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 "
7390 "direct call of ("
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();
7400 if (!DCArgPrivTy)
7401 return true;
7402 if (*DCArgPrivTy == PrivatizableType)
7403 return true;
7407 LLVM_DEBUG({
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 "
7412 "direct call of ("
7413 << ACS.getInstruction()->getCalledOperand()->getName()
7414 << ").\n[AAPrivatizablePtr] for which the argument "
7415 "privatization is not compatible.\n";
7417 return false;
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
7422 // here.
7423 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7424 if (ACS.isDirectCall())
7425 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7426 if (ACS.isCallbackCall())
7427 return IsCompatiblePrivArgOfDirectCS(ACS);
7428 return false;
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.
7440 static void
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());
7454 } else {
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();
7474 Value *Ptr =
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);
7488 } else {
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);
7515 Value *Ptr =
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);
7533 } else {
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);
7556 return true;
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()),
7603 NewArgOperands);
7606 // Collect the types that will replace the privatizable type in the function
7607 // signature.
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());
7643 if (!Obj) {
7644 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7645 return nullptr;
7648 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7649 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7650 if (CI->isOne())
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: "
7661 << *Obj << "!\n");
7662 return nullptr;
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();
7706 bool IsKnown;
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);
7753 } // namespace
7755 /// -------------------- Memory Behavior Attributes ----------------------------
7756 /// Includes read-none, read-only, and write-only.
7757 /// ----------------------------------------------------------------------------
7758 namespace {
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);
7780 break;
7781 case Attribute::ReadOnly:
7782 State.addKnownBits(NO_WRITES);
7783 break;
7784 case Attribute::WriteOnly:
7785 State.addKnownBits(NO_READS);
7786 break;
7787 default:
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())
7840 return "readnone";
7841 if (isAssumedReadOnly())
7842 return "readonly";
7843 if (isAssumedWriteOnly())
7844 return "writeonly";
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)
7873 private:
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();
7937 if (!Arg) {
7938 indicatePessimisticFixpoint();
7939 return;
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);
7959 auto *ArgAA =
7960 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
7961 if (!ArgAA)
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);
8118 if (FnMemAA) {
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,
8137 &ArgNoCaptureAA);
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
8150 << " \n");
8152 // Droppable users, e.g., llvm::assume does not actually perform any action.
8153 if (UserI->isDroppable())
8154 return true;
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))
8178 return false;
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))
8184 return true;
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);
8200 return true;
8203 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8204 const Instruction *UserI) {
8205 assert(UserI->mayReadOrWriteMemory());
8207 switch (UserI->getOpcode()) {
8208 default:
8209 // TODO: Handle all atomics and other side-effect operations we know of.
8210 break;
8211 case Instruction::Load:
8212 // Loads cause the NO_READS property to disappear.
8213 removeAssumedBits(NO_READS);
8214 return;
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);
8222 else
8223 indicatePessimisticFixpoint();
8224 return;
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();
8236 return;
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);
8243 break;
8246 // Adjust the possible access behavior based on the information on the
8247 // argument.
8248 IRPosition Pos;
8249 if (U.get()->getType()->isPointerTy())
8250 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
8251 else
8252 Pos = IRPosition::callsite_function(*CB);
8253 const auto *MemBehaviorAA =
8254 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8255 if (!MemBehaviorAA)
8256 break;
8257 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8258 // and at least "known".
8259 intersectAssumedBits(MemBehaviorAA->getAssumed());
8260 return;
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);
8271 } // namespace
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)
8283 return "no memory";
8284 std::string S = "memory:";
8285 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8286 S += "stack,";
8287 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8288 S += "constant,";
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))
8294 S += "argument,";
8295 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM))
8296 S += "inaccessible,";
8297 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8298 S += "malloced,";
8299 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8300 S += "unknown,";
8301 S.pop_back();
8302 return S;
8305 namespace {
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)
8317 if (AS)
8318 AS->~AccessSet();
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);
8352 continue;
8354 if (ME.onlyAccessesInaccessibleMem()) {
8355 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8356 continue;
8358 if (ME.onlyAccessesArgPointees()) {
8359 if (UseArgMemOnly)
8360 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8361 else {
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);
8369 continue;
8371 if (ME.onlyAccessesInaccessibleOrArgMem()) {
8372 if (UseArgMemOnly)
8373 State.addKnownBits(inverseLocation(
8374 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8375 else {
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);
8383 continue;
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())
8395 Attrs.push_back(
8396 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8397 else if (isAssumedInaccessibleMemOnly())
8398 Attrs.push_back(Attribute::getWithMemoryEffects(
8399 Ctx, MemoryEffects::inaccessibleMemOnly()));
8400 else if (isAssumedArgMemOnly())
8401 Attrs.push_back(
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)>
8430 Pred,
8431 MemoryLocationsKind RequestedMLK) const override {
8432 if (!isValidState())
8433 return false;
8435 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8436 if (AssumedMLK == NO_LOCATIONS)
8437 return true;
8439 unsigned Idx = 0;
8440 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8441 CurMLK *= 2, ++Idx) {
8442 if (CurMLK & RequestedMLK)
8443 continue;
8445 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8446 for (const AccessInfo &AI : *Accesses)
8447 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8448 return false;
8451 return true;
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();
8469 protected:
8470 /// Helper struct to tie together an instruction that has a read or write
8471 /// effect with the pointer it accesses (if any).
8472 struct AccessInfo {
8474 /// The instruction that caused the access.
8475 const Instruction *I;
8477 /// The base pointer that is accessed, or null if unknown.
8478 const Value *Ptr;
8480 /// The kind of access (read/write/read+write).
8481 AccessKind Kind;
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 {
8487 if (LHS.I != RHS.I)
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;
8493 return false;
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.
8504 void
8505 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8506 AAMemoryLocation::StateType &AccessedLocs,
8507 bool &Changed);
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;
8516 if (I) {
8517 AK = I->mayReadFromMemory() ? READ : NONE;
8518 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8520 return AK;
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
8525 /// pointer \p Ptr.
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)];
8533 if (!Accesses)
8534 Accesses = new (Allocator) AccessSet();
8535 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8536 if (MLK == NO_UNKOWN_MEM)
8537 MLK = NO_LOCATIONS;
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 "
8555 << Ptr << " ["
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()))
8569 return true;
8571 if (isa<UndefValue>(&Obj))
8572 return true;
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())
8587 return true;
8589 if (GV->hasLocalLinkage())
8590 MLK = NO_GLOBAL_INTERNAL_MEM;
8591 else
8592 MLK = NO_GLOBAL_EXTERNAL_MEM;
8593 } else if (isa<ConstantPointerNull>(&Obj) &&
8594 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8595 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8596 return true;
8597 } else if (isa<AllocaInst>(&Obj)) {
8598 MLK = NO_LOCAL_MEM;
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,
8603 IsKnownNoAlias))
8604 MLK = NO_MALLOCED_MEM;
8605 else
8606 MLK = NO_UNKOWN_MEM;
8607 } else {
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));
8617 return true;
8620 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8621 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL);
8622 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8623 LLVM_DEBUG(
8624 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8625 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8626 getAccessKindFromInst(&I));
8627 return;
8630 LLVM_DEBUG(
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,
8637 bool &Changed) {
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())
8643 continue;
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())
8651 continue;
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,
8661 bool &Changed) {
8662 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8663 << I << "\n");
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)
8699 continue;
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));
8712 return true;
8714 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8715 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8716 return AccessedLocs.getWorstState();
8719 LLVM_DEBUG(
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);
8725 if (HasArgAccesses)
8726 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8728 LLVM_DEBUG(
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)) {
8736 LLVM_DEBUG(
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: "
8745 << I << "\n");
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);
8819 auto *FnAA =
8820 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8821 if (!FnAA)
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));
8828 return true;
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)
8841 } // namespace
8843 /// ------------------ denormal-fp-math Attribute -------------------------
8845 namespace {
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;
8857 else
8858 OS << "invalid";
8860 if (Known.ModeF32.isValid())
8861 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8862 OS << ']';
8863 return OS.str();
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())
8880 ModeF32 = Mode;
8881 Known = DenormalState{Mode, ModeF32};
8882 if (isModeFixed())
8883 indicateFixpoint();
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);
8896 if (!CallerInfo)
8897 return false;
8899 Change = Change | clampStateAndIndicateChange(this->getState(),
8900 CallerInfo->getState());
8901 return true;
8904 bool AllCallSitesKnown = true;
8905 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
8906 return indicatePessimisticFixpoint();
8908 if (Change == ChangeStatus::CHANGED && isModeFixed())
8909 indicateFixpoint();
8910 return Change;
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");
8920 } else {
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()));
8928 } else {
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)
8943 } // namespace
8945 /// ------------------ Value Constant Range Attribute -------------------------
8947 namespace {
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();
8957 return;
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 {
8969 std::string Str;
8970 llvm::raw_string_ostream OS(Str);
8971 OS << "range(" << getBitWidth() << ")<";
8972 getKnown().print(OS);
8973 OS << " / ";
8974 getAssumed().print(OS);
8975 OS << ">";
8976 return OS.str();
8979 /// Helper function to get a SCEV expr for the associated value at program
8980 /// point \p I.
8981 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
8982 if (!getAnchorScope())
8983 return nullptr;
8985 ScalarEvolution *SE =
8986 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
8987 *getAnchorScope());
8989 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
8990 *getAnchorScope());
8992 if (!SE || !LI)
8993 return nullptr;
8995 const SCEV *S = SE->getSCEV(&getAssociatedValue());
8996 if (!I)
8997 return S;
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>(
9011 *getAnchorScope());
9013 const SCEV *S = getSCEV(A, I);
9014 if (!SE || !S)
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.
9022 ConstantRange
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>(
9030 *getAnchorScope());
9032 if (!LVI || !CtxI)
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()))
9047 return false;
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()))
9052 return false;
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>(
9061 *I->getFunction());
9062 return DT && DT->dominates(I, CtxI);
9065 return true;
9068 /// See AAValueConstantRange::getKnownConstantRange(..).
9069 ConstantRange
9070 getKnownConstantRange(Attributor &A,
9071 const Instruction *CtxI = nullptr) const override {
9072 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9073 /* AllowAACtxI */ false))
9074 return getKnown();
9076 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9077 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9078 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9081 /// See AAValueConstantRange::getAssumedConstantRange(..).
9082 ConstantRange
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.
9099 static MDNode *
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())
9113 return false;
9115 if (!KnownRanges)
9116 return true;
9118 // If multiple ranges are annotated in IR, we give up to annotate assumed
9119 // range for now.
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)
9124 return false;
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.
9136 static bool
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));
9145 return true;
9148 return false;
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;
9169 return 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)
9181 : Base(IRP, 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> {
9194 using Base =
9195 AAReturnedFromReturnedValues<AAValueConstantRange,
9196 AAValueConstantRangeImpl,
9197 AAValueConstantRangeImpl::StateType,
9198 /* PropogateCallBaseContext */ true>;
9199 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9200 : Base(IRP, 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);
9221 if (isAtFixpoint())
9222 return;
9224 Value &V = getAssociatedValue();
9226 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9227 unionAssumed(ConstantRange(C->getValue()));
9228 indicateOptimisticFixpoint();
9229 return;
9232 if (isa<UndefValue>(&V)) {
9233 // Collapse the undef state to 0.
9234 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9235 indicateOptimisticFixpoint();
9236 return;
9239 if (isa<CallBase>(&V))
9240 return;
9242 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9243 return;
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));
9249 return;
9252 // We can work with PHI and select instruction as we traverse their operands
9253 // during update.
9254 if (isa<SelectInst>(V) || isa<PHINode>(V))
9255 return;
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())
9277 return true;
9278 if (!*SimplifiedLHS)
9279 return false;
9280 LHS = *SimplifiedLHS;
9282 const auto &SimplifiedRHS = A.getAssumedSimplified(
9283 IRPosition::value(*RHS, getCallBaseContext()), *this,
9284 UsedAssumedInformation, AA::Interprocedural);
9285 if (!SimplifiedRHS.has_value())
9286 return true;
9287 if (!*SimplifiedRHS)
9288 return false;
9289 RHS = *SimplifiedRHS;
9291 // TODO: Allow non integers as well.
9292 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9293 return false;
9295 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9296 *this, IRPosition::value(*LHS, getCallBaseContext()),
9297 DepClassTy::REQUIRED);
9298 if (!LHSAA)
9299 return false;
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);
9306 if (!RHSAA)
9307 return false;
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())
9334 return true;
9335 if (!*SimplifiedOpV)
9336 return false;
9337 OpV = *SimplifiedOpV;
9339 if (!OpV->getType()->isIntegerTy())
9340 return false;
9342 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9343 *this, IRPosition::value(*OpV, getCallBaseContext()),
9344 DepClassTy::REQUIRED);
9345 if (!OpAA)
9346 return false;
9347 QuerriedAAs.push_back(OpAA);
9348 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9349 getState().getBitWidth()));
9350 return T.isValidState();
9353 bool
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())
9366 return true;
9367 if (!*SimplifiedLHS)
9368 return false;
9369 LHS = *SimplifiedLHS;
9371 const auto &SimplifiedRHS = A.getAssumedSimplified(
9372 IRPosition::value(*RHS, getCallBaseContext()), *this,
9373 UsedAssumedInformation, AA::Interprocedural);
9374 if (!SimplifiedRHS.has_value())
9375 return true;
9376 if (!*SimplifiedRHS)
9377 return false;
9378 RHS = *SimplifiedRHS;
9380 // TODO: Allow non integers as well.
9381 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9382 return false;
9384 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9385 *this, IRPosition::value(*LHS, getCallBaseContext()),
9386 DepClassTy::REQUIRED);
9387 if (!LHSAA)
9388 return false;
9389 QuerriedAAs.push_back(LHSAA);
9390 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9391 *this, IRPosition::value(*RHS, getCallBaseContext()),
9392 DepClassTy::REQUIRED);
9393 if (!RHSAA)
9394 return false;
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())
9401 return true;
9403 bool MustTrue = false, MustFalse = false;
9405 auto AllowedRegion =
9406 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
9408 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9409 MustFalse = true;
9411 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9412 MustTrue = true;
9414 assert((!MustTrue || !MustFalse) &&
9415 "Either MustTrue or MustFalse should be false!");
9417 if (MustTrue)
9418 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9419 else if (MustFalse)
9420 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9421 else
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"
9427 << *RHSAA);
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())
9447 return true;
9448 if (!*SimplifiedOpV)
9449 return false;
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.
9458 if (AA)
9459 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9460 else
9461 return false;
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))
9469 return false;
9470 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9471 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9472 return false;
9473 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9474 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9475 return false;
9476 } else {
9477 // Give up with other instructions.
9478 // TODO: Add other instructions
9480 T.indicatePessimisticFixpoint();
9481 return false;
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)
9489 continue;
9490 // If we are in a stady state we do not need to worry.
9491 if (T.getAssumed() == getState().getAssumed())
9492 continue;
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.
9521 int NumChanges = 0;
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 "
9535 "not be called");
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)
9588 } // namespace
9590 /// ------------------ Potential Values Attribute -------------------------
9592 namespace {
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();
9603 else
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
9614 // IRP itself.
9615 if (ForSelf)
9616 return false;
9617 if (!IRP.getAssociatedType()->isIntegerTy())
9618 return false;
9619 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9620 *this, IRP, DepClassTy::REQUIRED);
9621 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9622 return false;
9623 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9624 S = PotentialValuesAA->getState().getAssumedSet();
9625 return true;
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;
9635 continue;
9637 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9638 if (!CI)
9639 return false;
9640 S.insert(CI->getValue());
9642 ContainsUndef &= S.empty();
9644 return true;
9647 /// See AbstractAttribute::getAsStr().
9648 const std::string getAsStr(Attributor *A) const override {
9649 std::string Str;
9650 llvm::raw_string_ostream OS(Str);
9651 OS << getState();
9652 return 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)
9669 : Base(IRP, 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)
9683 : Base(IRP, 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);
9704 if (isAtFixpoint())
9705 return;
9707 Value &V = getAssociatedValue();
9709 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9710 unionAssumed(C->getValue());
9711 indicateOptimisticFixpoint();
9712 return;
9715 if (isa<UndefValue>(&V)) {
9716 unionAssumedWithUndef();
9717 indicateOptimisticFixpoint();
9718 return;
9721 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9722 return;
9724 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9725 return;
9727 indicatePessimisticFixpoint();
9729 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9730 << getAssociatedValue() << "\n");
9733 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9734 const APInt &RHS) {
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();
9741 switch (CastOp) {
9742 default:
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:
9751 return Src;
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
9761 // (LHS, RHS).
9762 // TODO: we should look at nsw and nuw keywords to handle operations
9763 // that create poison or undef value.
9764 switch (BinOpcode) {
9765 default:
9766 Unsupported = true;
9767 return LHS;
9768 case Instruction::Add:
9769 return LHS + RHS;
9770 case Instruction::Sub:
9771 return LHS - RHS;
9772 case Instruction::Mul:
9773 return LHS * RHS;
9774 case Instruction::UDiv:
9775 if (RHS.isZero()) {
9776 SkipOperation = true;
9777 return LHS;
9779 return LHS.udiv(RHS);
9780 case Instruction::SDiv:
9781 if (RHS.isZero()) {
9782 SkipOperation = true;
9783 return LHS;
9785 return LHS.sdiv(RHS);
9786 case Instruction::URem:
9787 if (RHS.isZero()) {
9788 SkipOperation = true;
9789 return LHS;
9791 return LHS.urem(RHS);
9792 case Instruction::SRem:
9793 if (RHS.isZero()) {
9794 SkipOperation = true;
9795 return LHS;
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:
9805 return LHS & RHS;
9806 case Instruction::Or:
9807 return LHS | RHS;
9808 case Instruction::Xor:
9809 return LHS ^ RHS;
9813 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9814 const APInt &LHS, const APInt &RHS) {
9815 bool SkipOperation = false;
9816 bool Unsupported = false;
9817 APInt Result =
9818 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9819 if (Unsupported)
9820 return false;
9821 // If SkipOperation is true, we can ignore this operand pair (L, R).
9822 if (!SkipOperation)
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
9845 // with undef.
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();
9863 } else {
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();
9874 if (MaybeTrue)
9875 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9876 if (MaybeFalse)
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())
9894 OnlyLeft = true;
9895 else if (C && *C && (*C)->isZeroValue())
9896 OnlyRight = true;
9898 bool LHSContainsUndef = false, RHSContainsUndef = false;
9899 SetTy LHSAAPVS, RHSAAPVS;
9900 if (!OnlyRight &&
9901 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9902 LHSContainsUndef, /* ForSelf */ false))
9903 return indicatePessimisticFixpoint();
9905 if (!OnlyLeft &&
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;
9915 if (Undef)
9916 unionAssumedWithUndef();
9917 else {
9918 for (const auto &It : *OpAA)
9919 unionAssumed(It);
9922 } else if (LHSContainsUndef && RHSContainsUndef) {
9923 // select i1 *, undef , undef => undef
9924 unionAssumedWithUndef();
9925 } else {
9926 for (const auto &It : LHSAAPVS)
9927 unionAssumed(It);
9928 for (const auto &It : RHSAAPVS)
9929 unionAssumed(It);
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;
9944 SetTy SrcPVS;
9945 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
9946 SrcContainsUndef, /* ForSelf */ false))
9947 return indicatePessimisticFixpoint();
9949 if (SrcContainsUndef)
9950 unionAssumedWithUndef();
9951 else {
9952 for (const APInt &S : SrcPVS) {
9953 APInt T = calculateCastInst(CI, S, ResultBitWidth);
9954 unionAssumed(T);
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();
9990 } else {
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();
10004 SetTy Incoming;
10005 bool ContainsUndef;
10006 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10007 ContainsUndef, /* ForSelf */ true))
10008 return indicatePessimisticFixpoint();
10009 if (ContainsUndef) {
10010 unionAssumedWithUndef();
10011 } else {
10012 for (const auto &It : Incoming)
10013 unionAssumed(It);
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 {
10054 llvm_unreachable(
10055 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10056 "not be called");
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,
10079 Attributor &A)
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,
10092 Attributor &A)
10093 : AAPotentialConstantValuesFloating(IRP, A) {}
10095 /// See AbstractAttribute::initialize(..).
10096 void initialize(Attributor &A) override {
10097 AAPotentialConstantValuesImpl::initialize(A);
10098 if (isAtFixpoint())
10099 return;
10101 Value &V = getAssociatedValue();
10103 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10104 unionAssumed(C->getValue());
10105 indicateOptimisticFixpoint();
10106 return;
10109 if (isa<UndefValue>(&V)) {
10110 unionAssumedWithUndef();
10111 indicateOptimisticFixpoint();
10112 return;
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);
10122 if (!AA)
10123 return indicatePessimisticFixpoint();
10124 const auto &S = AA->getAssumed();
10125 unionAssumed(S);
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)
10135 } // namespace
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))
10145 return true;
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));
10152 return true;
10155 return false;
10158 namespace {
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))
10186 TrackUse = true;
10187 return TrackUse;
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
10198 // values.
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)
10208 .has_value())
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);
10235 bool Stripped;
10236 bool UsedAssumedInformation = false;
10237 Value *AssociatedValue = &getAssociatedValue();
10238 SmallVector<AA::ValueAndContext> Values;
10239 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10240 AA::AnyScope, UsedAssumedInformation))
10241 Stripped = false;
10242 else
10243 Stripped =
10244 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10246 if (!Stripped) {
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
10250 // value.
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();
10314 return;
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;
10357 return TrackUse;
10360 const std::string getAsStr(Attributor *A) const override {
10361 std::string Result = "nofpclass";
10362 raw_string_ostream OS(Result);
10363 OS << getAssumedNoFPClass();
10364 return Result;
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()});
10386 StateType T;
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();
10392 } else {
10393 const AANoFPClass::StateType &S =
10394 static_cast<const AANoFPClass::StateType &>(AA->getState());
10395 T ^= S;
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>(
10419 IRP, A) {}
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 {}
10477 protected:
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()
10482 << "\n");
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;
10495 private:
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);
10516 } else {
10517 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10518 setHasUnknownCallee(true, Change);
10521 // Explore all values.
10522 return true;
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);
10530 return;
10533 bool UsedAssumedInformation = false;
10534 Values.clear();
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);
10551 return 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); }))
10559 return Change;
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);
10570 return Change;
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);
10587 if (!CBEdges)
10588 return false;
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);
10597 return true;
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);
10610 return 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)
10620 : Base(IRP, 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,
10643 IsTemporaryRQI);
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())
10649 return false;
10650 // TODO Check To backwards in this case.
10651 if (CBEdges->hasUnknownCallee())
10652 return false;
10654 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10655 if (Fn == RQI.To)
10656 return false;
10658 if (Fn->isDeclaration()) {
10659 if (Fn->hasFnAttribute(Attribute::NoCallback))
10660 continue;
10661 // TODO Check To backwards in this case.
10662 return false;
10665 if (Fn == getAnchorScope()) {
10666 if (EntryI == RQI.From)
10667 continue;
10668 return false;
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,
10678 RQI.ExclusionSet))
10679 return false;
10681 return true;
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)))
10693 return true;
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,
10704 IsTemporaryRQI);
10706 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10707 IsTemporaryRQI);
10710 void trackStatistics() const override {}
10712 } // namespace
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())
10719 return nullptr;
10721 // This will also pass the call base context.
10722 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10723 if (!AA)
10724 return nullptr;
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);
10734 return C;
10736 return nullptr;
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)
10747 break;
10749 if (!V.has_value())
10750 return UndefValue::get(&Ty);
10751 return *V;
10754 namespace {
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();
10765 return;
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,
10772 getAnchorScope());
10773 indicateOptimisticFixpoint();
10774 return;
10776 AAPotentialValues::initialize(A);
10779 /// See AbstractAttribute::getAsStr().
10780 const std::string getAsStr(Attributor *A) const override {
10781 std::string Str;
10782 llvm::raw_string_ostream OS(Str);
10783 OS << getState();
10784 return 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);
10794 if (!C)
10795 return std::nullopt;
10796 if (*C)
10797 if (auto *CC = AA::getWithType(**C, Ty))
10798 return CC;
10799 return nullptr;
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()) {
10809 if (U.get() != &V)
10810 continue;
10811 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10812 break;
10816 Value *VPtr = &V;
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});
10829 return;
10832 if (!SimpleV.has_value())
10833 return;
10835 if (*SimpleV)
10836 VPtr = *SimpleV;
10839 if (isa<ConstantInt>(VPtr))
10840 CtxI = nullptr;
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.
10849 struct ItemInfo {
10850 AA::ValueAndContext I;
10851 AA::ValueScope S;
10853 bool operator==(const ItemInfo &II) const {
10854 return II.I == I && II.S == S;
10856 bool operator<(const ItemInfo &II) const {
10857 if (I == II.I)
10858 return S < II.S;
10859 return I < II.I;
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}) {
10866 if (!(CS & S))
10867 continue;
10869 bool UsedAssumedInformation = false;
10870 SmallVector<AA::ValueAndContext> Values;
10871 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10872 UsedAssumedInformation))
10873 return false;
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());
10882 return true;
10885 void giveUpOnIntraprocedural(Attributor &A) {
10886 auto NewS = StateType::getBestState(getState());
10887 for (const auto &It : getAssumedSet()) {
10888 if (It.second == AA::Intraprocedural)
10889 continue;
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,
10895 getAnchorScope());
10896 getState() = NewS;
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}) {
10916 Values.clear();
10917 if (!getAssumedSimplifiedValues(A, Values, S))
10918 continue;
10919 Value &OldV = getAssociatedValue();
10920 if (isa<UndefValue>(OldV))
10921 continue;
10922 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
10923 if (!NewV || NewV == &OldV)
10924 continue;
10925 if (getCtxI() &&
10926 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
10927 continue;
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())
10938 return false;
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))
10947 continue;
10949 Values.push_back(It.first);
10951 assert(!undefIsContained() && "Undef should be an explicit value!");
10952 return true;
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)) {
10993 Values.clear();
10994 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
10996 return Values.empty();
10998 if (GetSimplifiedValues(*LHS, LHSValues))
10999 return true;
11000 if (GetSimplifiedValues(*RHS, RHSValues))
11001 return true;
11003 LLVMContext &Ctx = LHS->getContext();
11005 InformationCache &InfoCache = A.getInfoCache();
11006 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11007 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11008 const auto *DT =
11009 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11010 : nullptr;
11011 const auto *TLI =
11012 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11013 auto *AC =
11014 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11015 : nullptr;
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());
11024 return true;
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,
11034 getAnchorScope());
11035 return true;
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,
11044 getAnchorScope());
11045 return true;
11049 // From now on we only handle equalities (==, !=).
11050 if (!CmpInst::isEquality(Pred))
11051 return false;
11053 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11054 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11055 if (!LHSIsNull && !RHSIsNull)
11056 return false;
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)
11071 return false;
11073 // The new value depends on the predicate, true for != and false for ==.
11074 Constant *NewV =
11075 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11076 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11077 getAnchorScope());
11078 return true;
11081 for (auto &LHSValue : LHSValues)
11082 for (auto &RHSValue : RHSValues)
11083 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11084 return false;
11085 return true;
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))
11097 return true;
11098 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11099 if (CI->isZero())
11100 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11101 else
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});
11107 } else {
11108 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11109 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11110 if (!SimpleV.has_value())
11111 return true;
11112 if (*SimpleV) {
11113 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11114 return true;
11116 return false;
11118 return true;
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 "
11132 << LI << "\n");
11133 return false;
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))
11143 return true;
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);
11152 })) {
11153 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11154 "and we cannot delete all the stores: "
11155 << LI << "\n");
11156 return false;
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: "
11173 << LI << "\n");
11174 return false;
11177 for (auto *PotentialCopy : PotentialCopies) {
11178 if (AllLocal) {
11179 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11180 } else {
11181 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11184 if (!AllLocal && ScopeIsLocal)
11185 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11186 return true;
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),
11197 DepClassTy::NONE);
11198 return LI;
11201 if (&PHI == &getAssociatedValue()) {
11202 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11203 const auto *CI =
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())) {
11213 LI.AnyDead = true;
11214 continue;
11216 Value *V = PHI.getIncomingValue(u);
11217 if (V == &PHI)
11218 continue;
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())))
11224 return false;
11226 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11228 return true;
11231 bool UsedAssumedInformation = false;
11232 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11233 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11234 if (!SimpleV.has_value())
11235 return true;
11236 if (!(*SimpleV))
11237 return false;
11238 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11239 return true;
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());
11251 int Idx = 0;
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())
11259 return true;
11261 if (*SimplifiedOp)
11262 NewOps[Idx] = *SimplifiedOp;
11263 else
11264 NewOps[Idx] = Op;
11266 SomeSimplified |= (NewOps[Idx] != Op);
11267 ++Idx;
11270 // We won't bother with the InstSimplify interface if we didn't simplify any
11271 // operand ourselves.
11272 if (!SomeSimplified)
11273 return false;
11275 InformationCache &InfoCache = A.getInfoCache();
11276 Function *F = I.getFunction();
11277 const auto *DT =
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)
11286 return false;
11288 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11289 << *NewV << "\n");
11290 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11291 return true;
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);
11309 default:
11310 return handleGenericInst(A, I, II, Worklist);
11312 return false;
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});
11322 int Iteration = 0;
11323 do {
11324 ItemInfo II = Worklist.pop_back_val();
11325 Value *V = II.I.getValue();
11326 assert(V);
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)
11333 continue;
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());
11340 continue;
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());
11348 } else {
11349 if (auto *CB = dyn_cast<CallBase>(V))
11350 if (auto *Callee =
11351 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
11352 for (Argument &Arg : Callee->args())
11353 if (Arg.hasReturnedAttr()) {
11354 NewV = CB->getArgOperand(Arg.getArgNo());
11355 break;
11359 if (NewV && NewV != V) {
11360 Worklist.push_back({{*NewV, CtxI}, S});
11361 continue;
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))
11368 continue;
11371 if (auto *I = dyn_cast<Instruction>(V)) {
11372 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11373 continue;
11376 if (V != InitialV || isa<Argument>(V))
11377 if (recurseForValue(A, IRPosition::value(*V), II.S))
11378 continue;
11380 // If we haven't stripped anything we give up.
11381 if (V == InitialV && CtxI == getCtxI()) {
11382 indicatePessimisticFixpoint();
11383 return;
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
11390 // dependence.
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)
11405 : Base(IRP, 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)
11425 return false;
11427 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11428 AA::Interprocedural,
11429 UsedAssumedInformation))
11430 return false;
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,
11445 getAnchorScope());
11446 continue;
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,
11454 getAnchorScope());
11455 continue;
11457 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11458 getAnchorScope());
11459 AnyNonLocal = true;
11461 assert(!undefIsContained() && "Undef should be an explicit value!");
11462 if (AnyNonLocal)
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)
11478 : Base(IRP, 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();
11485 return;
11488 for (Argument &Arg : F->args())
11489 if (Arg.hasReturnedAttr()) {
11490 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11491 ReturnedArg = &Arg;
11492 break;
11494 if (!A.isFunctionIPOAmendable(*F) ||
11495 A.hasSimplificationCallback(getIRPosition())) {
11496 if (!ReturnedArg)
11497 indicatePessimisticFixpoint();
11498 else
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,
11511 bool AddValues) {
11512 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) {
11513 Values.clear();
11514 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11515 UsedAssumedInformation,
11516 /* RecurseForSelectAndPHI */ true))
11517 return false;
11518 if (!AddValues)
11519 continue;
11520 for (const AA::ValueAndContext &VAC : Values)
11521 addValue(A, getState(), *VAC.getValue(),
11522 VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope);
11524 return true;
11527 if (ReturnedArg) {
11528 HandleReturnedValue(*ReturnedArg, nullptr, true);
11529 } else {
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,
11535 AnchorScope);
11536 AddValues = false;
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)
11557 return;
11558 Base::addValue(A, State, V, CtxI, S, AnchorScope);
11561 ChangeStatus manifest(Attributor &A) override {
11562 if (ReturnedArg)
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);
11569 if (!NewVal)
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)
11585 return true;
11586 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11587 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11588 Changed = ChangeStatus::CHANGED;
11589 return true;
11591 bool UsedAssumedInformation = false;
11592 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11593 UsedAssumedInformation,
11594 /* CheckBBLivenessOnly */ true);
11595 return Changed;
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 "
11617 "not be called");
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();
11645 if (!Callee)
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.
11670 continue;
11672 V = *CallerV ? *CallerV : V;
11673 if (AA::isDynamicallyUnique(A, *this, *V) &&
11674 AA::isValidInScope(*V, Caller)) {
11675 if (*CallerV) {
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))
11682 continue;
11684 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope());
11685 } else {
11686 AnyNonLocal = true;
11687 break;
11690 if (AnyNonLocal) {
11691 Values.clear();
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());
11704 } else {
11705 AnyNonLocal = true;
11706 addValue(A, getState(), *V, CB, AA::Interprocedural,
11707 getAnchorScope());
11710 if (AnyNonLocal)
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)
11736 } // namespace
11738 /// ---------------------- Assumption Propagation ------------------------------
11739 namespace {
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(
11753 IRP,
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())
11772 ? "Universal"
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);
11803 if (!AssumptionAA)
11804 return false;
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);
11842 if (!AssumptionAA)
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 {}
11851 private:
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;
11864 } // namespace
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 ---------------------------------
11875 namespace {
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 ") +
11884 (isValidState()
11885 ? (std::string("inter #") +
11886 std::to_string(InterAssumedUnderlyingObjects.size()) +
11887 " objs" + std::string(", intra #") +
11888 std::to_string(IntraAssumedUnderlyingObjects.size()) +
11889 " objs")
11890 : "<invalid>");
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);
11921 return true;
11924 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
11925 llvm_unreachable(
11926 "The forall call should not return false at this position");
11928 continue;
11931 if (isa<SelectInst>(Obj)) {
11932 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope);
11933 continue;
11935 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
11936 // Explicitly look through PHIs as we do not care about dynamically
11937 // uniqueness.
11938 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
11939 Changed |= handleIndirect(A, *PHI->getIncomingValue(u),
11940 UnderlyingObjects, Scope);
11942 continue;
11945 Changed |= UnderlyingObjects.insert(Obj);
11948 return Changed;
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)
11968 if (!Pred(*Obj))
11969 return false;
11971 return true;
11974 private:
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);
11985 return true;
11987 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
11988 llvm_unreachable(
11989 "The forall call should not return false at this position");
11990 return Changed;
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) {}
12033 } // namespace
12035 /// ------------------------ Global Value Info -------------------------------
12036 namespace {
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());
12047 if (!UInst) {
12048 Follow = true;
12049 return true;
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)))
12058 return true;
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());
12066 return true;
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))
12073 return false;
12074 return true;
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);
12080 if (!CB)
12081 return false;
12082 // Direct calls are OK uses.
12083 if (CB->isCallee(&U))
12084 return true;
12085 // Non-argument uses are scary.
12086 if (!CB->isArgOperand(&U))
12087 return false;
12088 // TODO: Iterate callees.
12089 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12090 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12091 return false;
12093 unsigned ArgNo = CB->getArgOperandNo(&U);
12094 Worklist.push_back(Fn->getArg(ArgNo));
12095 return true;
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 {
12106 Uses.insert(&U);
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:
12113 Follow = true;
12114 return true;
12116 return true;
12118 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12119 Uses.insert(&OldU);
12120 return true;
12123 while (!Worklist.empty()) {
12124 const Value *V = Worklist.pop_back_val();
12125 if (!Visited.insert(V).second)
12126 continue;
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);
12157 private:
12158 /// Set of (transitive) uses of this GlobalValue.
12159 SmallPtrSet<const Use *, 8> Uses;
12161 } // namespace
12163 /// ------------------------ Indirect Call Info -------------------------------
12164 namespace {
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())
12173 return;
12175 if (MD) {
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))
12203 return true;
12204 UsedAssumedInformation = !GIAA->isAtFixpoint();
12205 return false;
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))
12232 return false;
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;
12242 return 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
12249 // be UB on undef.
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)) {
12255 if (IsKnown)
12256 CachedResult = false;
12257 return false;
12261 CachedResult = true;
12262 return 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()))
12269 continue;
12270 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12271 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12272 continue;
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);
12277 continue;
12279 if (!PotentialCallees.empty()) {
12280 AddPotentialCallees();
12281 break;
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)
12319 // dead (or UB).
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);
12336 if (!CBIsVoid)
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
12344 // ```
12345 // if (ptr == value) value(args);
12346 // else ...
12347 // ```
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;
12358 continue;
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;
12368 if (IP == CB) {
12369 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12370 ThenTI->getFunction(), CBBB);
12371 IP = BranchInst::Create(CBBB, ElseBB);
12372 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12373 } else {
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));
12383 } else {
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();
12408 } else {
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.
12417 if (!CBIsVoid) {
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());
12429 else
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;
12438 return 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()) +
12445 " functions";
12448 void trackStatistics() const override {
12449 if (AllCalleesKnown) {
12450 STATS_DECLTRACK(
12451 Eliminated, CallSites,
12452 "Number of indirect call sites eliminated via specialization")
12453 } else {
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);
12463 private:
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
12472 /// time.
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;
12479 } // namespace
12481 /// ------------------------ Address Space ------------------------------------
12482 namespace {
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))
12504 return true;
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) {
12533 Changed = true;
12534 if (UseOriginalValue) {
12535 A.changeUseAfterManifest(U, *OriginalValue);
12536 return;
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)
12545 return true;
12546 auto *Inst = dyn_cast<Instruction>(U.getUser());
12547 if (!Inst)
12548 return true;
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()))
12552 return true;
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));
12560 return true;
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
12577 ? "none"
12578 : std::to_string(AssumedAddressSpace)) +
12579 ")";
12582 private:
12583 int32_t AssumedAddressSpace = NoAddressSpace;
12585 bool takeAddressSpace(int32_t AS) {
12586 if (AssumedAddressSpace == NoAddressSpace) {
12587 AssumedAddressSpace = AS;
12588 return true;
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));
12599 return V;
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);
12659 } // namespace
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); \
12708 ++NumAAs; \
12709 break;
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) \
12724 return *AA; \
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) \
12740 return *AA; \
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) \
12748 default: \
12749 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
12750 " position!"); \
12752 return *AA; \
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) \
12768 return *AA; \
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) \
12784 return *AA; \
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) \
12800 return *AA; \
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,
12836 AAGlobalValueInfo)
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