LLVM 20.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
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.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.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"
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"
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"
74#include <cassert>
75#include <numeric>
76#include <optional>
77#include <string>
78
79using namespace llvm;
80
81#define DEBUG_TYPE "attributor"
82
84 "attributor-manifest-internal", cl::Hidden,
85 cl::desc("Manifest Attributor internal string attributes."),
86 cl::init(false));
87
88static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
90
91template <>
93
95
97 "attributor-max-potential-values", cl::Hidden,
98 cl::desc("Maximum number of potential values to be "
99 "tracked for each position."),
101 cl::init(7));
102
104 "attributor-max-potential-values-iterations", cl::Hidden,
105 cl::desc(
106 "Maximum number of iterations we keep dismantling potential values."),
107 cl::init(64));
108
109STATISTIC(NumAAs, "Number of abstract attributes created");
110
111// Some helper macros to deal with statistics tracking.
112//
113// Usage:
114// For simple IR attribute tracking overload trackStatistics in the abstract
115// attribute and choose the right STATS_DECLTRACK_********* macro,
116// e.g.,:
117// void trackStatistics() const override {
118// STATS_DECLTRACK_ARG_ATTR(returned)
119// }
120// If there is a single "increment" side one can use the macro
121// STATS_DECLTRACK with a custom message. If there are multiple increment
122// sides, STATS_DECL and STATS_TRACK can also be used separately.
123//
124#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
125 ("Number of " #TYPE " marked '" #NAME "'")
126#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
127#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
128#define STATS_DECL(NAME, TYPE, MSG) \
129 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
130#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
131#define STATS_DECLTRACK(NAME, TYPE, MSG) \
132 { \
133 STATS_DECL(NAME, TYPE, MSG) \
134 STATS_TRACK(NAME, TYPE) \
135 }
136#define STATS_DECLTRACK_ARG_ATTR(NAME) \
137 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
138#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
139 STATS_DECLTRACK(NAME, CSArguments, \
140 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
141#define STATS_DECLTRACK_FN_ATTR(NAME) \
142 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
143#define STATS_DECLTRACK_CS_ATTR(NAME) \
144 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
145#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
146 STATS_DECLTRACK(NAME, FunctionReturn, \
147 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
148#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
149 STATS_DECLTRACK(NAME, CSReturn, \
150 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
151#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
152 STATS_DECLTRACK(NAME, Floating, \
153 ("Number of floating values known to be '" #NAME "'"))
154
155// Specialization of the operator<< for abstract attributes subclasses. This
156// disambiguates situations where multiple operators are applicable.
157namespace llvm {
158#define PIPE_OPERATOR(CLASS) \
159 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
160 return OS << static_cast<const AbstractAttribute &>(AA); \
161 }
162
200
201#undef PIPE_OPERATOR
202
203template <>
205 const DerefState &R) {
206 ChangeStatus CS0 =
207 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
208 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
209 return CS0 | CS1;
210}
211
212} // namespace llvm
213
214static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
215 bool HeaderOnly, Cycle **CPtr = nullptr) {
216 if (!CI)
217 return true;
218 auto *BB = I->getParent();
219 auto *C = CI->getCycle(BB);
220 if (!C)
221 return false;
222 if (CPtr)
223 *CPtr = C;
224 return !HeaderOnly || BB == C->getHeader();
225}
226
227/// Checks if a type could have padding bytes.
228static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
229 // There is no size information, so be conservative.
230 if (!Ty->isSized())
231 return false;
232
233 // If the alloc size is not equal to the storage size, then there are padding
234 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
235 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
236 return false;
237
238 // FIXME: This isn't the right way to check for padding in vectors with
239 // non-byte-size elements.
240 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
241 return isDenselyPacked(SeqTy->getElementType(), DL);
242
243 // For array types, check for padding within members.
244 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
245 return isDenselyPacked(SeqTy->getElementType(), DL);
246
247 if (!isa<StructType>(Ty))
248 return true;
249
250 // Check for padding within and between elements of a struct.
251 StructType *StructTy = cast<StructType>(Ty);
252 const StructLayout *Layout = DL.getStructLayout(StructTy);
253 uint64_t StartPos = 0;
254 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
255 Type *ElTy = StructTy->getElementType(I);
256 if (!isDenselyPacked(ElTy, DL))
257 return false;
258 if (StartPos != Layout->getElementOffsetInBits(I))
259 return false;
260 StartPos += DL.getTypeAllocSizeInBits(ElTy);
261 }
262
263 return true;
264}
265
266/// Get pointer operand of memory accessing instruction. If \p I is
267/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
268/// is set to false and the instruction is volatile, return nullptr.
270 bool AllowVolatile) {
271 if (!AllowVolatile && I->isVolatile())
272 return nullptr;
273
274 if (auto *LI = dyn_cast<LoadInst>(I)) {
275 return LI->getPointerOperand();
276 }
277
278 if (auto *SI = dyn_cast<StoreInst>(I)) {
279 return SI->getPointerOperand();
280 }
281
282 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
283 return CXI->getPointerOperand();
284 }
285
286 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
287 return RMWI->getPointerOperand();
288 }
289
290 return nullptr;
291}
292
293/// Helper function to create a pointer based on \p Ptr, and advanced by \p
294/// Offset bytes.
296 IRBuilder<NoFolder> &IRB) {
297 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
298 << "-bytes\n");
299
300 if (Offset)
301 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
302 Ptr->getName() + ".b" + Twine(Offset));
303 return Ptr;
304}
305
306static const Value *
308 const Value *Val, const DataLayout &DL, APInt &Offset,
309 bool GetMinOffset, bool AllowNonInbounds,
310 bool UseAssumed = false) {
311
312 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
313 const IRPosition &Pos = IRPosition::value(V);
314 // Only track dependence if we are going to use the assumed info.
315 const AAValueConstantRange *ValueConstantRangeAA =
316 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
317 UseAssumed ? DepClassTy::OPTIONAL
318 : DepClassTy::NONE);
319 if (!ValueConstantRangeAA)
320 return false;
321 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
322 : ValueConstantRangeAA->getKnown();
323 if (Range.isFullSet())
324 return false;
325
326 // We can only use the lower part of the range because the upper part can
327 // be higher than what the value can really be.
328 if (GetMinOffset)
329 ROffset = Range.getSignedMin();
330 else
331 ROffset = Range.getSignedMax();
332 return true;
333 };
334
335 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
336 /* AllowInvariant */ true,
337 AttributorAnalysis);
338}
339
340static const Value *
342 const Value *Ptr, int64_t &BytesOffset,
343 const DataLayout &DL, bool AllowNonInbounds = false) {
344 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
345 const Value *Base =
346 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
347 /* GetMinOffset */ true, AllowNonInbounds);
348
349 BytesOffset = OffsetAPInt.getSExtValue();
350 return Base;
351}
352
353/// Clamp the information known for all returned values of a function
354/// (identified by \p QueryingAA) into \p S.
355template <typename AAType, typename StateType = typename AAType::StateType,
356 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
357 bool RecurseForSelectAndPHI = true>
359 Attributor &A, const AAType &QueryingAA, StateType &S,
360 const IRPosition::CallBaseContext *CBContext = nullptr) {
361 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
362 << QueryingAA << " into " << S << "\n");
363
364 assert((QueryingAA.getIRPosition().getPositionKind() ==
366 QueryingAA.getIRPosition().getPositionKind() ==
368 "Can only clamp returned value states for a function returned or call "
369 "site returned position!");
370
371 // Use an optional state as there might not be any return values and we want
372 // to join (IntegerState::operator&) the state of all there are.
373 std::optional<StateType> T;
374
375 // Callback for each possibly returned value.
376 auto CheckReturnValue = [&](Value &RV) -> bool {
377 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
378 // If possible, use the hasAssumedIRAttr interface.
379 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
380 bool IsKnown;
381 return AA::hasAssumedIRAttr<IRAttributeKind>(
382 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
383 }
384
385 const AAType *AA =
386 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
387 if (!AA)
388 return false;
389 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
390 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
391 const StateType &AAS = AA->getState();
392 if (!T)
393 T = StateType::getBestState(AAS);
394 *T &= AAS;
395 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
396 << "\n");
397 return T->isValidState();
398 };
399
400 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
401 AA::ValueScope::Intraprocedural,
402 RecurseForSelectAndPHI))
403 S.indicatePessimisticFixpoint();
404 else if (T)
405 S ^= *T;
406}
407
408namespace {
409/// Helper class for generic deduction: return value -> returned position.
410template <typename AAType, typename BaseType,
411 typename StateType = typename BaseType::StateType,
412 bool PropagateCallBaseContext = false,
413 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
414 bool RecurseForSelectAndPHI = true>
415struct AAReturnedFromReturnedValues : public BaseType {
416 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
417 : BaseType(IRP, A) {}
418
419 /// See AbstractAttribute::updateImpl(...).
420 ChangeStatus updateImpl(Attributor &A) override {
421 StateType S(StateType::getBestState(this->getState()));
422 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
423 RecurseForSelectAndPHI>(
424 A, *this, S,
425 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
426 // TODO: If we know we visited all returned values, thus no are assumed
427 // dead, we can take the known information from the state T.
428 return clampStateAndIndicateChange<StateType>(this->getState(), S);
429 }
430};
431
432/// Clamp the information known at all call sites for a given argument
433/// (identified by \p QueryingAA) into \p S.
434template <typename AAType, typename StateType = typename AAType::StateType,
435 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
436static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
437 StateType &S) {
438 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
439 << QueryingAA << " into " << S << "\n");
440
441 assert(QueryingAA.getIRPosition().getPositionKind() ==
443 "Can only clamp call site argument states for an argument position!");
444
445 // Use an optional state as there might not be any return values and we want
446 // to join (IntegerState::operator&) the state of all there are.
447 std::optional<StateType> T;
448
449 // The argument number which is also the call site argument number.
450 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
451
452 auto CallSiteCheck = [&](AbstractCallSite ACS) {
453 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
454 // Check if a coresponding argument was found or if it is on not associated
455 // (which can happen for callback calls).
456 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
457 return false;
458
459 // If possible, use the hasAssumedIRAttr interface.
460 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
461 bool IsKnown;
462 return AA::hasAssumedIRAttr<IRAttributeKind>(
463 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
464 }
465
466 const AAType *AA =
467 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
468 if (!AA)
469 return false;
470 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
471 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
472 << "\n");
473 const StateType &AAS = AA->getState();
474 if (!T)
475 T = StateType::getBestState(AAS);
476 *T &= AAS;
477 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
478 << "\n");
479 return T->isValidState();
480 };
481
482 bool UsedAssumedInformation = false;
483 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
484 UsedAssumedInformation))
485 S.indicatePessimisticFixpoint();
486 else if (T)
487 S ^= *T;
488}
489
490/// This function is the bridge between argument position and the call base
491/// context.
492template <typename AAType, typename BaseType,
493 typename StateType = typename AAType::StateType,
494 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
495bool getArgumentStateFromCallBaseContext(Attributor &A,
496 BaseType &QueryingAttribute,
497 IRPosition &Pos, StateType &State) {
499 "Expected an 'argument' position !");
500 const CallBase *CBContext = Pos.getCallBaseContext();
501 if (!CBContext)
502 return false;
503
504 int ArgNo = Pos.getCallSiteArgNo();
505 assert(ArgNo >= 0 && "Invalid Arg No!");
506 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
507
508 // If possible, use the hasAssumedIRAttr interface.
509 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
510 bool IsKnown;
511 return AA::hasAssumedIRAttr<IRAttributeKind>(
512 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
513 }
514
515 const auto *AA =
516 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
517 if (!AA)
518 return false;
519 const StateType &CBArgumentState =
520 static_cast<const StateType &>(AA->getState());
521
522 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
523 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
524 << "\n");
525
526 // NOTE: If we want to do call site grouping it should happen here.
527 State ^= CBArgumentState;
528 return true;
529}
530
531/// Helper class for generic deduction: call site argument -> argument position.
532template <typename AAType, typename BaseType,
533 typename StateType = typename AAType::StateType,
534 bool BridgeCallBaseContext = false,
535 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
536struct AAArgumentFromCallSiteArguments : public BaseType {
537 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
538 : BaseType(IRP, A) {}
539
540 /// See AbstractAttribute::updateImpl(...).
541 ChangeStatus updateImpl(Attributor &A) override {
542 StateType S = StateType::getBestState(this->getState());
543
544 if (BridgeCallBaseContext) {
545 bool Success =
546 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
547 IRAttributeKind>(
548 A, *this, this->getIRPosition(), S);
549 if (Success)
550 return clampStateAndIndicateChange<StateType>(this->getState(), S);
551 }
552 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
553 S);
554
555 // TODO: If we know we visited all incoming values, thus no are assumed
556 // dead, we can take the known information from the state T.
557 return clampStateAndIndicateChange<StateType>(this->getState(), S);
558 }
559};
560
561/// Helper class for generic replication: function returned -> cs returned.
562template <typename AAType, typename BaseType,
563 typename StateType = typename BaseType::StateType,
564 bool IntroduceCallBaseContext = false,
565 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
566struct AACalleeToCallSite : public BaseType {
567 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
568
569 /// See AbstractAttribute::updateImpl(...).
570 ChangeStatus updateImpl(Attributor &A) override {
571 auto IRPKind = this->getIRPosition().getPositionKind();
573 IRPKind == IRPosition::IRP_CALL_SITE) &&
574 "Can only wrap function returned positions for call site "
575 "returned positions!");
576 auto &S = this->getState();
577
578 CallBase &CB = cast<CallBase>(this->getAnchorValue());
579 if (IntroduceCallBaseContext)
580 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
581 << "\n");
582
583 ChangeStatus Changed = ChangeStatus::UNCHANGED;
584 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
585 for (const Function *Callee : Callees) {
586 IRPosition FnPos =
588 ? IRPosition::returned(*Callee,
589 IntroduceCallBaseContext ? &CB : nullptr)
591 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
592 // If possible, use the hasAssumedIRAttr interface.
593 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
594 bool IsKnown;
595 if (!AA::hasAssumedIRAttr<IRAttributeKind>(
596 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
597 return false;
598 continue;
599 }
600
601 const AAType *AA =
602 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
603 if (!AA)
604 return false;
605 Changed |= clampStateAndIndicateChange(S, AA->getState());
606 if (S.isAtFixpoint())
607 return S.isValidState();
608 }
609 return true;
610 };
611 if (!A.checkForAllCallees(CalleePred, *this, CB))
612 return S.indicatePessimisticFixpoint();
613 return Changed;
614 }
615};
616
617/// Helper function to accumulate uses.
618template <class AAType, typename StateType = typename AAType::StateType>
619static void followUsesInContext(AAType &AA, Attributor &A,
621 const Instruction *CtxI,
623 StateType &State) {
624 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
625 for (unsigned u = 0; u < Uses.size(); ++u) {
626 const Use *U = Uses[u];
627 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
628 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
629 if (Found && AA.followUseInMBEC(A, U, UserI, State))
630 for (const Use &Us : UserI->uses())
631 Uses.insert(&Us);
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
649 A.getInfoCache().getMustBeExecutedContextExplorer();
650 if (!Explorer)
651 return;
652
653 // Container for (transitive) uses of the associated value.
655 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses())
656 Uses.insert(&U);
657
658 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
659
660 if (S.isAtFixpoint())
661 return;
662
664 auto Pred = [&](const Instruction *I) {
665 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
666 if (Br->isConditional())
667 BrInsts.push_back(Br);
668 return true;
669 };
670
671 // Here, accumulate conditional branch instructions in the context. We
672 // explore the child paths and collect the known states. The disjunction of
673 // those states can be merged to its own state. Let ParentState_i be a state
674 // to indicate the known information for an i-th branch instruction in the
675 // context. ChildStates are created for its successors respectively.
676 //
677 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
678 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
679 // ...
680 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
681 //
682 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
683 //
684 // FIXME: Currently, recursive branches are not handled. For example, we
685 // can't deduce that ptr must be dereferenced in below function.
686 //
687 // void f(int a, int c, int *ptr) {
688 // if(a)
689 // if (b) {
690 // *ptr = 0;
691 // } else {
692 // *ptr = 1;
693 // }
694 // else {
695 // if (b) {
696 // *ptr = 0;
697 // } else {
698 // *ptr = 1;
699 // }
700 // }
701 // }
702
703 Explorer->checkForAllContext(&CtxI, Pred);
704 for (const BranchInst *Br : BrInsts) {
705 StateType ParentState;
706
707 // The known state of the parent state is a conjunction of children's
708 // known states so it is initialized with a best state.
709 ParentState.indicateOptimisticFixpoint();
710
711 for (const BasicBlock *BB : Br->successors()) {
712 StateType ChildState;
713
714 size_t BeforeSize = Uses.size();
715 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
716
717 // Erase uses which only appear in the child.
718 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
719 It = Uses.erase(It);
720
721 ParentState &= ChildState;
722 }
723
724 // Use only known state.
725 S += ParentState;
726 }
727}
728} // namespace
729
730/// ------------------------ PointerInfo ---------------------------------------
731
732namespace llvm {
733namespace AA {
734namespace PointerInfo {
735
736struct State;
737
738} // namespace PointerInfo
739} // namespace AA
740
741/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
742template <>
745 static inline Access getEmptyKey();
746 static inline Access getTombstoneKey();
747 static unsigned getHashValue(const Access &A);
748 static bool isEqual(const Access &LHS, const Access &RHS);
749};
750
751/// Helper that allows RangeTy as a key in a DenseMap.
752template <> struct DenseMapInfo<AA::RangeTy> {
753 static inline AA::RangeTy getEmptyKey() {
754 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
755 return AA::RangeTy{EmptyKey, EmptyKey};
756 }
757
758 static inline AA::RangeTy getTombstoneKey() {
759 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
760 return AA::RangeTy{TombstoneKey, TombstoneKey};
761 }
762
763 static unsigned getHashValue(const AA::RangeTy &Range) {
767 }
768
769 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
770 return A == B;
771 }
772};
773
774/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
775/// but the instruction
776struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
779 static inline Access getEmptyKey();
780 static inline Access getTombstoneKey();
781 static unsigned getHashValue(const Access &A);
782 static bool isEqual(const Access &LHS, const Access &RHS);
783};
784
785} // namespace llvm
786
787/// A type to track pointer/struct usage and accesses for AAPointerInfo.
789 /// Return the best possible representable state.
790 static State getBestState(const State &SIS) { return State(); }
791
792 /// Return the worst possible representable state.
793 static State getWorstState(const State &SIS) {
794 State R;
795 R.indicatePessimisticFixpoint();
796 return R;
797 }
798
799 State() = default;
800 State(State &&SIS) = default;
801
802 const State &getAssumed() const { return *this; }
803
804 /// See AbstractState::isValidState().
805 bool isValidState() const override { return BS.isValidState(); }
806
807 /// See AbstractState::isAtFixpoint().
808 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
809
810 /// See AbstractState::indicateOptimisticFixpoint().
814 }
815
816 /// See AbstractState::indicatePessimisticFixpoint().
820 }
821
822 State &operator=(const State &R) {
823 if (this == &R)
824 return *this;
825 BS = R.BS;
826 AccessList = R.AccessList;
827 OffsetBins = R.OffsetBins;
828 RemoteIMap = R.RemoteIMap;
829 return *this;
830 }
831
833 if (this == &R)
834 return *this;
835 std::swap(BS, R.BS);
836 std::swap(AccessList, R.AccessList);
837 std::swap(OffsetBins, R.OffsetBins);
838 std::swap(RemoteIMap, R.RemoteIMap);
839 return *this;
840 }
841
842 /// Add a new Access to the state at offset \p Offset and with size \p Size.
843 /// The access is associated with \p I, writes \p Content (if anything), and
844 /// is of kind \p Kind. If an Access already exists for the same \p I and same
845 /// \p RemoteI, the two are combined, potentially losing information about
846 /// offset and size. The resulting access must now be moved from its original
847 /// OffsetBin to the bin for its new offset.
848 ///
849 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
851 Instruction &I, std::optional<Value *> Content,
853 Instruction *RemoteI = nullptr);
854
857 int64_t numOffsetBins() const { return OffsetBins.size(); }
858
859 const AAPointerInfo::Access &getAccess(unsigned Index) const {
860 return AccessList[Index];
861 }
862
863protected:
864 // Every memory instruction results in an Access object. We maintain a list of
865 // all Access objects that we own, along with the following maps:
866 //
867 // - OffsetBins: RangeTy -> { Access }
868 // - RemoteIMap: RemoteI x LocalI -> Access
869 //
870 // A RemoteI is any instruction that accesses memory. RemoteI is different
871 // from LocalI if and only if LocalI is a call; then RemoteI is some
872 // instruction in the callgraph starting from LocalI. Multiple paths in the
873 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
874 // are all combined into a single Access object. This may result in loss of
875 // information in RangeTy in the Access object.
879
880 /// See AAPointerInfo::forallInterferingAccesses.
883 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const {
884 if (!isValidState())
885 return false;
886
887 for (const auto &It : OffsetBins) {
888 AA::RangeTy ItRange = It.getFirst();
889 if (!Range.mayOverlap(ItRange))
890 continue;
891 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
892 for (auto Index : It.getSecond()) {
893 auto &Access = AccessList[Index];
894 if (!CB(Access, IsExact))
895 return false;
896 }
897 }
898 return true;
899 }
900
901 /// See AAPointerInfo::forallInterferingAccesses.
903 Instruction &I,
904 function_ref<bool(const AAPointerInfo::Access &, bool)> CB,
905 AA::RangeTy &Range) const {
906 if (!isValidState())
907 return false;
908
909 auto LocalList = RemoteIMap.find(&I);
910 if (LocalList == RemoteIMap.end()) {
911 return true;
912 }
913
914 for (unsigned Index : LocalList->getSecond()) {
915 for (auto &R : AccessList[Index]) {
916 Range &= R;
917 if (Range.offsetAndSizeAreUnknown())
918 break;
919 }
920 }
922 }
923
924private:
925 /// State to track fixpoint and validity.
926 BooleanState BS;
927};
928
931 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
932 Instruction *RemoteI) {
933 RemoteI = RemoteI ? RemoteI : &I;
934
935 // Check if we have an access for this instruction, if not, simply add it.
936 auto &LocalList = RemoteIMap[RemoteI];
937 bool AccExists = false;
938 unsigned AccIndex = AccessList.size();
939 for (auto Index : LocalList) {
940 auto &A = AccessList[Index];
941 if (A.getLocalInst() == &I) {
942 AccExists = true;
943 AccIndex = Index;
944 break;
945 }
946 }
947
948 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
949 LLVM_DEBUG(if (ToAdd.size()) dbgs()
950 << "[AAPointerInfo] Inserting access in new offset bins\n";);
951
952 for (auto Key : ToAdd) {
953 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
954 OffsetBins[Key].insert(AccIndex);
955 }
956 };
957
958 if (!AccExists) {
959 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
960 assert((AccessList.size() == AccIndex + 1) &&
961 "New Access should have been at AccIndex");
962 LocalList.push_back(AccIndex);
963 AddToBins(AccessList[AccIndex].getRanges());
965 }
966
967 // Combine the new Access with the existing Access, and then update the
968 // mapping in the offset bins.
969 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
970 auto &Current = AccessList[AccIndex];
971 auto Before = Current;
972 Current &= Acc;
973 if (Current == Before)
975
976 auto &ExistingRanges = Before.getRanges();
977 auto &NewRanges = Current.getRanges();
978
979 // Ranges that are in the old access but not the new access need to be removed
980 // from the offset bins.
982 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
983 LLVM_DEBUG(if (ToRemove.size()) dbgs()
984 << "[AAPointerInfo] Removing access from old offset bins\n";);
985
986 for (auto Key : ToRemove) {
987 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
988 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
989 auto &Bin = OffsetBins[Key];
990 assert(Bin.count(AccIndex) &&
991 "Expected bin to actually contain the Access.");
992 Bin.erase(AccIndex);
993 }
994
995 // Ranges that are in the new access but not the old access need to be added
996 // to the offset bins.
998 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
999 AddToBins(ToAdd);
1000 return ChangeStatus::CHANGED;
1001}
1002
1003namespace {
1004
1005/// A helper containing a list of offsets computed for a Use. Ideally this
1006/// list should be strictly ascending, but we ensure that only when we
1007/// actually translate the list of offsets to a RangeList.
1008struct OffsetInfo {
1009 using VecTy = SmallVector<int64_t>;
1010 using const_iterator = VecTy::const_iterator;
1011 VecTy Offsets;
1012
1013 const_iterator begin() const { return Offsets.begin(); }
1014 const_iterator end() const { return Offsets.end(); }
1015
1016 bool operator==(const OffsetInfo &RHS) const {
1017 return Offsets == RHS.Offsets;
1018 }
1019
1020 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); }
1021
1022 void insert(int64_t Offset) { Offsets.push_back(Offset); }
1023 bool isUnassigned() const { return Offsets.size() == 0; }
1024
1025 bool isUnknown() const {
1026 if (isUnassigned())
1027 return false;
1028 if (Offsets.size() == 1)
1029 return Offsets.front() == AA::RangeTy::Unknown;
1030 return false;
1031 }
1032
1033 void setUnknown() {
1034 Offsets.clear();
1035 Offsets.push_back(AA::RangeTy::Unknown);
1036 }
1037
1038 void addToAll(int64_t Inc) {
1039 for (auto &Offset : Offsets) {
1040 Offset += Inc;
1041 }
1042 }
1043
1044 /// Copy offsets from \p R into the current list.
1045 ///
1046 /// Ideally all lists should be strictly ascending, but we defer that to the
1047 /// actual use of the list. So we just blindly append here.
1048 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); }
1049};
1050
1051#ifndef NDEBUG
1052static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) {
1053 ListSeparator LS;
1054 OS << "[";
1055 for (auto Offset : OI) {
1056 OS << LS << Offset;
1057 }
1058 OS << "]";
1059 return OS;
1060}
1061#endif // NDEBUG
1062
1063struct AAPointerInfoImpl
1064 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1066 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1067
1068 /// See AbstractAttribute::getAsStr().
1069 const std::string getAsStr(Attributor *A) const override {
1070 return std::string("PointerInfo ") +
1071 (isValidState() ? (std::string("#") +
1072 std::to_string(OffsetBins.size()) + " bins")
1073 : "<invalid>");
1074 }
1075
1076 /// See AbstractAttribute::manifest(...).
1077 ChangeStatus manifest(Attributor &A) override {
1078 return AAPointerInfo::manifest(A);
1079 }
1080
1081 virtual const_bin_iterator begin() const override { return State::begin(); }
1082 virtual const_bin_iterator end() const override { return State::end(); }
1083 virtual int64_t numOffsetBins() const override {
1084 return State::numOffsetBins();
1085 }
1086
1087 bool forallInterferingAccesses(
1089 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1090 const override {
1091 return State::forallInterferingAccesses(Range, CB);
1092 }
1093
1094 bool forallInterferingAccesses(
1095 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1096 bool FindInterferingWrites, bool FindInterferingReads,
1097 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1099 function_ref<bool(const Access &)> SkipCB) const override {
1100 HasBeenWrittenTo = false;
1101
1102 SmallPtrSet<const Access *, 8> DominatingWrites;
1103 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1104
1105 Function &Scope = *I.getFunction();
1106 bool IsKnownNoSync;
1107 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1108 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1109 IsKnownNoSync);
1110 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1111 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1112 bool AllInSameNoSyncFn = IsAssumedNoSync;
1113 bool InstIsExecutedByInitialThreadOnly =
1114 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1115
1116 // If the function is not ending in aligned barriers, we need the stores to
1117 // be in aligned barriers. The load being in one is not sufficient since the
1118 // store might be executed by a thread that disappears after, causing the
1119 // aligned barrier guarding the load to unblock and the load to read a value
1120 // that has no CFG path to the load.
1121 bool InstIsExecutedInAlignedRegion =
1122 FindInterferingReads && ExecDomainAA &&
1123 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1124
1125 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1126 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1127
1128 InformationCache &InfoCache = A.getInfoCache();
1129 bool IsThreadLocalObj =
1130 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1131
1132 // Helper to determine if we need to consider threading, which we cannot
1133 // right now. However, if the function is (assumed) nosync or the thread
1134 // executing all instructions is the main thread only we can ignore
1135 // threading. Also, thread-local objects do not require threading reasoning.
1136 // Finally, we can ignore threading if either access is executed in an
1137 // aligned region.
1138 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1139 if (IsThreadLocalObj || AllInSameNoSyncFn)
1140 return true;
1141 const auto *FnExecDomainAA =
1142 I.getFunction() == &Scope
1143 ? ExecDomainAA
1144 : A.lookupAAFor<AAExecutionDomain>(
1145 IRPosition::function(*I.getFunction()), &QueryingAA,
1146 DepClassTy::NONE);
1147 if (!FnExecDomainAA)
1148 return false;
1149 if (InstIsExecutedInAlignedRegion ||
1150 (FindInterferingWrites &&
1151 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1153 return true;
1154 }
1155 if (InstIsExecutedByInitialThreadOnly &&
1156 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1157 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1158 return true;
1159 }
1160 return false;
1161 };
1162
1163 // Helper to determine if the access is executed by the same thread as the
1164 // given instruction, for now it is sufficient to avoid any potential
1165 // threading effects as we cannot deal with them anyway.
1166 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1167 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1168 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1169 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1170 };
1171
1172 // TODO: Use inter-procedural reachability and dominance.
1173 bool IsKnownNoRecurse;
1174 AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1175 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1176 IsKnownNoRecurse);
1177
1178 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1179 // AAExecutionDomain) such that we allow scopes other than kernels as long
1180 // as the reaching kernels are disjoint.
1181 bool InstInKernel = Scope.hasFnAttribute("kernel");
1182 bool ObjHasKernelLifetime = false;
1183 const bool UseDominanceReasoning =
1184 FindInterferingWrites && IsKnownNoRecurse;
1185 const DominatorTree *DT =
1187
1188 // Helper to check if a value has "kernel lifetime", that is it will not
1189 // outlive a GPU kernel. This is true for shared, constant, and local
1190 // globals on AMD and NVIDIA GPUs.
1191 auto HasKernelLifetime = [&](Value *V, Module &M) {
1192 if (!AA::isGPU(M))
1193 return false;
1194 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1195 case AA::GPUAddressSpace::Shared:
1196 case AA::GPUAddressSpace::Constant:
1197 case AA::GPUAddressSpace::Local:
1198 return true;
1199 default:
1200 return false;
1201 };
1202 };
1203
1204 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1205 // to determine if we should look at reachability from the callee. For
1206 // certain pointers we know the lifetime and we do not have to step into the
1207 // callee to determine reachability as the pointer would be dead in the
1208 // callee. See the conditional initialization below.
1209 std::function<bool(const Function &)> IsLiveInCalleeCB;
1210
1211 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1212 // If the alloca containing function is not recursive the alloca
1213 // must be dead in the callee.
1214 const Function *AIFn = AI->getFunction();
1215 ObjHasKernelLifetime = AIFn->hasFnAttribute("kernel");
1216 bool IsKnownNoRecurse;
1217 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1218 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1219 IsKnownNoRecurse)) {
1220 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1221 }
1222 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1223 // If the global has kernel lifetime we can stop if we reach a kernel
1224 // as it is "dead" in the (unknown) callees.
1225 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1226 if (ObjHasKernelLifetime)
1227 IsLiveInCalleeCB = [](const Function &Fn) {
1228 return !Fn.hasFnAttribute("kernel");
1229 };
1230 }
1231
1232 // Set of accesses/instructions that will overwrite the result and are
1233 // therefore blockers in the reachability traversal.
1234 AA::InstExclusionSetTy ExclusionSet;
1235
1236 auto AccessCB = [&](const Access &Acc, bool Exact) {
1237 Function *AccScope = Acc.getRemoteInst()->getFunction();
1238 bool AccInSameScope = AccScope == &Scope;
1239
1240 // If the object has kernel lifetime we can ignore accesses only reachable
1241 // by other kernels. For now we only skip accesses *in* other kernels.
1242 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1243 AccScope->hasFnAttribute("kernel"))
1244 return true;
1245
1246 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1247 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1248 ExclusionSet.insert(Acc.getRemoteInst());
1249 }
1250
1251 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1252 (!FindInterferingReads || !Acc.isRead()))
1253 return true;
1254
1255 bool Dominates = FindInterferingWrites && DT && Exact &&
1256 Acc.isMustAccess() && AccInSameScope &&
1257 DT->dominates(Acc.getRemoteInst(), &I);
1258 if (Dominates)
1259 DominatingWrites.insert(&Acc);
1260
1261 // Track if all interesting accesses are in the same `nosync` function as
1262 // the given instruction.
1263 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1264
1265 InterferingAccesses.push_back({&Acc, Exact});
1266 return true;
1267 };
1268 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1269 return false;
1270
1271 HasBeenWrittenTo = !DominatingWrites.empty();
1272
1273 // Dominating writes form a chain, find the least/lowest member.
1274 Instruction *LeastDominatingWriteInst = nullptr;
1275 for (const Access *Acc : DominatingWrites) {
1276 if (!LeastDominatingWriteInst) {
1277 LeastDominatingWriteInst = Acc->getRemoteInst();
1278 } else if (DT->dominates(LeastDominatingWriteInst,
1279 Acc->getRemoteInst())) {
1280 LeastDominatingWriteInst = Acc->getRemoteInst();
1281 }
1282 }
1283
1284 // Helper to determine if we can skip a specific write access.
1285 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1286 if (SkipCB && SkipCB(Acc))
1287 return true;
1288 if (!CanIgnoreThreading(Acc))
1289 return false;
1290
1291 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1292 // If we successfully excluded all effects we are interested in, the
1293 // access can be skipped.
1294 bool ReadChecked = !FindInterferingReads;
1295 bool WriteChecked = !FindInterferingWrites;
1296
1297 // If the instruction cannot reach the access, the former does not
1298 // interfere with what the access reads.
1299 if (!ReadChecked) {
1300 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1301 &ExclusionSet, IsLiveInCalleeCB))
1302 ReadChecked = true;
1303 }
1304 // If the instruction cannot be reach from the access, the latter does not
1305 // interfere with what the instruction reads.
1306 if (!WriteChecked) {
1307 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1308 &ExclusionSet, IsLiveInCalleeCB))
1309 WriteChecked = true;
1310 }
1311
1312 // If we still might be affected by the write of the access but there are
1313 // dominating writes in the function of the instruction
1314 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1315 // by them. This would have happend above if they are all in the same
1316 // function, so we only check the inter-procedural case. Effectively, we
1317 // want to show that there is no call after the dominting write that might
1318 // reach the access, and when it returns reach the instruction with the
1319 // updated value. To this end, we iterate all call sites, check if they
1320 // might reach the instruction without going through another access
1321 // (ExclusionSet) and at the same time might reach the access. However,
1322 // that is all part of AAInterFnReachability.
1323 if (!WriteChecked && HasBeenWrittenTo &&
1324 Acc.getRemoteInst()->getFunction() != &Scope) {
1325
1326 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1327 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1328 if (FnReachabilityAA) {
1329 // Without going backwards in the call tree, can we reach the access
1330 // from the least dominating write. Do not allow to pass the
1331 // instruction itself either.
1332 bool Inserted = ExclusionSet.insert(&I).second;
1333
1334 if (!FnReachabilityAA->instructionCanReach(
1335 A, *LeastDominatingWriteInst,
1336 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1337 WriteChecked = true;
1338
1339 if (Inserted)
1340 ExclusionSet.erase(&I);
1341 }
1342 }
1343
1344 if (ReadChecked && WriteChecked)
1345 return true;
1346
1347 if (!DT || !UseDominanceReasoning)
1348 return false;
1349 if (!DominatingWrites.count(&Acc))
1350 return false;
1351 return LeastDominatingWriteInst != Acc.getRemoteInst();
1352 };
1353
1354 // Run the user callback on all accesses we cannot skip and return if
1355 // that succeeded for all or not.
1356 for (auto &It : InterferingAccesses) {
1357 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1358 !CanSkipAccess(*It.first, It.second)) {
1359 if (!UserCB(*It.first, It.second))
1360 return false;
1361 }
1362 }
1363 return true;
1364 }
1365
1366 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1367 const AAPointerInfo &OtherAA,
1368 CallBase &CB) {
1369 using namespace AA::PointerInfo;
1370 if (!OtherAA.getState().isValidState() || !isValidState())
1371 return indicatePessimisticFixpoint();
1372
1373 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1374 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1375
1376 // Combine the accesses bin by bin.
1377 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1378 const auto &State = OtherAAImpl.getState();
1379 for (const auto &It : State) {
1380 for (auto Index : It.getSecond()) {
1381 const auto &RAcc = State.getAccess(Index);
1382 if (IsByval && !RAcc.isRead())
1383 continue;
1384 bool UsedAssumedInformation = false;
1385 AccessKind AK = RAcc.getKind();
1386 auto Content = A.translateArgumentToCallSiteContent(
1387 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1388 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1389 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1390
1391 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1392 RAcc.getType(), RAcc.getRemoteInst());
1393 }
1394 }
1395 return Changed;
1396 }
1397
1398 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1399 const OffsetInfo &Offsets, CallBase &CB) {
1400 using namespace AA::PointerInfo;
1401 if (!OtherAA.getState().isValidState() || !isValidState())
1402 return indicatePessimisticFixpoint();
1403
1404 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1405
1406 // Combine the accesses bin by bin.
1407 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1408 const auto &State = OtherAAImpl.getState();
1409 for (const auto &It : State) {
1410 for (auto Index : It.getSecond()) {
1411 const auto &RAcc = State.getAccess(Index);
1412 for (auto Offset : Offsets) {
1413 auto NewRanges = Offset == AA::RangeTy::Unknown
1415 : RAcc.getRanges();
1416 if (!NewRanges.isUnknown()) {
1417 NewRanges.addToAllOffsets(Offset);
1418 }
1419 Changed |=
1420 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(),
1421 RAcc.getType(), RAcc.getRemoteInst());
1422 }
1423 }
1424 }
1425 return Changed;
1426 }
1427
1428 /// Statistic tracking for all AAPointerInfo implementations.
1429 /// See AbstractAttribute::trackStatistics().
1430 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1431
1432 /// Dump the state into \p O.
1433 void dumpState(raw_ostream &O) {
1434 for (auto &It : OffsetBins) {
1435 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1436 << "] : " << It.getSecond().size() << "\n";
1437 for (auto AccIndex : It.getSecond()) {
1438 auto &Acc = AccessList[AccIndex];
1439 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1440 if (Acc.getLocalInst() != Acc.getRemoteInst())
1441 O << " --> " << *Acc.getRemoteInst()
1442 << "\n";
1443 if (!Acc.isWrittenValueYetUndetermined()) {
1444 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1445 O << " - c: func " << Acc.getWrittenValue()->getName()
1446 << "\n";
1447 else if (Acc.getWrittenValue())
1448 O << " - c: " << *Acc.getWrittenValue() << "\n";
1449 else
1450 O << " - c: <unknown>\n";
1451 }
1452 }
1453 }
1454 }
1455};
1456
1457struct AAPointerInfoFloating : public AAPointerInfoImpl {
1459 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1460 : AAPointerInfoImpl(IRP, A) {}
1461
1462 /// Deal with an access and signal if it was handled successfully.
1463 bool handleAccess(Attributor &A, Instruction &I,
1464 std::optional<Value *> Content, AccessKind Kind,
1465 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed,
1466 Type &Ty) {
1467 using namespace AA::PointerInfo;
1469 const DataLayout &DL = A.getDataLayout();
1470 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1471 if (!AccessSize.isScalable())
1472 Size = AccessSize.getFixedValue();
1473
1474 // Make a strictly ascending list of offsets as required by addAccess()
1475 llvm::sort(Offsets);
1476 auto *Last = llvm::unique(Offsets);
1477 Offsets.erase(Last, Offsets.end());
1478
1479 VectorType *VT = dyn_cast<VectorType>(&Ty);
1480 if (!VT || VT->getElementCount().isScalable() ||
1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1482 (*Content)->getType() != VT ||
1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1484 Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty);
1485 } else {
1486 // Handle vector stores with constant content element-wise.
1487 // TODO: We could look for the elements or create instructions
1488 // representing them.
1489 // TODO: We need to push the Content into the range abstraction
1490 // (AA::RangeTy) to allow different content values for different
1491 // ranges. ranges. Hence, support vectors storing different values.
1492 Type *ElementType = VT->getElementType();
1493 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1494 auto *ConstContent = cast<Constant>(*Content);
1495 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1496 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1497
1498 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1499 Value *ElementContent = ConstantExpr::getExtractElement(
1500 ConstContent, ConstantInt::get(Int32Ty, i));
1501
1502 // Add the element access.
1503 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1504 ElementContent, Kind, ElementType);
1505
1506 // Advance the offsets for the next element.
1507 for (auto &ElementOffset : ElementOffsets)
1508 ElementOffset += ElementSize;
1509 }
1510 }
1511 return true;
1512 };
1513
1514 /// See AbstractAttribute::updateImpl(...).
1515 ChangeStatus updateImpl(Attributor &A) override;
1516
1517 /// If the indices to \p GEP can be traced to constants, incorporate all
1518 /// of these into \p UsrOI.
1519 ///
1520 /// \return true iff \p UsrOI is updated.
1521 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1522 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1523 const GEPOperator *GEP);
1524
1525 /// See AbstractAttribute::trackStatistics()
1526 void trackStatistics() const override {
1527 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1528 }
1529};
1530
1531bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1532 const DataLayout &DL,
1533 OffsetInfo &UsrOI,
1534 const OffsetInfo &PtrOI,
1535 const GEPOperator *GEP) {
1536 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1537 MapVector<Value *, APInt> VariableOffsets;
1538 APInt ConstantOffset(BitWidth, 0);
1539
1540 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1541 "Don't look for constant values if the offset has already been "
1542 "determined to be unknown.");
1543
1544 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1545 UsrOI.setUnknown();
1546 return true;
1547 }
1548
1549 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1550 << (VariableOffsets.empty() ? "" : "not") << " constant "
1551 << *GEP << "\n");
1552
1553 auto Union = PtrOI;
1554 Union.addToAll(ConstantOffset.getSExtValue());
1555
1556 // Each VI in VariableOffsets has a set of potential constant values. Every
1557 // combination of elements, picked one each from these sets, is separately
1558 // added to the original set of offsets, thus resulting in more offsets.
1559 for (const auto &VI : VariableOffsets) {
1560 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1561 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1562 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1563 UsrOI.setUnknown();
1564 return true;
1565 }
1566
1567 // UndefValue is treated as a zero, which leaves Union as is.
1568 if (PotentialConstantsAA->undefIsContained())
1569 continue;
1570
1571 // We need at least one constant in every set to compute an actual offset.
1572 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1573 // don't actually exist. In other words, the absence of constant values
1574 // implies that the operation can be assumed dead for now.
1575 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1576 if (AssumedSet.empty())
1577 return false;
1578
1579 OffsetInfo Product;
1580 for (const auto &ConstOffset : AssumedSet) {
1581 auto CopyPerOffset = Union;
1582 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1583 VI.second.getZExtValue());
1584 Product.merge(CopyPerOffset);
1585 }
1586 Union = Product;
1587 }
1588
1589 UsrOI = std::move(Union);
1590 return true;
1591}
1592
1593ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1594 using namespace AA::PointerInfo;
1596 const DataLayout &DL = A.getDataLayout();
1597 Value &AssociatedValue = getAssociatedValue();
1598
1599 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1600 OffsetInfoMap[&AssociatedValue].insert(0);
1601
1602 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1603 // One does not simply walk into a map and assign a reference to a possibly
1604 // new location. That can cause an invalidation before the assignment
1605 // happens, like so:
1606 //
1607 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1608 //
1609 // The RHS is a reference that may be invalidated by an insertion caused by
1610 // the LHS. So we ensure that the side-effect of the LHS happens first.
1611
1612 assert(OffsetInfoMap.contains(CurPtr) &&
1613 "CurPtr does not exist in the map!");
1614
1615 auto &UsrOI = OffsetInfoMap[Usr];
1616 auto &PtrOI = OffsetInfoMap[CurPtr];
1617 assert(!PtrOI.isUnassigned() &&
1618 "Cannot pass through if the input Ptr was not visited!");
1619 UsrOI.merge(PtrOI);
1620 Follow = true;
1621 return true;
1622 };
1623
1624 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1625 Value *CurPtr = U.get();
1626 User *Usr = U.getUser();
1627 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1628 << "\n");
1629 assert(OffsetInfoMap.count(CurPtr) &&
1630 "The current pointer offset should have been seeded!");
1631 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1632 "Current pointer should be assigned");
1633
1634 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1635 if (CE->isCast())
1636 return HandlePassthroughUser(Usr, CurPtr, Follow);
1637 if (!isa<GEPOperator>(CE)) {
1638 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1639 << "\n");
1640 return false;
1641 }
1642 }
1643 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1644 // Note the order here, the Usr access might change the map, CurPtr is
1645 // already in it though.
1646 auto &UsrOI = OffsetInfoMap[Usr];
1647 auto &PtrOI = OffsetInfoMap[CurPtr];
1648
1649 if (UsrOI.isUnknown())
1650 return true;
1651
1652 if (PtrOI.isUnknown()) {
1653 Follow = true;
1654 UsrOI.setUnknown();
1655 return true;
1656 }
1657
1658 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1659 return true;
1660 }
1661 if (isa<PtrToIntInst>(Usr))
1662 return false;
1663 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr))
1664 return HandlePassthroughUser(Usr, CurPtr, Follow);
1665
1666 // For PHIs we need to take care of the recurrence explicitly as the value
1667 // might change while we iterate through a loop. For now, we give up if
1668 // the PHI is not invariant.
1669 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1670 // Note the order here, the Usr access might change the map, CurPtr is
1671 // already in it though.
1672 bool IsFirstPHIUser = !OffsetInfoMap.count(PHI);
1673 auto &UsrOI = OffsetInfoMap[PHI];
1674 auto &PtrOI = OffsetInfoMap[CurPtr];
1675
1676 // Check if the PHI operand has already an unknown offset as we can't
1677 // improve on that anymore.
1678 if (PtrOI.isUnknown()) {
1679 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1680 << *CurPtr << " in " << *PHI << "\n");
1681 Follow = !UsrOI.isUnknown();
1682 UsrOI.setUnknown();
1683 return true;
1684 }
1685
1686 // Check if the PHI is invariant (so far).
1687 if (UsrOI == PtrOI) {
1688 assert(!PtrOI.isUnassigned() &&
1689 "Cannot assign if the current Ptr was not visited!");
1690 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1691 return true;
1692 }
1693
1694 // Check if the PHI operand can be traced back to AssociatedValue.
1695 APInt Offset(
1696 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1697 0);
1698 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1699 DL, Offset, /* AllowNonInbounds */ true);
1700 auto It = OffsetInfoMap.find(CurPtrBase);
1701 if (It == OffsetInfoMap.end()) {
1702 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1703 << *CurPtr << " in " << *PHI
1704 << " (base: " << *CurPtrBase << ")\n");
1705 UsrOI.setUnknown();
1706 Follow = true;
1707 return true;
1708 }
1709
1710 // Check if the PHI operand is not dependent on the PHI itself. Every
1711 // recurrence is a cyclic net of PHIs in the data flow, and has an
1712 // equivalent Cycle in the control flow. One of those PHIs must be in the
1713 // header of that control flow Cycle. This is independent of the choice of
1714 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1715 // every Cycle header; if such a node is marked unknown, this will
1716 // eventually propagate through the whole net of PHIs in the recurrence.
1717 const auto *CI =
1718 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1719 *PHI->getFunction());
1720 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1721 auto BaseOI = It->getSecond();
1722 BaseOI.addToAll(Offset.getZExtValue());
1723 if (IsFirstPHIUser || BaseOI == UsrOI) {
1724 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1725 << " in " << *Usr << "\n");
1726 return HandlePassthroughUser(Usr, CurPtr, Follow);
1727 }
1728
1729 LLVM_DEBUG(
1730 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1731 << *CurPtr << " in " << *PHI << "\n");
1732 UsrOI.setUnknown();
1733 Follow = true;
1734 return true;
1735 }
1736
1737 UsrOI.merge(PtrOI);
1738 Follow = true;
1739 return true;
1740 }
1741
1742 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1743 // If the access is to a pointer that may or may not be the associated
1744 // value, e.g. due to a PHI, we cannot assume it will be read.
1745 AccessKind AK = AccessKind::AK_R;
1746 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1747 AK = AccessKind(AK | AccessKind::AK_MUST);
1748 else
1749 AK = AccessKind(AK | AccessKind::AK_MAY);
1750 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1751 OffsetInfoMap[CurPtr].Offsets, Changed,
1752 *LoadI->getType()))
1753 return false;
1754
1755 auto IsAssumption = [](Instruction &I) {
1756 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1757 return II->isAssumeLikeIntrinsic();
1758 return false;
1759 };
1760
1761 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1762 // Check if the assumption and the load are executed together without
1763 // memory modification.
1764 do {
1765 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1766 return true;
1767 FromI = FromI->getNextNonDebugInstruction();
1768 } while (FromI && FromI != ToI);
1769 return false;
1770 };
1771
1772 BasicBlock *BB = LoadI->getParent();
1773 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1774 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1775 return false;
1776 BasicBlock *IntrBB = IntrI.getParent();
1777 if (IntrI.getParent() == BB) {
1778 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI))
1779 return false;
1780 } else {
1781 auto PredIt = pred_begin(IntrBB);
1782 if (PredIt == pred_end(IntrBB))
1783 return false;
1784 if ((*PredIt) != BB)
1785 return false;
1786 if (++PredIt != pred_end(IntrBB))
1787 return false;
1788 for (auto *SuccBB : successors(BB)) {
1789 if (SuccBB == IntrBB)
1790 continue;
1791 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1792 continue;
1793 return false;
1794 }
1795 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(),
1796 BB->getTerminator()))
1797 return false;
1798 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1799 return false;
1800 }
1801 return true;
1802 };
1803
1804 std::pair<Value *, IntrinsicInst *> Assumption;
1805 for (const Use &LoadU : LoadI->uses()) {
1806 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1807 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1808 continue;
1809 for (const Use &CmpU : CmpI->uses()) {
1810 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1811 if (!IsValidAssume(*IntrI))
1812 continue;
1813 int Idx = CmpI->getOperandUse(0) == LoadU;
1814 Assumption = {CmpI->getOperand(Idx), IntrI};
1815 break;
1816 }
1817 }
1818 }
1819 if (Assumption.first)
1820 break;
1821 }
1822
1823 // Check if we found an assumption associated with this load.
1824 if (!Assumption.first || !Assumption.second)
1825 return true;
1826
1827 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1828 << *Assumption.second << ": " << *LoadI
1829 << " == " << *Assumption.first << "\n");
1830 bool UsedAssumedInformation = false;
1831 std::optional<Value *> Content = nullptr;
1832 if (Assumption.first)
1833 Content =
1834 A.getAssumedSimplified(*Assumption.first, *this,
1835 UsedAssumedInformation, AA::Interprocedural);
1836 return handleAccess(
1837 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1838 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1839 }
1840
1841 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1842 ArrayRef<Value *> OtherOps, AccessKind AK) {
1843 for (auto *OtherOp : OtherOps) {
1844 if (OtherOp == CurPtr) {
1845 LLVM_DEBUG(
1846 dbgs()
1847 << "[AAPointerInfo] Escaping use in store like instruction " << I
1848 << "\n");
1849 return false;
1850 }
1851 }
1852
1853 // If the access is to a pointer that may or may not be the associated
1854 // value, e.g. due to a PHI, we cannot assume it will be written.
1855 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1856 AK = AccessKind(AK | AccessKind::AK_MUST);
1857 else
1858 AK = AccessKind(AK | AccessKind::AK_MAY);
1859 bool UsedAssumedInformation = false;
1860 std::optional<Value *> Content = nullptr;
1861 if (ValueOp)
1862 Content = A.getAssumedSimplified(
1863 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1864 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1865 Changed, ValueTy);
1866 };
1867
1868 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1869 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1870 *StoreI->getValueOperand()->getType(),
1871 {StoreI->getValueOperand()}, AccessKind::AK_W);
1872 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1873 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1874 {RMWI->getValOperand()}, AccessKind::AK_RW);
1875 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1876 return HandleStoreLike(
1877 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1878 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1879 AccessKind::AK_RW);
1880
1881 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1882 if (CB->isLifetimeStartOrEnd())
1883 return true;
1884 const auto *TLI =
1885 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1886 if (getFreedOperand(CB, TLI) == U)
1887 return true;
1888 if (CB->isArgOperand(&U)) {
1889 unsigned ArgNo = CB->getArgOperandNo(&U);
1890 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1891 *this, IRPosition::callsite_argument(*CB, ArgNo),
1893 if (!CSArgPI)
1894 return false;
1895 Changed =
1896 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) |
1897 Changed;
1898 return isValidState();
1899 }
1900 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1901 << "\n");
1902 // TODO: Allow some call uses
1903 return false;
1904 }
1905
1906 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1907 return false;
1908 };
1909 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1910 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1911 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1912 if (OffsetInfoMap.count(NewU)) {
1913 LLVM_DEBUG({
1914 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1915 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1916 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1917 << "\n";
1918 }
1919 });
1920 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1921 }
1922 bool Unused;
1923 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1924 };
1925 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1926 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1927 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1928 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1929 return indicatePessimisticFixpoint();
1930 }
1931
1932 LLVM_DEBUG({
1933 dbgs() << "Accesses by bin after update:\n";
1934 dumpState(dbgs());
1935 });
1936
1937 return Changed;
1938}
1939
1940struct AAPointerInfoReturned final : AAPointerInfoImpl {
1941 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1942 : AAPointerInfoImpl(IRP, A) {}
1943
1944 /// See AbstractAttribute::updateImpl(...).
1945 ChangeStatus updateImpl(Attributor &A) override {
1946 return indicatePessimisticFixpoint();
1947 }
1948
1949 /// See AbstractAttribute::trackStatistics()
1950 void trackStatistics() const override {
1951 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1952 }
1953};
1954
1955struct AAPointerInfoArgument final : AAPointerInfoFloating {
1956 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1957 : AAPointerInfoFloating(IRP, A) {}
1958
1959 /// See AbstractAttribute::trackStatistics()
1960 void trackStatistics() const override {
1961 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1962 }
1963};
1964
1965struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1966 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1967 : AAPointerInfoFloating(IRP, A) {}
1968
1969 /// See AbstractAttribute::updateImpl(...).
1970 ChangeStatus updateImpl(Attributor &A) override {
1971 using namespace AA::PointerInfo;
1972 // We handle memory intrinsics explicitly, at least the first (=
1973 // destination) and second (=source) arguments as we know how they are
1974 // accessed.
1975 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1976 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
1977 int64_t LengthVal = AA::RangeTy::Unknown;
1978 if (Length)
1979 LengthVal = Length->getSExtValue();
1980 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
1981 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1982 if (ArgNo > 1) {
1983 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
1984 << *MI << "\n");
1985 return indicatePessimisticFixpoint();
1986 } else {
1987 auto Kind =
1988 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
1989 Changed =
1990 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
1991 }
1992 LLVM_DEBUG({
1993 dbgs() << "Accesses by bin after update:\n";
1994 dumpState(dbgs());
1995 });
1996
1997 return Changed;
1998 }
1999
2000 // TODO: Once we have call site specific value information we can provide
2001 // call site specific liveness information and then it makes
2002 // sense to specialize attributes for call sites arguments instead of
2003 // redirecting requests to the callee argument.
2004 Argument *Arg = getAssociatedArgument();
2005 if (Arg) {
2006 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2007 auto *ArgAA =
2008 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2009 if (ArgAA && ArgAA->getState().isValidState())
2010 return translateAndAddStateFromCallee(A, *ArgAA,
2011 *cast<CallBase>(getCtxI()));
2012 if (!Arg->getParent()->isDeclaration())
2013 return indicatePessimisticFixpoint();
2014 }
2015
2016 bool IsKnownNoCapture;
2017 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>(
2018 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2019 return indicatePessimisticFixpoint();
2020
2021 bool IsKnown = false;
2022 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2023 return ChangeStatus::UNCHANGED;
2024 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2025 auto Kind =
2026 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2027 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2028 nullptr);
2029 }
2030
2031 /// See AbstractAttribute::trackStatistics()
2032 void trackStatistics() const override {
2033 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2034 }
2035};
2036
2037struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2038 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2039 : AAPointerInfoFloating(IRP, A) {}
2040
2041 /// See AbstractAttribute::trackStatistics()
2042 void trackStatistics() const override {
2043 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2044 }
2045};
2046} // namespace
2047
2048/// -----------------------NoUnwind Function Attribute--------------------------
2049
2050namespace {
2051struct AANoUnwindImpl : AANoUnwind {
2052 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2053
2054 /// See AbstractAttribute::initialize(...).
2055 void initialize(Attributor &A) override {
2056 bool IsKnown;
2057 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2058 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2059 (void)IsKnown;
2060 }
2061
2062 const std::string getAsStr(Attributor *A) const override {
2063 return getAssumed() ? "nounwind" : "may-unwind";
2064 }
2065
2066 /// See AbstractAttribute::updateImpl(...).
2067 ChangeStatus updateImpl(Attributor &A) override {
2068 auto Opcodes = {
2069 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2070 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2071 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2072
2073 auto CheckForNoUnwind = [&](Instruction &I) {
2074 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2075 return true;
2076
2077 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2078 bool IsKnownNoUnwind;
2079 return AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2080 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2081 IsKnownNoUnwind);
2082 }
2083 return false;
2084 };
2085
2086 bool UsedAssumedInformation = false;
2087 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2088 UsedAssumedInformation))
2089 return indicatePessimisticFixpoint();
2090
2091 return ChangeStatus::UNCHANGED;
2092 }
2093};
2094
2095struct AANoUnwindFunction final : public AANoUnwindImpl {
2096 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2097 : AANoUnwindImpl(IRP, A) {}
2098
2099 /// See AbstractAttribute::trackStatistics()
2100 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2101};
2102
2103/// NoUnwind attribute deduction for a call sites.
2104struct AANoUnwindCallSite final
2105 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2106 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2107 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2108
2109 /// See AbstractAttribute::trackStatistics()
2110 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2111};
2112} // namespace
2113
2114/// ------------------------ NoSync Function Attribute -------------------------
2115
2116bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2117 switch (CB.getIntrinsicID()) {
2118 case Intrinsic::nvvm_barrier0:
2119 case Intrinsic::nvvm_barrier0_and:
2120 case Intrinsic::nvvm_barrier0_or:
2121 case Intrinsic::nvvm_barrier0_popc:
2122 return true;
2123 case Intrinsic::amdgcn_s_barrier:
2124 if (ExecutedAligned)
2125 return true;
2126 break;
2127 default:
2128 break;
2129 }
2130 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2131}
2132
2134 if (!I->isAtomic())
2135 return false;
2136
2137 if (auto *FI = dyn_cast<FenceInst>(I))
2138 // All legal orderings for fence are stronger than monotonic.
2139 return FI->getSyncScopeID() != SyncScope::SingleThread;
2140 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2141 // Unordered is not a legal ordering for cmpxchg.
2142 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2143 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2144 }
2145
2146 AtomicOrdering Ordering;
2147 switch (I->getOpcode()) {
2148 case Instruction::AtomicRMW:
2149 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2150 break;
2151 case Instruction::Store:
2152 Ordering = cast<StoreInst>(I)->getOrdering();
2153 break;
2154 case Instruction::Load:
2155 Ordering = cast<LoadInst>(I)->getOrdering();
2156 break;
2157 default:
2159 "New atomic operations need to be known in the attributor.");
2160 }
2161
2162 return (Ordering != AtomicOrdering::Unordered &&
2163 Ordering != AtomicOrdering::Monotonic);
2164}
2165
2166/// Return true if this intrinsic is nosync. This is only used for intrinsics
2167/// which would be nosync except that they have a volatile flag. All other
2168/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2170 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2171 return !MI->isVolatile();
2172 return false;
2173}
2174
2175namespace {
2176struct AANoSyncImpl : AANoSync {
2177 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2178
2179 /// See AbstractAttribute::initialize(...).
2180 void initialize(Attributor &A) override {
2181 bool IsKnown;
2182 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2183 DepClassTy::NONE, IsKnown));
2184 (void)IsKnown;
2185 }
2186
2187 const std::string getAsStr(Attributor *A) const override {
2188 return getAssumed() ? "nosync" : "may-sync";
2189 }
2190
2191 /// See AbstractAttribute::updateImpl(...).
2192 ChangeStatus updateImpl(Attributor &A) override;
2193};
2194
2195ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2196
2197 auto CheckRWInstForNoSync = [&](Instruction &I) {
2198 return AA::isNoSyncInst(A, I, *this);
2199 };
2200
2201 auto CheckForNoSync = [&](Instruction &I) {
2202 // At this point we handled all read/write effects and they are all
2203 // nosync, so they can be skipped.
2204 if (I.mayReadOrWriteMemory())
2205 return true;
2206
2207 bool IsKnown;
2208 CallBase &CB = cast<CallBase>(I);
2209 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
2211 IsKnown))
2212 return true;
2213
2214 // non-convergent and readnone imply nosync.
2215 return !CB.isConvergent();
2216 };
2217
2218 bool UsedAssumedInformation = false;
2219 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2220 UsedAssumedInformation) ||
2221 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2222 UsedAssumedInformation))
2223 return indicatePessimisticFixpoint();
2224
2226}
2227
2228struct AANoSyncFunction final : public AANoSyncImpl {
2229 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2230 : AANoSyncImpl(IRP, A) {}
2231
2232 /// See AbstractAttribute::trackStatistics()
2233 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2234};
2235
2236/// NoSync attribute deduction for a call sites.
2237struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2238 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2239 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2240
2241 /// See AbstractAttribute::trackStatistics()
2242 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2243};
2244} // namespace
2245
2246/// ------------------------ No-Free Attributes ----------------------------
2247
2248namespace {
2249struct AANoFreeImpl : public AANoFree {
2250 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2251
2252 /// See AbstractAttribute::initialize(...).
2253 void initialize(Attributor &A) override {
2254 bool IsKnown;
2255 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2256 DepClassTy::NONE, IsKnown));
2257 (void)IsKnown;
2258 }
2259
2260 /// See AbstractAttribute::updateImpl(...).
2261 ChangeStatus updateImpl(Attributor &A) override {
2262 auto CheckForNoFree = [&](Instruction &I) {
2263 bool IsKnown;
2264 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2265 A, this, IRPosition::callsite_function(cast<CallBase>(I)),
2266 DepClassTy::REQUIRED, IsKnown);
2267 };
2268
2269 bool UsedAssumedInformation = false;
2270 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2271 UsedAssumedInformation))
2272 return indicatePessimisticFixpoint();
2273 return ChangeStatus::UNCHANGED;
2274 }
2275
2276 /// See AbstractAttribute::getAsStr().
2277 const std::string getAsStr(Attributor *A) const override {
2278 return getAssumed() ? "nofree" : "may-free";
2279 }
2280};
2281
2282struct AANoFreeFunction final : public AANoFreeImpl {
2283 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2284 : AANoFreeImpl(IRP, A) {}
2285
2286 /// See AbstractAttribute::trackStatistics()
2287 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2288};
2289
2290/// NoFree attribute deduction for a call sites.
2291struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2292 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2293 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2294
2295 /// See AbstractAttribute::trackStatistics()
2296 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2297};
2298
2299/// NoFree attribute for floating values.
2300struct AANoFreeFloating : AANoFreeImpl {
2301 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2302 : AANoFreeImpl(IRP, A) {}
2303
2304 /// See AbstractAttribute::trackStatistics()
2305 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2306
2307 /// See Abstract Attribute::updateImpl(...).
2308 ChangeStatus updateImpl(Attributor &A) override {
2309 const IRPosition &IRP = getIRPosition();
2310
2311 bool IsKnown;
2312 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this,
2314 DepClassTy::OPTIONAL, IsKnown))
2315 return ChangeStatus::UNCHANGED;
2316
2317 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2318 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2319 Instruction *UserI = cast<Instruction>(U.getUser());
2320 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2321 if (CB->isBundleOperand(&U))
2322 return false;
2323 if (!CB->isArgOperand(&U))
2324 return true;
2325 unsigned ArgNo = CB->getArgOperandNo(&U);
2326
2327 bool IsKnown;
2328 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2329 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2330 DepClassTy::REQUIRED, IsKnown);
2331 }
2332
2333 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2334 isa<SelectInst>(UserI)) {
2335 Follow = true;
2336 return true;
2337 }
2338 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) ||
2339 isa<ReturnInst>(UserI))
2340 return true;
2341
2342 // Unknown user.
2343 return false;
2344 };
2345 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2346 return indicatePessimisticFixpoint();
2347
2348 return ChangeStatus::UNCHANGED;
2349 }
2350};
2351
2352/// NoFree attribute for a call site argument.
2353struct AANoFreeArgument final : AANoFreeFloating {
2354 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2355 : AANoFreeFloating(IRP, A) {}
2356
2357 /// See AbstractAttribute::trackStatistics()
2358 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2359};
2360
2361/// NoFree attribute for call site arguments.
2362struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2363 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2364 : AANoFreeFloating(IRP, A) {}
2365
2366 /// See AbstractAttribute::updateImpl(...).
2367 ChangeStatus updateImpl(Attributor &A) override {
2368 // TODO: Once we have call site specific value information we can provide
2369 // call site specific liveness information and then it makes
2370 // sense to specialize attributes for call sites arguments instead of
2371 // redirecting requests to the callee argument.
2372 Argument *Arg = getAssociatedArgument();
2373 if (!Arg)
2374 return indicatePessimisticFixpoint();
2375 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2376 bool IsKnown;
2377 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos,
2378 DepClassTy::REQUIRED, IsKnown))
2379 return ChangeStatus::UNCHANGED;
2380 return indicatePessimisticFixpoint();
2381 }
2382
2383 /// See AbstractAttribute::trackStatistics()
2384 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
2385};
2386
2387/// NoFree attribute for function return value.
2388struct AANoFreeReturned final : AANoFreeFloating {
2389 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2390 : AANoFreeFloating(IRP, A) {
2391 llvm_unreachable("NoFree is not applicable to function returns!");
2392 }
2393
2394 /// See AbstractAttribute::initialize(...).
2395 void initialize(Attributor &A) override {
2396 llvm_unreachable("NoFree is not applicable to function returns!");
2397 }
2398
2399 /// See AbstractAttribute::updateImpl(...).
2400 ChangeStatus updateImpl(Attributor &A) override {
2401 llvm_unreachable("NoFree is not applicable to function returns!");
2402 }
2403
2404 /// See AbstractAttribute::trackStatistics()
2405 void trackStatistics() const override {}
2406};
2407
2408/// NoFree attribute deduction for a call site return value.
2409struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2410 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2411 : AANoFreeFloating(IRP, A) {}
2412
2413 ChangeStatus manifest(Attributor &A) override {
2414 return ChangeStatus::UNCHANGED;
2415 }
2416 /// See AbstractAttribute::trackStatistics()
2417 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2418};
2419} // namespace
2420
2421/// ------------------------ NonNull Argument Attribute ------------------------
2422
2424 Attribute::AttrKind ImpliedAttributeKind,
2425 bool IgnoreSubsumingPositions) {
2427 AttrKinds.push_back(Attribute::NonNull);
2430 AttrKinds.push_back(Attribute::Dereferenceable);
2431 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2432 return true;
2433
2434 DominatorTree *DT = nullptr;
2435 AssumptionCache *AC = nullptr;
2436 InformationCache &InfoCache = A.getInfoCache();
2437 if (const Function *Fn = IRP.getAnchorScope()) {
2438 if (!Fn->isDeclaration()) {
2441 }
2442 }
2443
2445 if (IRP.getPositionKind() != IRP_RETURNED) {
2446 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2447 } else {
2448 bool UsedAssumedInformation = false;
2449 if (!A.checkForAllInstructions(
2450 [&](Instruction &I) {
2451 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2452 return true;
2453 },
2454 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2455 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2456 return false;
2457 }
2458
2459 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2460 return !isKnownNonZero(
2461 VAC.getValue(),
2462 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2463 }))
2464 return false;
2465
2466 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2467 Attribute::NonNull)});
2468 return true;
2469}
2470
2471namespace {
2472static int64_t getKnownNonNullAndDerefBytesForUse(
2473 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2474 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2475 TrackUse = false;
2476
2477 const Value *UseV = U->get();
2478 if (!UseV->getType()->isPointerTy())
2479 return 0;
2480
2481 // We need to follow common pointer manipulation uses to the accesses they
2482 // feed into. We can try to be smart to avoid looking through things we do not
2483 // like for now, e.g., non-inbounds GEPs.
2484 if (isa<CastInst>(I)) {
2485 TrackUse = true;
2486 return 0;
2487 }
2488
2489 if (isa<GetElementPtrInst>(I)) {
2490 TrackUse = true;
2491 return 0;
2492 }
2493
2494 Type *PtrTy = UseV->getType();
2495 const Function *F = I->getFunction();
2498 const DataLayout &DL = A.getInfoCache().getDL();
2499 if (const auto *CB = dyn_cast<CallBase>(I)) {
2500 if (CB->isBundleOperand(U)) {
2502 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2503 IsNonNull |=
2504 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2505 return RK.ArgValue;
2506 }
2507 return 0;
2508 }
2509
2510 if (CB->isCallee(U)) {
2511 IsNonNull |= !NullPointerIsDefined;
2512 return 0;
2513 }
2514
2515 unsigned ArgNo = CB->getArgOperandNo(U);
2516 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2517 // As long as we only use known information there is no need to track
2518 // dependences here.
2519 bool IsKnownNonNull;
2520 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP,
2521 DepClassTy::NONE, IsKnownNonNull);
2522 IsNonNull |= IsKnownNonNull;
2523 auto *DerefAA =
2524 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2525 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2526 }
2527
2528 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2529 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2530 Loc->Size.isScalable() || I->isVolatile())
2531 return 0;
2532
2533 int64_t Offset;
2534 const Value *Base =
2535 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2536 if (Base && Base == &AssociatedValue) {
2537 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2538 IsNonNull |= !NullPointerIsDefined;
2539 return std::max(int64_t(0), DerefBytes);
2540 }
2541
2542 /// Corner case when an offset is 0.
2544 /*AllowNonInbounds*/ true);
2545 if (Base && Base == &AssociatedValue && Offset == 0) {
2546 int64_t DerefBytes = Loc->Size.getValue();
2547 IsNonNull |= !NullPointerIsDefined;
2548 return std::max(int64_t(0), DerefBytes);
2549 }
2550
2551 return 0;
2552}
2553
2554struct AANonNullImpl : AANonNull {
2555 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2556
2557 /// See AbstractAttribute::initialize(...).
2558 void initialize(Attributor &A) override {
2559 Value &V = *getAssociatedValue().stripPointerCasts();
2560 if (isa<ConstantPointerNull>(V)) {
2561 indicatePessimisticFixpoint();
2562 return;
2563 }
2564
2565 if (Instruction *CtxI = getCtxI())
2566 followUsesInMBEC(*this, A, getState(), *CtxI);
2567 }
2568
2569 /// See followUsesInMBEC
2570 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2571 AANonNull::StateType &State) {
2572 bool IsNonNull = false;
2573 bool TrackUse = false;
2574 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2575 IsNonNull, TrackUse);
2576 State.setKnown(IsNonNull);
2577 return TrackUse;
2578 }
2579
2580 /// See AbstractAttribute::getAsStr().
2581 const std::string getAsStr(Attributor *A) const override {
2582 return getAssumed() ? "nonnull" : "may-null";
2583 }
2584};
2585
2586/// NonNull attribute for a floating value.
2587struct AANonNullFloating : public AANonNullImpl {
2588 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2589 : AANonNullImpl(IRP, A) {}
2590
2591 /// See AbstractAttribute::updateImpl(...).
2592 ChangeStatus updateImpl(Attributor &A) override {
2593 auto CheckIRP = [&](const IRPosition &IRP) {
2594 bool IsKnownNonNull;
2595 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2596 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2597 };
2598
2599 bool Stripped;
2600 bool UsedAssumedInformation = false;
2601 Value *AssociatedValue = &getAssociatedValue();
2603 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2604 AA::AnyScope, UsedAssumedInformation))
2605 Stripped = false;
2606 else
2607 Stripped =
2608 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2609
2610 if (!Stripped) {
2611 bool IsKnown;
2612 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2613 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2614 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2615 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2616 IsKnown);
2617 }))
2618 return ChangeStatus::UNCHANGED;
2619 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2620 if (AA::hasAssumedIRAttr<Attribute::NonNull>(
2621 A, this, IRPosition::value(*Select->getFalseValue()),
2622 DepClassTy::OPTIONAL, IsKnown) &&
2623 AA::hasAssumedIRAttr<Attribute::NonNull>(
2624 A, this, IRPosition::value(*Select->getTrueValue()),
2625 DepClassTy::OPTIONAL, IsKnown))
2626 return ChangeStatus::UNCHANGED;
2627
2628 // If we haven't stripped anything we might still be able to use a
2629 // different AA, but only if the IRP changes. Effectively when we
2630 // interpret this not as a call site value but as a floating/argument
2631 // value.
2632 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2633 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2634 return indicatePessimisticFixpoint();
2635 return ChangeStatus::UNCHANGED;
2636 }
2637
2638 for (const auto &VAC : Values)
2639 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2640 return indicatePessimisticFixpoint();
2641
2642 return ChangeStatus::UNCHANGED;
2643 }
2644
2645 /// See AbstractAttribute::trackStatistics()
2646 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2647};
2648
2649/// NonNull attribute for function return value.
2650struct AANonNullReturned final
2651 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2652 false, AANonNull::IRAttributeKind, false> {
2653 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2654 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2655 false, Attribute::NonNull, false>(IRP, A) {
2656 }
2657
2658 /// See AbstractAttribute::getAsStr().
2659 const std::string getAsStr(Attributor *A) const override {
2660 return getAssumed() ? "nonnull" : "may-null";
2661 }
2662
2663 /// See AbstractAttribute::trackStatistics()
2664 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2665};
2666
2667/// NonNull attribute for function argument.
2668struct AANonNullArgument final
2669 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2670 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2671 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2672
2673 /// See AbstractAttribute::trackStatistics()
2674 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2675};
2676
2677struct AANonNullCallSiteArgument final : AANonNullFloating {
2678 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2679 : AANonNullFloating(IRP, A) {}
2680
2681 /// See AbstractAttribute::trackStatistics()
2682 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2683};
2684
2685/// NonNull attribute for a call site return position.
2686struct AANonNullCallSiteReturned final
2687 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2688 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2689 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2690
2691 /// See AbstractAttribute::trackStatistics()
2692 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2693};
2694} // namespace
2695
2696/// ------------------------ Must-Progress Attributes --------------------------
2697namespace {
2698struct AAMustProgressImpl : public AAMustProgress {
2699 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2700 : AAMustProgress(IRP, A) {}
2701
2702 /// See AbstractAttribute::initialize(...).
2703 void initialize(Attributor &A) override {
2704 bool IsKnown;
2705 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2706 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2707 (void)IsKnown;
2708 }
2709
2710 /// See AbstractAttribute::getAsStr()
2711 const std::string getAsStr(Attributor *A) const override {
2712 return getAssumed() ? "mustprogress" : "may-not-progress";
2713 }
2714};
2715
2716struct AAMustProgressFunction final : AAMustProgressImpl {
2717 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2718 : AAMustProgressImpl(IRP, A) {}
2719
2720 /// See AbstractAttribute::updateImpl(...).
2721 ChangeStatus updateImpl(Attributor &A) override {
2722 bool IsKnown;
2723 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
2724 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2725 if (IsKnown)
2726 return indicateOptimisticFixpoint();
2727 return ChangeStatus::UNCHANGED;
2728 }
2729
2730 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2731 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2732 bool IsKnownMustProgress;
2733 return AA::hasAssumedIRAttr<Attribute::MustProgress>(
2734 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2735 /* IgnoreSubsumingPositions */ true);
2736 };
2737
2738 bool AllCallSitesKnown = true;
2739 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2740 /* RequireAllCallSites */ true,
2741 AllCallSitesKnown))
2742 return indicatePessimisticFixpoint();
2743
2744 return ChangeStatus::UNCHANGED;
2745 }
2746
2747 /// See AbstractAttribute::trackStatistics()
2748 void trackStatistics() const override {
2749 STATS_DECLTRACK_FN_ATTR(mustprogress)
2750 }
2751};
2752
2753/// MustProgress attribute deduction for a call sites.
2754struct AAMustProgressCallSite final : AAMustProgressImpl {
2755 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2756 : AAMustProgressImpl(IRP, A) {}
2757
2758 /// See AbstractAttribute::updateImpl(...).
2759 ChangeStatus updateImpl(Attributor &A) override {
2760 // TODO: Once we have call site specific value information we can provide
2761 // call site specific liveness information and then it makes
2762 // sense to specialize attributes for call sites arguments instead of
2763 // redirecting requests to the callee argument.
2764 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2765 bool IsKnownMustProgress;
2766 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>(
2767 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2768 return indicatePessimisticFixpoint();
2769 return ChangeStatus::UNCHANGED;
2770 }
2771
2772 /// See AbstractAttribute::trackStatistics()
2773 void trackStatistics() const override {
2774 STATS_DECLTRACK_CS_ATTR(mustprogress);
2775 }
2776};
2777} // namespace
2778
2779/// ------------------------ No-Recurse Attributes ----------------------------
2780
2781namespace {
2782struct AANoRecurseImpl : public AANoRecurse {
2783 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2784
2785 /// See AbstractAttribute::initialize(...).
2786 void initialize(Attributor &A) override {
2787 bool IsKnown;
2788 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2789 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2790 (void)IsKnown;
2791 }
2792
2793 /// See AbstractAttribute::getAsStr()
2794 const std::string getAsStr(Attributor *A) const override {
2795 return getAssumed() ? "norecurse" : "may-recurse";
2796 }
2797};
2798
2799struct AANoRecurseFunction final : AANoRecurseImpl {
2800 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2801 : AANoRecurseImpl(IRP, A) {}
2802
2803 /// See AbstractAttribute::updateImpl(...).
2804 ChangeStatus updateImpl(Attributor &A) override {
2805
2806 // If all live call sites are known to be no-recurse, we are as well.
2807 auto CallSitePred = [&](AbstractCallSite ACS) {
2808 bool IsKnownNoRecurse;
2809 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
2810 A, this,
2811 IRPosition::function(*ACS.getInstruction()->getFunction()),
2812 DepClassTy::NONE, IsKnownNoRecurse))
2813 return false;
2814 return IsKnownNoRecurse;
2815 };
2816 bool UsedAssumedInformation = false;
2817 if (A.checkForAllCallSites(CallSitePred, *this, true,
2818 UsedAssumedInformation)) {
2819 // If we know all call sites and all are known no-recurse, we are done.
2820 // If all known call sites, which might not be all that exist, are known
2821 // to be no-recurse, we are not done but we can continue to assume
2822 // no-recurse. If one of the call sites we have not visited will become
2823 // live, another update is triggered.
2824 if (!UsedAssumedInformation)
2825 indicateOptimisticFixpoint();
2826 return ChangeStatus::UNCHANGED;
2827 }
2828
2829 const AAInterFnReachability *EdgeReachability =
2830 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2831 DepClassTy::REQUIRED);
2832 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2833 return indicatePessimisticFixpoint();
2834 return ChangeStatus::UNCHANGED;
2835 }
2836
2837 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2838};
2839
2840/// NoRecurse attribute deduction for a call sites.
2841struct AANoRecurseCallSite final
2842 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2843 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2844 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2845
2846 /// See AbstractAttribute::trackStatistics()
2847 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2848};
2849} // namespace
2850
2851/// ------------------------ No-Convergent Attribute --------------------------
2852
2853namespace {
2854struct AANonConvergentImpl : public AANonConvergent {
2855 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2856 : AANonConvergent(IRP, A) {}
2857
2858 /// See AbstractAttribute::getAsStr()
2859 const std::string getAsStr(Attributor *A) const override {
2860 return getAssumed() ? "non-convergent" : "may-be-convergent";
2861 }
2862};
2863
2864struct AANonConvergentFunction final : AANonConvergentImpl {
2865 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2866 : AANonConvergentImpl(IRP, A) {}
2867
2868 /// See AbstractAttribute::updateImpl(...).
2869 ChangeStatus updateImpl(Attributor &A) override {
2870 // If all function calls are known to not be convergent, we are not
2871 // convergent.
2872 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2873 CallBase &CB = cast<CallBase>(Inst);
2874 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
2875 if (!Callee || Callee->isIntrinsic()) {
2876 return false;
2877 }
2878 if (Callee->isDeclaration()) {
2879 return !Callee->hasFnAttribute(Attribute::Convergent);
2880 }
2881 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2882 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2883 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2884 };
2885
2886 bool UsedAssumedInformation = false;
2887 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2888 UsedAssumedInformation)) {
2889 return indicatePessimisticFixpoint();
2890 }
2891 return ChangeStatus::UNCHANGED;
2892 }
2893
2894 ChangeStatus manifest(Attributor &A) override {
2895 if (isKnownNotConvergent() &&
2896 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2897 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2898 return ChangeStatus::CHANGED;
2899 }
2900 return ChangeStatus::UNCHANGED;
2901 }
2902
2903 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2904};
2905} // namespace
2906
2907/// -------------------- Undefined-Behavior Attributes ------------------------
2908
2909namespace {
2910struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2911 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2912 : AAUndefinedBehavior(IRP, A) {}
2913
2914 /// See AbstractAttribute::updateImpl(...).
2915 // through a pointer (i.e. also branches etc.)
2916 ChangeStatus updateImpl(Attributor &A) override {
2917 const size_t UBPrevSize = KnownUBInsts.size();
2918 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2919
2920 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2921 // Lang ref now states volatile store is not UB, let's skip them.
2922 if (I.isVolatile() && I.mayWriteToMemory())
2923 return true;
2924
2925 // Skip instructions that are already saved.
2926 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2927 return true;
2928
2929 // If we reach here, we know we have an instruction
2930 // that accesses memory through a pointer operand,
2931 // for which getPointerOperand() should give it to us.
2932 Value *PtrOp =
2933 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2934 assert(PtrOp &&
2935 "Expected pointer operand of memory accessing instruction");
2936
2937 // Either we stopped and the appropriate action was taken,
2938 // or we got back a simplified value to continue.
2939 std::optional<Value *> SimplifiedPtrOp =
2940 stopOnUndefOrAssumed(A, PtrOp, &I);
2941 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2942 return true;
2943 const Value *PtrOpVal = *SimplifiedPtrOp;
2944
2945 // A memory access through a pointer is considered UB
2946 // only if the pointer has constant null value.
2947 // TODO: Expand it to not only check constant values.
2948 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2949 AssumedNoUBInsts.insert(&I);
2950 return true;
2951 }
2952 const Type *PtrTy = PtrOpVal->getType();
2953
2954 // Because we only consider instructions inside functions,
2955 // assume that a parent function exists.
2956 const Function *F = I.getFunction();
2957
2958 // A memory access using constant null pointer is only considered UB
2959 // if null pointer is _not_ defined for the target platform.
2961 AssumedNoUBInsts.insert(&I);
2962 else
2963 KnownUBInsts.insert(&I);
2964 return true;
2965 };
2966
2967 auto InspectBrInstForUB = [&](Instruction &I) {
2968 // A conditional branch instruction is considered UB if it has `undef`
2969 // condition.
2970
2971 // Skip instructions that are already saved.
2972 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2973 return true;
2974
2975 // We know we have a branch instruction.
2976 auto *BrInst = cast<BranchInst>(&I);
2977
2978 // Unconditional branches are never considered UB.
2979 if (BrInst->isUnconditional())
2980 return true;
2981
2982 // Either we stopped and the appropriate action was taken,
2983 // or we got back a simplified value to continue.
2984 std::optional<Value *> SimplifiedCond =
2985 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2986 if (!SimplifiedCond || !*SimplifiedCond)
2987 return true;
2988 AssumedNoUBInsts.insert(&I);
2989 return true;
2990 };
2991
2992 auto InspectCallSiteForUB = [&](Instruction &I) {
2993 // Check whether a callsite always cause UB or not
2994
2995 // Skip instructions that are already saved.
2996 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2997 return true;
2998
2999 // Check nonnull and noundef argument attribute violation for each
3000 // callsite.
3001 CallBase &CB = cast<CallBase>(I);
3002 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3003 if (!Callee)
3004 return true;
3005 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3006 // If current argument is known to be simplified to null pointer and the
3007 // corresponding argument position is known to have nonnull attribute,
3008 // the argument is poison. Furthermore, if the argument is poison and
3009 // the position is known to have noundef attriubte, this callsite is
3010 // considered UB.
3011 if (idx >= Callee->arg_size())
3012 break;
3013 Value *ArgVal = CB.getArgOperand(idx);
3014 if (!ArgVal)
3015 continue;
3016 // Here, we handle three cases.
3017 // (1) Not having a value means it is dead. (we can replace the value
3018 // with undef)
3019 // (2) Simplified to undef. The argument violate noundef attriubte.
3020 // (3) Simplified to null pointer where known to be nonnull.
3021 // The argument is a poison value and violate noundef attribute.
3022 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3023 bool IsKnownNoUndef;
3024 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3025 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3026 if (!IsKnownNoUndef)
3027 continue;
3028 bool UsedAssumedInformation = false;
3029 std::optional<Value *> SimplifiedVal =
3030 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3031 UsedAssumedInformation, AA::Interprocedural);
3032 if (UsedAssumedInformation)
3033 continue;
3034 if (SimplifiedVal && !*SimplifiedVal)
3035 return true;
3036 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3037 KnownUBInsts.insert(&I);
3038 continue;
3039 }
3040 if (!ArgVal->getType()->isPointerTy() ||
3041 !isa<ConstantPointerNull>(**SimplifiedVal))
3042 continue;
3043 bool IsKnownNonNull;
3044 AA::hasAssumedIRAttr<Attribute::NonNull>(
3045 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3046 if (IsKnownNonNull)
3047 KnownUBInsts.insert(&I);
3048 }
3049 return true;
3050 };
3051
3052 auto InspectReturnInstForUB = [&](Instruction &I) {
3053 auto &RI = cast<ReturnInst>(I);
3054 // Either we stopped and the appropriate action was taken,
3055 // or we got back a simplified return value to continue.
3056 std::optional<Value *> SimplifiedRetValue =
3057 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3058 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3059 return true;
3060
3061 // Check if a return instruction always cause UB or not
3062 // Note: It is guaranteed that the returned position of the anchor
3063 // scope has noundef attribute when this is called.
3064 // We also ensure the return position is not "assumed dead"
3065 // because the returned value was then potentially simplified to
3066 // `undef` in AAReturnedValues without removing the `noundef`
3067 // attribute yet.
3068
3069 // When the returned position has noundef attriubte, UB occurs in the
3070 // following cases.
3071 // (1) Returned value is known to be undef.
3072 // (2) The value is known to be a null pointer and the returned
3073 // position has nonnull attribute (because the returned value is
3074 // poison).
3075 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3076 bool IsKnownNonNull;
3077 AA::hasAssumedIRAttr<Attribute::NonNull>(
3078 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3079 IsKnownNonNull);
3080 if (IsKnownNonNull)
3081 KnownUBInsts.insert(&I);
3082 }
3083
3084 return true;
3085 };
3086
3087 bool UsedAssumedInformation = false;
3088 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3089 {Instruction::Load, Instruction::Store,
3090 Instruction::AtomicCmpXchg,
3091 Instruction::AtomicRMW},
3092 UsedAssumedInformation,
3093 /* CheckBBLivenessOnly */ true);
3094 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3095 UsedAssumedInformation,
3096 /* CheckBBLivenessOnly */ true);
3097 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3098 UsedAssumedInformation);
3099
3100 // If the returned position of the anchor scope has noundef attriubte, check
3101 // all returned instructions.
3102 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3103 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3104 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3105 bool IsKnownNoUndef;
3106 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3107 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3108 if (IsKnownNoUndef)
3109 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3110 {Instruction::Ret}, UsedAssumedInformation,
3111 /* CheckBBLivenessOnly */ true);
3112 }
3113 }
3114
3115 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3116 UBPrevSize != KnownUBInsts.size())
3117 return ChangeStatus::CHANGED;
3118 return ChangeStatus::UNCHANGED;
3119 }
3120
3121 bool isKnownToCauseUB(Instruction *I) const override {
3122 return KnownUBInsts.count(I);
3123 }
3124
3125 bool isAssumedToCauseUB(Instruction *I) const override {
3126 // In simple words, if an instruction is not in the assumed to _not_
3127 // cause UB, then it is assumed UB (that includes those
3128 // in the KnownUBInsts set). The rest is boilerplate
3129 // is to ensure that it is one of the instructions we test
3130 // for UB.
3131
3132 switch (I->getOpcode()) {
3133 case Instruction::Load:
3134 case Instruction::Store:
3135 case Instruction::AtomicCmpXchg:
3136 case Instruction::AtomicRMW:
3137 return !AssumedNoUBInsts.count(I);
3138 case Instruction::Br: {
3139 auto *BrInst = cast<BranchInst>(I);
3140 if (BrInst->isUnconditional())
3141 return false;
3142 return !AssumedNoUBInsts.count(I);
3143 } break;
3144 default:
3145 return false;
3146 }
3147 return false;
3148 }
3149
3150 ChangeStatus manifest(Attributor &A) override {
3151 if (KnownUBInsts.empty())
3152 return ChangeStatus::UNCHANGED;
3153 for (Instruction *I : KnownUBInsts)
3154 A.changeToUnreachableAfterManifest(I);
3155 return ChangeStatus::CHANGED;
3156 }
3157
3158 /// See AbstractAttribute::getAsStr()
3159 const std::string getAsStr(Attributor *A) const override {
3160 return getAssumed() ? "undefined-behavior" : "no-ub";
3161 }
3162
3163 /// Note: The correctness of this analysis depends on the fact that the
3164 /// following 2 sets will stop changing after some point.
3165 /// "Change" here means that their size changes.
3166 /// The size of each set is monotonically increasing
3167 /// (we only add items to them) and it is upper bounded by the number of
3168 /// instructions in the processed function (we can never save more
3169 /// elements in either set than this number). Hence, at some point,
3170 /// they will stop increasing.
3171 /// Consequently, at some point, both sets will have stopped
3172 /// changing, effectively making the analysis reach a fixpoint.
3173
3174 /// Note: These 2 sets are disjoint and an instruction can be considered
3175 /// one of 3 things:
3176 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3177 /// the KnownUBInsts set.
3178 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3179 /// has a reason to assume it).
3180 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3181 /// could not find a reason to assume or prove that it can cause UB,
3182 /// hence it assumes it doesn't. We have a set for these instructions
3183 /// so that we don't reprocess them in every update.
3184 /// Note however that instructions in this set may cause UB.
3185
3186protected:
3187 /// A set of all live instructions _known_ to cause UB.
3188 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3189
3190private:
3191 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3192 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3193
3194 // Should be called on updates in which if we're processing an instruction
3195 // \p I that depends on a value \p V, one of the following has to happen:
3196 // - If the value is assumed, then stop.
3197 // - If the value is known but undef, then consider it UB.
3198 // - Otherwise, do specific processing with the simplified value.
3199 // We return std::nullopt in the first 2 cases to signify that an appropriate
3200 // action was taken and the caller should stop.
3201 // Otherwise, we return the simplified value that the caller should
3202 // use for specific processing.
3203 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3204 Instruction *I) {
3205 bool UsedAssumedInformation = false;
3206 std::optional<Value *> SimplifiedV =
3207 A.getAssumedSimplified(IRPosition::value(*V), *this,
3208 UsedAssumedInformation, AA::Interprocedural);
3209 if (!UsedAssumedInformation) {
3210 // Don't depend on assumed values.
3211 if (!SimplifiedV) {
3212 // If it is known (which we tested above) but it doesn't have a value,
3213 // then we can assume `undef` and hence the instruction is UB.
3214 KnownUBInsts.insert(I);
3215 return std::nullopt;
3216 }
3217 if (!*SimplifiedV)
3218 return nullptr;
3219 V = *SimplifiedV;
3220 }
3221 if (isa<UndefValue>(V)) {
3222 KnownUBInsts.insert(I);
3223 return std::nullopt;
3224 }
3225 return V;
3226 }
3227};
3228
3229struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3230 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3231 : AAUndefinedBehaviorImpl(IRP, A) {}
3232
3233 /// See AbstractAttribute::trackStatistics()
3234 void trackStatistics() const override {
3235 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3236 "Number of instructions known to have UB");
3237 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3238 KnownUBInsts.size();
3239 }
3240};
3241} // namespace
3242
3243/// ------------------------ Will-Return Attributes ----------------------------
3244
3245namespace {
3246// Helper function that checks whether a function has any cycle which we don't
3247// know if it is bounded or not.
3248// Loops with maximum trip count are considered bounded, any other cycle not.
3249static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3250 ScalarEvolution *SE =
3251 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3252 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3253 // If either SCEV or LoopInfo is not available for the function then we assume
3254 // any cycle to be unbounded cycle.
3255 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3256 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3257 if (!SE || !LI) {
3258 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3259 if (SCCI.hasCycle())
3260 return true;
3261 return false;
3262 }
3263
3264 // If there's irreducible control, the function may contain non-loop cycles.
3266 return true;
3267
3268 // Any loop that does not have a max trip count is considered unbounded cycle.
3269 for (auto *L : LI->getLoopsInPreorder()) {
3270 if (!SE->getSmallConstantMaxTripCount(L))
3271 return true;
3272 }
3273 return false;
3274}
3275
3276struct AAWillReturnImpl : public AAWillReturn {
3277 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3278 : AAWillReturn(IRP, A) {}
3279
3280 /// See AbstractAttribute::initialize(...).
3281 void initialize(Attributor &A) override {
3282 bool IsKnown;
3283 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>(
3284 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3285 (void)IsKnown;
3286 }
3287
3288 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3289 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3290 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3291 return false;
3292
3293 bool IsKnown;
3294 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3295 return IsKnown || !KnownOnly;
3296 return false;
3297 }
3298
3299 /// See AbstractAttribute::updateImpl(...).
3300 ChangeStatus updateImpl(Attributor &A) override {
3301 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3302 return ChangeStatus::UNCHANGED;
3303
3304 auto CheckForWillReturn = [&](Instruction &I) {
3305 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I));
3306 bool IsKnown;
3307 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
3308 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3309 if (IsKnown)
3310 return true;
3311 } else {
3312 return false;
3313 }
3314 bool IsKnownNoRecurse;
3315 return AA::hasAssumedIRAttr<Attribute::NoRecurse>(
3316 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3317 };
3318
3319 bool UsedAssumedInformation = false;
3320 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3321 UsedAssumedInformation))
3322 return indicatePessimisticFixpoint();
3323
3324 return ChangeStatus::UNCHANGED;
3325 }
3326
3327 /// See AbstractAttribute::getAsStr()
3328 const std::string getAsStr(Attributor *A) const override {
3329 return getAssumed() ? "willreturn" : "may-noreturn";
3330 }
3331};
3332
3333struct AAWillReturnFunction final : AAWillReturnImpl {
3334 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3335 : AAWillReturnImpl(IRP, A) {}
3336
3337 /// See AbstractAttribute::initialize(...).
3338 void initialize(Attributor &A) override {
3339 AAWillReturnImpl::initialize(A);
3340
3341 Function *F = getAnchorScope();
3342 assert(F && "Did expect an anchor function");
3343 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3344 indicatePessimisticFixpoint();
3345 }
3346
3347 /// See AbstractAttribute::trackStatistics()
3348 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3349};
3350
3351/// WillReturn attribute deduction for a call sites.
3352struct AAWillReturnCallSite final
3353 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3354 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3355 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3356
3357 /// See AbstractAttribute::updateImpl(...).
3358 ChangeStatus updateImpl(Attributor &A) override {
3359 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3360 return ChangeStatus::UNCHANGED;
3361
3362 return AACalleeToCallSite::updateImpl(A);
3363 }
3364
3365 /// See AbstractAttribute::trackStatistics()
3366 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3367};
3368} // namespace
3369
3370/// -------------------AAIntraFnReachability Attribute--------------------------
3371
3372/// All information associated with a reachability query. This boilerplate code
3373/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3374/// different \p ToTy values.
3375template <typename ToTy> struct ReachabilityQueryInfo {
3376 enum class Reachable {
3377 No,
3378 Yes,
3379 };
3380
3381 /// Start here,
3382 const Instruction *From = nullptr;
3383 /// reach this place,
3384 const ToTy *To = nullptr;
3385 /// without going through any of these instructions,
3386 const AA::InstExclusionSetTy *ExclusionSet = nullptr;
3387 /// and remember if it worked:
3388 Reachable Result = Reachable::No;
3389
3390 /// Precomputed hash for this RQI.
3391 unsigned Hash = 0;
3392
3393 unsigned computeHashValue() const {
3394 assert(Hash == 0 && "Computed hash twice!");
3397 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3398 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3399 InstSetDMI::getHashValue(ExclusionSet));
3400 }
3401
3403 : From(From), To(To) {}
3404
3405 /// Constructor replacement to ensure unique and stable sets are used for the
3406 /// cache.
3408 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3409 : From(&From), To(&To), ExclusionSet(ES) {
3410
3411 if (!ES || ES->empty()) {
3412 ExclusionSet = nullptr;
3413 } else if (MakeUnique) {
3414 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3415 }
3416 }
3417
3419 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {}
3420};
3421
3422namespace llvm {
3423template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3426
3429
3430 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; }
3432 return &TombstoneKey;
3433 }
3434 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3435 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3436 }
3439 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3440 return false;
3441 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3442 }
3443};
3444
3445#define DefineKeys(ToTy) \
3446 template <> \
3447 ReachabilityQueryInfo<ToTy> \
3448 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3449 ReachabilityQueryInfo<ToTy>( \
3450 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3451 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3452 template <> \
3453 ReachabilityQueryInfo<ToTy> \
3454 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3455 ReachabilityQueryInfo<ToTy>( \
3456 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3457 DenseMapInfo<const ToTy *>::getTombstoneKey());
3458
3460#undef DefineKeys
3461
3462} // namespace llvm
3463
3464namespace {
3465
3466template <typename BaseTy, typename ToTy>
3467struct CachedReachabilityAA : public BaseTy {
3468 using RQITy = ReachabilityQueryInfo<ToTy>;
3469
3470 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3471
3472 /// See AbstractAttribute::isQueryAA.
3473 bool isQueryAA() const override { return true; }
3474
3475 /// See AbstractAttribute::updateImpl(...).
3476 ChangeStatus updateImpl(Attributor &A) override {
3477 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3478 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3479 RQITy *RQI = QueryVector[u];
3480 if (RQI->Result == RQITy::Reachable::No &&
3481 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3482 Changed = ChangeStatus::CHANGED;
3483 }
3484 return Changed;
3485 }
3486
3487 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3488 bool IsTemporaryRQI) = 0;
3489
3490 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3491 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3492 RQI.Result = Result;
3493
3494 // Remove the temporary RQI from the cache.
3495 if (IsTemporaryRQI)
3496 QueryCache.erase(&RQI);
3497
3498 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3499 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3500 // this query. 2) We did not use the exclusion set, potentially because
3501 // there is none.
3502 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3503 RQITy PlainRQI(RQI.From, RQI.To);
3504 if (!QueryCache.count(&PlainRQI)) {
3505 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3506 RQIPtr->Result = Result;
3507 QueryVector.push_back(RQIPtr);
3508 QueryCache.insert(RQIPtr);
3509 }
3510 }
3511
3512 // Check if we need to insert a new permanent RQI with the exclusion set.
3513 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3514 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3515 "Did not expect empty set!");
3516 RQITy *RQIPtr = new (A.Allocator)
3517 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3518 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3519 RQIPtr->Result = Result;
3520 assert(!QueryCache.count(RQIPtr));
3521 QueryVector.push_back(RQIPtr);
3522 QueryCache.insert(RQIPtr);
3523 }
3524
3525 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3526 A.registerForUpdate(*this);
3527 return Result == RQITy::Reachable::Yes;
3528 }
3529
3530 const std::string getAsStr(Attributor *A) const override {
3531 // TODO: Return the number of reachable queries.
3532 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3533 }
3534
3535 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3536 typename RQITy::Reachable &Result) {
3537 if (!this->getState().isValidState()) {
3538 Result = RQITy::Reachable::Yes;
3539 return true;
3540 }
3541
3542 // If we have an exclusion set we might be able to find our answer by
3543 // ignoring it first.
3544 if (StackRQI.ExclusionSet) {
3545 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3546 auto It = QueryCache.find(&PlainRQI);
3547 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3548 Result = RQITy::Reachable::No;
3549 return true;
3550 }
3551 }
3552
3553 auto It = QueryCache.find(&StackRQI);
3554 if (It != QueryCache.end()) {
3555 Result = (*It)->Result;
3556 return true;
3557 }
3558
3559 // Insert a temporary for recursive queries. We will replace it with a
3560 // permanent entry later.
3561 QueryCache.insert(&StackRQI);
3562 return false;
3563 }
3564
3565private:
3566 SmallVector<RQITy *> QueryVector;
3567 DenseSet<RQITy *> QueryCache;
3568};
3569
3570struct AAIntraFnReachabilityFunction final
3571 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3572 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3573 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3574 : Base(IRP, A) {
3575 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3576 *IRP.getAssociatedFunction());
3577 }
3578
3579 bool isAssumedReachable(
3580 Attributor &A, const Instruction &From, const Instruction &To,
3581 const AA::InstExclusionSetTy *ExclusionSet) const override {
3582 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3583 if (&From == &To)
3584 return true;
3585
3586 RQITy StackRQI(A, From, To, ExclusionSet, false);
3587 typename RQITy::Reachable Result;
3588 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3589 return NonConstThis->isReachableImpl(A, StackRQI,
3590 /*IsTemporaryRQI=*/true);
3591 return Result == RQITy::Reachable::Yes;
3592 }
3593
3594 ChangeStatus updateImpl(Attributor &A) override {
3595 // We only depend on liveness. DeadEdges is all we care about, check if any
3596 // of them changed.
3597 auto *LivenessAA =
3598 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3599 if (LivenessAA &&
3600 llvm::all_of(DeadEdges,
3601 [&](const auto &DeadEdge) {
3602 return LivenessAA->isEdgeDead(DeadEdge.first,
3603 DeadEdge.second);
3604 }) &&
3605 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3606 return LivenessAA->isAssumedDead(BB);
3607 })) {
3608 return ChangeStatus::UNCHANGED;
3609 }
3610 DeadEdges.clear();
3611 DeadBlocks.clear();
3612 return Base::updateImpl(A);
3613 }
3614
3615 bool isReachableImpl(Attributor &A, RQITy &RQI,
3616 bool IsTemporaryRQI) override {
3617 const Instruction *Origin = RQI.From;
3618 bool UsedExclusionSet = false;
3619
3620 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3621 const AA::InstExclusionSetTy *ExclusionSet) {
3622 const Instruction *IP = &From;
3623 while (IP && IP != &To) {
3624 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3625 UsedExclusionSet = true;
3626 break;
3627 }
3628 IP = IP->getNextNode();
3629 }
3630 return IP == &To;
3631 };
3632
3633 const BasicBlock *FromBB = RQI.From->getParent();
3634 const BasicBlock *ToBB = RQI.To->getParent();
3635 assert(FromBB->getParent() == ToBB->getParent() &&
3636 "Not an intra-procedural query!");
3637
3638 // Check intra-block reachability, however, other reaching paths are still
3639 // possible.
3640 if (FromBB == ToBB &&
3641 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3642 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3643 IsTemporaryRQI);
3644
3645 // Check if reaching the ToBB block is sufficient or if even that would not
3646 // ensure reaching the target. In the latter case we are done.
3647 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3648 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3649 IsTemporaryRQI);
3650
3651 const Function *Fn = FromBB->getParent();
3653 if (RQI.ExclusionSet)
3654 for (auto *I : *RQI.ExclusionSet)
3655 if (I->getFunction() == Fn)
3656 ExclusionBlocks.insert(I->getParent());
3657
3658 // Check if we make it out of the FromBB block at all.
3659 if (ExclusionBlocks.count(FromBB) &&
3660 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3661 RQI.ExclusionSet))
3662 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3663
3664 auto *LivenessAA =
3665 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3666 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3667 DeadBlocks.insert(ToBB);
3668 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3669 IsTemporaryRQI);
3670 }
3671
3674 Worklist.push_back(FromBB);
3675
3677 while (!Worklist.empty()) {
3678 const BasicBlock *BB = Worklist.pop_back_val();
3679 if (!Visited.insert(BB).second)
3680 continue;
3681 for (const BasicBlock *SuccBB : successors(BB)) {
3682 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3683 LocalDeadEdges.insert({BB, SuccBB});
3684 continue;
3685 }
3686 // We checked before if we just need to reach the ToBB block.
3687 if (SuccBB == ToBB)
3688 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3689 IsTemporaryRQI);
3690 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3691 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3692 IsTemporaryRQI);
3693
3694 if (ExclusionBlocks.count(SuccBB)) {
3695 UsedExclusionSet = true;
3696 continue;
3697 }
3698 Worklist.push_back(SuccBB);
3699 }
3700 }
3701
3702 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end());
3703 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3704 IsTemporaryRQI);
3705 }
3706
3707 /// See AbstractAttribute::trackStatistics()
3708 void trackStatistics() const override {}
3709
3710private:
3711 // Set of assumed dead blocks we used in the last query. If any changes we
3712 // update the state.
3714
3715 // Set of assumed dead edges we used in the last query. If any changes we
3716 // update the state.
3718
3719 /// The dominator tree of the function to short-circuit reasoning.
3720 const DominatorTree *DT = nullptr;
3721};
3722} // namespace
3723
3724/// ------------------------ NoAlias Argument Attribute ------------------------
3725
3727 Attribute::AttrKind ImpliedAttributeKind,
3728 bool IgnoreSubsumingPositions) {
3729 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3730 "Unexpected attribute kind");
3731 Value *Val = &IRP.getAssociatedValue();
3732 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) {
3733 if (isa<AllocaInst>(Val))
3734 return true;
3735 } else {
3736 IgnoreSubsumingPositions = true;
3737 }
3738
3739 if (isa<UndefValue>(Val))
3740 return true;
3741
3742 if (isa<ConstantPointerNull>(Val) &&
3745 return true;
3746
3747 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3748 IgnoreSubsumingPositions, Attribute::NoAlias))
3749 return true;
3750
3751 return false;
3752}
3753
3754namespace {
3755struct AANoAliasImpl : AANoAlias {
3756 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3757 assert(getAssociatedType()->isPointerTy() &&
3758 "Noalias is a pointer attribute");
3759 }
3760
3761 const std::string getAsStr(Attributor *A) const override {
3762 return getAssumed() ? "noalias" : "may-alias";
3763 }
3764};
3765
3766/// NoAlias attribute for a floating value.
3767struct AANoAliasFloating final : AANoAliasImpl {
3768 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3769 : AANoAliasImpl(IRP, A) {}
3770
3771 /// See AbstractAttribute::updateImpl(...).
3772 ChangeStatus updateImpl(Attributor &A) override {
3773 // TODO: Implement this.
3774 return indicatePessimisticFixpoint();
3775 }
3776
3777 /// See AbstractAttribute::trackStatistics()
3778 void trackStatistics() const override {
3780 }
3781};
3782
3783/// NoAlias attribute for an argument.
3784struct AANoAliasArgument final
3785 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3786 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3787 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3788
3789 /// See AbstractAttribute::update(...).
3790 ChangeStatus updateImpl(Attributor &A) override {
3791 // We have to make sure no-alias on the argument does not break
3792 // synchronization when this is a callback argument, see also [1] below.
3793 // If synchronization cannot be affected, we delegate to the base updateImpl
3794 // function, otherwise we give up for now.
3795
3796 // If the function is no-sync, no-alias cannot break synchronization.
3797 bool IsKnownNoSycn;
3798 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
3799 A, this, IRPosition::function_scope(getIRPosition()),
3800 DepClassTy::OPTIONAL, IsKnownNoSycn))
3801 return Base::updateImpl(A);
3802
3803 // If the argument is read-only, no-alias cannot break synchronization.
3804 bool IsKnown;
3805 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3806 return Base::updateImpl(A);
3807
3808 // If the argument is never passed through callbacks, no-alias cannot break
3809 // synchronization.
3810 bool UsedAssumedInformation = false;
3811 if (A.checkForAllCallSites(
3812 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3813 true, UsedAssumedInformation))
3814 return Base::updateImpl(A);
3815
3816 // TODO: add no-alias but make sure it doesn't break synchronization by
3817 // introducing fake uses. See:
3818 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3819 // International Workshop on OpenMP 2018,
3820 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3821
3822 return indicatePessimisticFixpoint();
3823 }
3824
3825 /// See AbstractAttribute::trackStatistics()
3826 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3827};
3828
3829struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3830 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3831 : AANoAliasImpl(IRP, A) {}
3832
3833 /// Determine if the underlying value may alias with the call site argument
3834 /// \p OtherArgNo of \p ICS (= the underlying call site).
3835 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3836 const AAMemoryBehavior &MemBehaviorAA,
3837 const CallBase &CB, unsigned OtherArgNo) {
3838 // We do not need to worry about aliasing with the underlying IRP.
3839 if (this->getCalleeArgNo() == (int)OtherArgNo)
3840 return false;
3841
3842 // If it is not a pointer or pointer vector we do not alias.
3843 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3844 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3845 return false;
3846
3847 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3848 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3849
3850 // If the argument is readnone, there is no read-write aliasing.
3851 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3852 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3853 return false;
3854 }
3855
3856 // If the argument is readonly and the underlying value is readonly, there
3857 // is no read-write aliasing.
3858 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3859 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3860 IsReadOnly) {
3861 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3862 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3863 return false;
3864 }
3865
3866 // We have to utilize actual alias analysis queries so we need the object.
3867 if (!AAR)
3868 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3869 *getAnchorScope());
3870
3871 // Try to rule it out at the call site.
3872 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3873 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3874 "callsite arguments: "
3875 << getAssociatedValue() << " " << *ArgOp << " => "
3876 << (IsAliasing ? "" : "no-") << "alias \n");
3877
3878 return IsAliasing;
3879 }
3880
3881 bool isKnownNoAliasDueToNoAliasPreservation(
3882 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3883 // We can deduce "noalias" if the following conditions hold.
3884 // (i) Associated value is assumed to be noalias in the definition.
3885 // (ii) Associated value is assumed to be no-capture in all the uses
3886 // possibly executed before this callsite.
3887 // (iii) There is no other pointer argument which could alias with the
3888 // value.
3889
3890 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) {
3891 const auto *DerefAA = A.getAAFor<AADereferenceable>(
3892 *this, IRPosition::value(*O), DepClassTy::OPTIONAL);
3893 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0;
3894 };
3895
3896 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3897 const Function *ScopeFn = VIRP.getAnchorScope();
3898 // Check whether the value is captured in the scope using AANoCapture.
3899 // Look at CFG and check only uses possibly executed before this
3900 // callsite.
3901 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3902 Instruction *UserI = cast<Instruction>(U.getUser());
3903
3904 // If UserI is the curr instruction and there is a single potential use of
3905 // the value in UserI we allow the use.
3906 // TODO: We should inspect the operands and allow those that cannot alias
3907 // with the value.
3908 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3909 return true;
3910
3911 if (ScopeFn) {
3912 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3913 if (CB->isArgOperand(&U)) {
3914
3915 unsigned ArgNo = CB->getArgOperandNo(&U);
3916
3917 bool IsKnownNoCapture;
3918 if (AA::hasAssumedIRAttr<Attribute::NoCapture>(
3919 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3920 DepClassTy::OPTIONAL, IsKnownNoCapture))
3921 return true;
3922 }
3923 }
3924
3926 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3927 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3928 return true;
3929 }
3930
3931 // TODO: We should track the capturing uses in AANoCapture but the problem
3932 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3933 // a value in the module slice.
3934 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) {
3935 case UseCaptureKind::NO_CAPTURE:
3936 return true;
3937 case UseCaptureKind::MAY_CAPTURE:
3938 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI
3939 << "\n");
3940 return false;
3941 case UseCaptureKind::PASSTHROUGH:
3942 Follow = true;
3943 return true;
3944 }
3945 llvm_unreachable("unknown UseCaptureKind");
3946 };
3947
3948 bool IsKnownNoCapture;
3949 const AANoCapture *NoCaptureAA = nullptr;
3950 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
3951 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3952 if (!IsAssumedNoCapture &&
3953 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3954 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3955 LLVM_DEBUG(
3956 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3957 << " cannot be noalias as it is potentially captured\n");
3958 return false;
3959 }
3960 }
3961 if (NoCaptureAA)
3962 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3963
3964 // Check there is no other pointer argument which could alias with the
3965 // value passed at this call site.
3966 // TODO: AbstractCallSite
3967 const auto &CB = cast<CallBase>(getAnchorValue());
3968 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3969 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3970 return false;
3971
3972 return true;
3973 }
3974
3975 /// See AbstractAttribute::updateImpl(...).
3976 ChangeStatus updateImpl(Attributor &A) override {
3977 // If the argument is readnone we are done as there are no accesses via the
3978 // argument.
3979 auto *MemBehaviorAA =
3980 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
3981 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
3982 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3983 return ChangeStatus::UNCHANGED;
3984 }
3985
3986 bool IsKnownNoAlias;
3987 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3988 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
3989 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
3990 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
3991 << " is not no-alias at the definition\n");
3992 return indicatePessimisticFixpoint();
3993 }
3994
3995 AAResults *AAR = nullptr;
3996 if (MemBehaviorAA &&
3997 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
3998 LLVM_DEBUG(
3999 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4000 return ChangeStatus::UNCHANGED;
4001 }
4002
4003 return indicatePessimisticFixpoint();
4004 }
4005
4006 /// See AbstractAttribute::trackStatistics()
4007 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4008};
4009
4010/// NoAlias attribute for function return value.
4011struct AANoAliasReturned final : AANoAliasImpl {
4012 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4013 : AANoAliasImpl(IRP, A) {}
4014
4015 /// See AbstractAttribute::updateImpl(...).
4016 ChangeStatus updateImpl(Attributor &A) override {
4017
4018 auto CheckReturnValue = [&](Value &RV) -> bool {
4019 if (Constant *C = dyn_cast<Constant>(&RV))
4020 if (C->isNullValue() || isa<UndefValue>(C))
4021 return true;
4022
4023 /// For now, we can only deduce noalias if we have call sites.
4024 /// FIXME: add more support.
4025 if (!isa<CallBase>(&RV))
4026 return false;
4027
4028 const IRPosition &RVPos = IRPosition::value(RV);
4029 bool IsKnownNoAlias;
4030 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4031 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4032 return false;
4033
4034 bool IsKnownNoCapture;
4035 const AANoCapture *NoCaptureAA = nullptr;
4036 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>(
4037 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4038 &NoCaptureAA);
4039 return IsAssumedNoCapture ||
4040 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4041 };
4042
4043 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4044 return indicatePessimisticFixpoint();
4045
4046 return ChangeStatus::UNCHANGED;
4047 }
4048
4049 /// See AbstractAttribute::trackStatistics()
4050 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4051};
4052
4053/// NoAlias attribute deduction for a call site return value.
4054struct AANoAliasCallSiteReturned final
4055 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4056 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4057 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4058
4059 /// See AbstractAttribute::trackStatistics()
4060 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4061};
4062} // namespace
4063
4064/// -------------------AAIsDead Function Attribute-----------------------
4065
4066namespace {
4067struct AAIsDeadValueImpl : public AAIsDead {
4068 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4069
4070 /// See AAIsDead::isAssumedDead().
4071 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4072
4073 /// See AAIsDead::isKnownDead().
4074 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4075
4076 /// See AAIsDead::isAssumedDead(BasicBlock *).
4077 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4078
4079 /// See AAIsDead::isKnownDead(BasicBlock *).
4080 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4081
4082 /// See AAIsDead::isAssumedDead(Instruction *I).
4083 bool isAssumedDead(const Instruction *I) const override {
4084 return I == getCtxI() && isAssumedDead();
4085 }
4086
4087 /// See AAIsDead::isKnownDead(Instruction *I).
4088 bool isKnownDead(const Instruction *I) const override {
4089 return isAssumedDead(I) && isKnownDead();
4090 }
4091
4092 /// See AbstractAttribute::getAsStr().
4093 const std::string getAsStr(Attributor *A) const override {
4094 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4095 }
4096
4097 /// Check if all uses are assumed dead.
4098 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4099 // Callers might not check the type, void has no uses.
4100 if (V.getType()->isVoidTy() || V.use_empty())
4101 return true;
4102
4103 // If we replace a value with a constant there are no uses left afterwards.
4104 if (!isa<Constant>(V)) {
4105 if (auto *I = dyn_cast<Instruction>(&V))
4106 if (!A.isRunOn(*I->getFunction()))
4107 return false;
4108 bool UsedAssumedInformation = false;
4109 std::optional<Constant *> C =
4110 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4111 if (!C || *C)
4112 return true;
4113 }
4114
4115 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4116 // Explicitly set the dependence class to required because we want a long
4117 // chain of N dependent instructions to be considered live as soon as one is
4118 // without going through N update cycles. This is not required for
4119 // correctness.
4120 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4121 DepClassTy::REQUIRED,
4122 /* IgnoreDroppableUses */ false);
4123 }
4124
4125 /// Determine if \p I is assumed to be side-effect free.
4126 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4128 return true;
4129
4130 auto *CB = dyn_cast<CallBase>(I);
4131 if (!CB || isa<IntrinsicInst>(CB))
4132 return false;
4133
4134 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4135
4136 bool IsKnownNoUnwind;
4137 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4138 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4139 return false;
4140
4141 bool IsKnown;
4142 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4143 }
4144};
4145
4146struct AAIsDeadFloating : public AAIsDeadValueImpl {
4147 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4148 : AAIsDeadValueImpl(IRP, A) {}
4149
4150 /// See AbstractAttribute::initialize(...).
4151 void initialize(Attributor &A) override {
4152 AAIsDeadValueImpl::initialize(A);
4153
4154 if (isa<UndefValue>(getAssociatedValue())) {
4155 indicatePessimisticFixpoint();
4156 return;
4157 }
4158
4159 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4160 if (!isAssumedSideEffectFree(A, I)) {
4161 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I))
4162 indicatePessimisticFixpoint();
4163 else
4164 removeAssumedBits(HAS_NO_EFFECT);
4165 }
4166 }
4167
4168 bool isDeadFence(Attributor &A, FenceInst &FI) {
4169 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4170 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4171 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4172 return false;
4173 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4174 return true;
4175 }
4176
4177 bool isDeadStore(Attributor &A, StoreInst &SI,
4178 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4179 // Lang ref now states volatile store is not UB/dead, let's skip them.
4180 if (SI.isVolatile())
4181 return false;
4182
4183 // If we are collecting assumes to be deleted we are in the manifest stage.
4184 // It's problematic to collect the potential copies again now so we use the
4185 // cached ones.
4186 bool UsedAssumedInformation = false;
4187 if (!AssumeOnlyInst) {
4188 PotentialCopies.clear();
4189 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4190 UsedAssumedInformation)) {
4191 LLVM_DEBUG(
4192 dbgs()
4193 << "[AAIsDead] Could not determine potential copies of store!\n");
4194 return false;
4195 }
4196 }
4197 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4198 << " potential copies.\n");
4199
4200 InformationCache &InfoCache = A.getInfoCache();
4201 return llvm::all_of(PotentialCopies, [&](Value *V) {
4202 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4203 UsedAssumedInformation))
4204 return true;
4205 if (auto *LI = dyn_cast<LoadInst>(V)) {
4206 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4207 auto &UserI = cast<Instruction>(*U.getUser());
4208 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4209 if (AssumeOnlyInst)
4210 AssumeOnlyInst->insert(&UserI);
4211 return true;
4212 }
4213 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4214 })) {
4215 return true;
4216 }
4217 }
4218 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4219 << " is assumed live!\n");
4220 return false;
4221 });
4222 }
4223
4224 /// See AbstractAttribute::getAsStr().
4225 const std::string getAsStr(Attributor *A) const override {
4226 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4227 if (isa_and_nonnull<StoreInst>(I))
4228 if (isValidState())
4229 return "assumed-dead-store";
4230 if (isa_and_nonnull<FenceInst>(I))
4231 if (isValidState())
4232 return "assumed-dead-fence";
4233 return AAIsDeadValueImpl::getAsStr(A);
4234 }
4235
4236 /// See AbstractAttribute::updateImpl(...).
4237 ChangeStatus updateImpl(Attributor &A) override {
4238 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4239 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4240 if (!isDeadStore(A, *SI))
4241 return indicatePessimisticFixpoint();
4242 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4243 if (!isDeadFence(A, *FI))
4244 return indicatePessimisticFixpoint();
4245 } else {
4246 if (!isAssumedSideEffectFree(A, I))
4247 return indicatePessimisticFixpoint();
4248 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4249 return indicatePessimisticFixpoint();
4250 }
4252 }
4253
4254 bool isRemovableStore() const override {
4255 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4256 }
4257
4258 /// See AbstractAttribute::manifest(...).
4259 ChangeStatus manifest(Attributor &A) override {
4260 Value &V = getAssociatedValue();
4261 if (auto *I = dyn_cast<Instruction>(&V)) {
4262 // If we get here we basically know the users are all dead. We check if
4263 // isAssumedSideEffectFree returns true here again because it might not be
4264 // the case and only the users are dead but the instruction (=call) is
4265 // still needed.
4266 if (auto *SI = dyn_cast<StoreInst>(I)) {
4267 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4268 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4269 (void)IsDead;
4270 assert(IsDead && "Store was assumed to be dead!");
4271 A.deleteAfterManifest(*I);
4272 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4273 Instruction *AOI = AssumeOnlyInst[i];
4274 for (auto *Usr : AOI->users())
4275 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4276 A.deleteAfterManifest(*AOI);
4277 }
4278 return ChangeStatus::CHANGED;
4279 }
4280 if (auto *FI = dyn_cast<FenceInst>(I)) {
4281 assert(isDeadFence(A, *FI));
4282 A.deleteAfterManifest(*FI);
4283 return ChangeStatus::CHANGED;
4284 }
4285 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4286 A.deleteAfterManifest(*I);
4287 return ChangeStatus::CHANGED;
4288 }
4289 }
4291 }
4292
4293 /// See AbstractAttribute::trackStatistics()
4294 void trackStatistics() const override {
4296 }
4297
4298private:
4299 // The potential copies of a dead store, used for deletion during manifest.
4300 SmallSetVector<Value *, 4> PotentialCopies;
4301};
4302
4303struct AAIsDeadArgument : public AAIsDeadFloating {
4304 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4305 : AAIsDeadFloating(IRP, A) {}
4306
4307 /// See AbstractAttribute::manifest(...).
4308 ChangeStatus manifest(Attributor &A) override {
4309 Argument &Arg = *getAssociatedArgument();
4310 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4311 if (A.registerFunctionSignatureRewrite(
4312 Arg, /* ReplacementTypes */ {},
4315 return ChangeStatus::CHANGED;
4316 }
4317 return ChangeStatus::UNCHANGED;
4318 }
4319
4320 /// See AbstractAttribute::trackStatistics()
4321 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4322};
4323
4324struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4325 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4326 : AAIsDeadValueImpl(IRP, A) {}
4327
4328 /// See AbstractAttribute::initialize(...).
4329 void initialize(Attributor &A) override {
4330 AAIsDeadValueImpl::initialize(A);
4331 if (isa<UndefValue>(getAssociatedValue()))
4332 indicatePessimisticFixpoint();
4333 }
4334
4335 /// See AbstractAttribute::updateImpl(...).
4336 ChangeStatus updateImpl(Attributor &A) override {
4337 // TODO: Once we have call site specific value information we can provide
4338 // call site specific liveness information and then it makes
4339 // sense to specialize attributes for call sites arguments instead of
4340 // redirecting requests to the callee argument.
4341 Argument *Arg = getAssociatedArgument();
4342 if (!Arg)
4343 return indicatePessimisticFixpoint();
4344 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4345 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4346 if (!ArgAA)
4347 return indicatePessimisticFixpoint();
4348 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4349 }
4350
4351 /// See AbstractAttribute::manifest(...).
4352 ChangeStatus manifest(Attributor &A) override {
4353 CallBase &CB = cast<CallBase>(getAnchorValue());
4354 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4355 assert(!isa<UndefValue>(U.get()) &&
4356 "Expected undef values to be filtered out!");
4357 UndefValue &UV = *UndefValue::get(U->getType());
4358 if (A.changeUseAfterManifest(U, UV))
4359 return ChangeStatus::CHANGED;
4360 return ChangeStatus::UNCHANGED;
4361 }
4362
4363 /// See AbstractAttribute::trackStatistics()
4364 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4365};
4366
4367struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4368 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4369 : AAIsDeadFloating(IRP, A) {}
4370
4371 /// See AAIsDead::isAssumedDead().
4372 bool isAssumedDead() const override {
4373 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4374 }
4375
4376 /// See AbstractAttribute::initialize(...).
4377 void initialize(Attributor &A) override {
4378 AAIsDeadFloating::initialize(A);
4379 if (isa<UndefValue>(getAssociatedValue())) {
4380 indicatePessimisticFixpoint();
4381 return;
4382 }
4383
4384 // We track this separately as a secondary state.
4385 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4386 }
4387
4388 /// See AbstractAttribute::updateImpl(...).
4389 ChangeStatus updateImpl(Attributor &A) override {
4390 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4391 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4392 IsAssumedSideEffectFree = false;
4393 Changed = ChangeStatus::CHANGED;
4394 }
4395 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4396 return indicatePessimisticFixpoint();
4397 return Changed;
4398 }
4399
4400 /// See AbstractAttribute::trackStatistics()
4401 void trackStatistics() const override {
4402 if (IsAssumedSideEffectFree)
4404 else
4405 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4406 }
4407
4408 /// See AbstractAttribute::getAsStr().
4409 const std::string getAsStr(Attributor *A) const override {
4410 return isAssumedDead()
4411 ? "assumed-dead"
4412 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4413 }
4414
4415private:
4416 bool IsAssumedSideEffectFree = true;
4417};
4418
4419struct AAIsDeadReturned : public AAIsDeadValueImpl {
4420 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4421 : AAIsDeadValueImpl(IRP, A) {}
4422
4423 /// See AbstractAttribute::updateImpl(...).
4424 ChangeStatus updateImpl(Attributor &A) override {
4425
4426 bool UsedAssumedInformation = false;
4427 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4428 {Instruction::Ret}, UsedAssumedInformation);
4429
4430 auto PredForCallSite = [&](AbstractCallSite ACS) {
4431 if (ACS.isCallbackCall() || !ACS.getInstruction())
4432 return false;
4433 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4434 };
4435
4436 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4437 UsedAssumedInformation))
4438 return indicatePessimisticFixpoint();
4439
4440 return ChangeStatus::UNCHANGED;
4441 }
4442
4443 /// See AbstractAttribute::manifest(...).
4444 ChangeStatus manifest(Attributor &A) override {
4445 // TODO: Rewrite the signature to return void?
4446 bool AnyChange = false;
4447 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4448 auto RetInstPred = [&](Instruction &I) {
4449 ReturnInst &RI = cast<ReturnInst>(I);
4450 if (!isa<UndefValue>(RI.getReturnValue()))
4451 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4452 return true;
4453 };
4454 bool UsedAssumedInformation = false;
4455 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4456 UsedAssumedInformation);
4457 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4458 }
4459
4460 /// See AbstractAttribute::trackStatistics()
4461 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4462};
4463
4464struct AAIsDeadFunction : public AAIsDead {
4465 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4466
4467 /// See AbstractAttribute::initialize(...).
4468 void initialize(Attributor &A) override {
4469 Function *F = getAnchorScope();
4470 assert(F && "Did expect an anchor function");
4471 if (!isAssumedDeadInternalFunction(A)) {
4472 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4473 assumeLive(A, F->getEntryBlock());
4474 }
4475 }
4476
4477 bool isAssumedDeadInternalFunction(Attributor &A) {
4478 if (!getAnchorScope()->hasLocalLinkage())
4479 return false;
4480 bool UsedAssumedInformation = false;
4481 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4482 true, UsedAssumedInformation);
4483 }
4484
4485 /// See AbstractAttribute::getAsStr().
4486 const std::string getAsStr(Attributor *A) const override {
4487 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4488 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4489 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4490 std::to_string(KnownDeadEnds.size()) + "]";
4491 }
4492
4493 /// See AbstractAttribute::manifest(...).
4494 ChangeStatus manifest(Attributor &A) override {
4495 assert(getState().isValidState() &&
4496 "Attempted to manifest an invalid state!");
4497
4498 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4499 Function &F = *getAnchorScope();
4500
4501 if (AssumedLiveBlocks.empty()) {
4502 A.deleteAfterManifest(F);
4503 return ChangeStatus::CHANGED;
4504 }
4505
4506 // Flag to determine if we can change an invoke to a call assuming the
4507 // callee is nounwind. This is not possible if the personality of the
4508 // function allows to catch asynchronous exceptions.
4509 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4510
4511 KnownDeadEnds.set_union(ToBeExploredFrom);
4512 for (const Instruction *DeadEndI : KnownDeadEnds) {
4513 auto *CB = dyn_cast<CallBase>(DeadEndI);
4514 if (!CB)
4515 continue;
4516 bool IsKnownNoReturn;
4517 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>(
4518 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4519 IsKnownNoReturn);
4520 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4521 continue;
4522
4523 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4524 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4525 else
4526 A.changeToUnreachableAfterManifest(
4527 const_cast<Instruction *>(DeadEndI->getNextNode()));
4528 HasChanged = ChangeStatus::CHANGED;
4529 }
4530
4531 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4532 for (BasicBlock &BB : F)
4533 if (!AssumedLiveBlocks.count(&BB)) {
4534 A.deleteAfterManifest(BB);
4536 HasChanged = ChangeStatus::CHANGED;
4537 }
4538
4539 return HasChanged;
4540 }
4541
4542 /// See AbstractAttribute::updateImpl(...).
4543 ChangeStatus updateImpl(Attributor &A) override;
4544
4545 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4546 assert(From->getParent() == getAnchorScope() &&
4547 To->getParent() == getAnchorScope() &&
4548 "Used AAIsDead of the wrong function");
4549 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4550 }
4551
4552 /// See AbstractAttribute::trackStatistics()
4553 void trackStatistics() const override {}
4554
4555 /// Returns true if the function is assumed dead.
4556 bool isAssumedDead() const override { return false; }
4557
4558 /// See AAIsDead::isKnownDead().
4559 bool isKnownDead() const override { return false; }
4560
4561 /// See AAIsDead::isAssumedDead(BasicBlock *).
4562 bool isAssumedDead(const BasicBlock *BB) const override {
4563 assert(BB->getParent() == getAnchorScope() &&
4564 "BB must be in the same anchor scope function.");
4565
4566 if (!getAssumed())
4567 return false;
4568 return !AssumedLiveBlocks.count(BB);
4569 }
4570
4571 /// See AAIsDead::isKnownDead(BasicBlock *).
4572 bool isKnownDead(const BasicBlock *BB) const override {
4573 return getKnown() && isAssumedDead(BB);
4574 }
4575
4576 /// See AAIsDead::isAssumed(Instruction *I).
4577 bool isAssumedDead(const Instruction *I) const override {
4578 assert(I->getParent()->getParent() == getAnchorScope() &&
4579 "Instruction must be in the same anchor scope function.");
4580
4581 if (!getAssumed())
4582 return false;
4583
4584 // If it is not in AssumedLiveBlocks then it for sure dead.
4585 // Otherwise, it can still be after noreturn call in a live block.
4586 if (!AssumedLiveBlocks.count(I->getParent()))
4587 return true;
4588
4589 // If it is not after a liveness barrier it is live.
4590 const Instruction *PrevI = I->getPrevNode();
4591 while (PrevI) {
4592 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4593 return true;
4594 PrevI = PrevI->getPrevNode();
4595 }
4596 return false;
4597 }
4598
4599 /// See AAIsDead::isKnownDead(Instruction *I).
4600 bool isKnownDead(const Instruction *I) const override {
4601 return getKnown() && isAssumedDead(I);
4602 }
4603
4604 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4605 /// that internal function called from \p BB should now be looked at.
4606 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4607 if (!AssumedLiveBlocks.insert(&BB).second)
4608 return false;
4609
4610 // We assume that all of BB is (probably) live now and if there are calls to
4611 // internal functions we will assume that those are now live as well. This
4612 // is a performance optimization for blocks with calls to a lot of internal
4613 // functions. It can however cause dead functions to be treated as live.
4614 for (const Instruction &I : BB)
4615 if (const auto *CB = dyn_cast<CallBase>(&I))
4616 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand()))
4617 if (F->hasLocalLinkage())
4618 A.markLiveInternalFunction(*F);
4619 return true;
4620 }
4621
4622 /// Collection of instructions that need to be explored again, e.g., we
4623 /// did assume they do not transfer control to (one of their) successors.
4625
4626 /// Collection of instructions that are known to not transfer control.
4628
4629 /// Collection of all assumed live edges
4631
4632 /// Collection of all assumed live BasicBlocks.
4633 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4634};
4635
4636static bool
4637identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4639 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4640 const IRPosition &IPos = IRPosition::callsite_function(CB);
4641
4642 bool IsKnownNoReturn;
4643 if (AA::hasAssumedIRAttr<Attribute::NoReturn>(
4644 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4645 return !IsKnownNoReturn;
4646 if (CB.isTerminator())
4647 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4648 else
4649 AliveSuccessors.push_back(CB.getNextNode());
4650 return false;
4651}
4652
4653static bool
4654identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4656 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4657 bool UsedAssumedInformation =
4658 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4659
4660 // First, determine if we can change an invoke to a call assuming the
4661 // callee is nounwind. This is not possible if the personality of the
4662 // function allows to catch asynchronous exceptions.
4663 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4664 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4665 } else {
4667
4668 bool IsKnownNoUnwind;
4669 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4670 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4671 UsedAssumedInformation |= !IsKnownNoUnwind;
4672 } else {
4673 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4674 }
4675 }
4676 return UsedAssumedInformation;
4677}
4678
4679static bool
4680identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4682 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4683 bool UsedAssumedInformation = false;
4684 if (BI.getNumSuccessors() == 1) {
4685 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4686 } else {
4687 std::optional<Constant *> C =
4688 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4689 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4690 // No value yet, assume both edges are dead.
4691 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4692 const BasicBlock *SuccBB =
4693 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4694 AliveSuccessors.push_back(&SuccBB->front());
4695 } else {
4696 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4697 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4698 UsedAssumedInformation = false;
4699 }
4700 }
4701 return UsedAssumedInformation;
4702}
4703
4704static bool
4705identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4707 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4708 bool UsedAssumedInformation = false;
4710 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4711 Values, AA::AnyScope,
4712 UsedAssumedInformation)) {
4713 // Something went wrong, assume all successors are live.
4714 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4715 AliveSuccessors.push_back(&SuccBB->front());
4716 return false;
4717 }
4718
4719 if (Values.empty() ||
4720 (Values.size() == 1 &&
4721 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4722 // No valid value yet, assume all edges are dead.
4723 return UsedAssumedInformation;
4724 }
4725
4726 Type &Ty = *SI.getCondition()->getType();
4728 auto CheckForConstantInt = [&](Value *V) {
4729 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4730 Constants.insert(CI);
4731 return true;
4732 }
4733 return false;
4734 };
4735
4736 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4737 return CheckForConstantInt(VAC.getValue());
4738 })) {
4739 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4740 AliveSuccessors.push_back(&SuccBB->front());
4741 return UsedAssumedInformation;
4742 }
4743
4744 unsigned MatchedCases = 0;
4745 for (const auto &CaseIt : SI.cases()) {
4746 if (Constants.count(CaseIt.getCaseValue())) {
4747 ++MatchedCases;
4748 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4749 }
4750 }
4751
4752 // If all potential values have been matched, we will not visit the default
4753 // case.
4754 if (MatchedCases < Constants.size())
4755 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4756 return UsedAssumedInformation;
4757}
4758
4759ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4761
4762 if (AssumedLiveBlocks.empty()) {
4763 if (isAssumedDeadInternalFunction(A))
4765
4766 Function *F = getAnchorScope();
4767 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4768 assumeLive(A, F->getEntryBlock());
4769 Change = ChangeStatus::CHANGED;
4770 }
4771
4772 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4773 << getAnchorScope()->size() << "] BBs and "
4774 << ToBeExploredFrom.size() << " exploration points and "
4775 << KnownDeadEnds.size() << " known dead ends\n");
4776
4777 // Copy and clear the list of instructions we need to explore from. It is
4778 // refilled with instructions the next update has to look at.
4779 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4780 ToBeExploredFrom.end());
4781 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4782
4784 while (!Worklist.empty()) {
4785 const Instruction *I = Worklist.pop_back_val();
4786 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4787
4788 // Fast forward for uninteresting instructions. We could look for UB here
4789 // though.
4790 while (!I->isTerminator() && !isa<CallBase>(I))
4791 I = I->getNextNode();
4792
4793 AliveSuccessors.clear();
4794
4795 bool UsedAssumedInformation = false;
4796 switch (I->getOpcode()) {
4797 // TODO: look for (assumed) UB to backwards propagate "deadness".
4798 default:
4799 assert(I->isTerminator() &&
4800 "Expected non-terminators to be handled already!");
4801 for (const BasicBlock *SuccBB : successors(I->getParent()))
4802 AliveSuccessors.push_back(&SuccBB->front());
4803 break;
4804 case Instruction::Call:
4805 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4806 *this, AliveSuccessors);
4807 break;
4808 case Instruction::Invoke:
4809 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4810 *this, AliveSuccessors);
4811 break;
4812 case Instruction::Br:
4813 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4814 *this, AliveSuccessors);
4815 break;
4816 case Instruction::Switch:
4817 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4818 *this, AliveSuccessors);
4819 break;
4820 }
4821
4822 if (UsedAssumedInformation) {
4823 NewToBeExploredFrom.insert(I);
4824 } else if (AliveSuccessors.empty() ||
4825 (I->isTerminator() &&
4826 AliveSuccessors.size() < I->getNumSuccessors())) {
4827 if (KnownDeadEnds.insert(I))
4828 Change = ChangeStatus::CHANGED;
4829 }
4830
4831 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4832 << AliveSuccessors.size() << " UsedAssumedInformation: "
4833 << UsedAssumedInformation << "\n");
4834
4835 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4836 if (!I->isTerminator()) {
4837 assert(AliveSuccessors.size() == 1 &&
4838 "Non-terminator expected to have a single successor!");
4839 Worklist.push_back(AliveSuccessor);
4840 } else {
4841 // record the assumed live edge
4842 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4843 if (AssumedLiveEdges.insert(Edge).second)
4844 Change = ChangeStatus::CHANGED;
4845 if (assumeLive(A, *AliveSuccessor->getParent()))
4846 Worklist.push_back(AliveSuccessor);
4847 }
4848 }
4849 }
4850
4851 // Check if the content of ToBeExploredFrom changed, ignore the order.
4852 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4853 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4854 return !ToBeExploredFrom.count(I);
4855 })) {
4856 Change = ChangeStatus::CHANGED;
4857 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4858 }
4859
4860 // If we know everything is live there is no need to query for liveness.
4861 // Instead, indicating a pessimistic fixpoint will cause the state to be
4862 // "invalid" and all queries to be answered conservatively without lookups.
4863 // To be in this state we have to (1) finished the exploration and (3) not
4864 // discovered any non-trivial dead end and (2) not ruled unreachable code
4865 // dead.
4866 if (ToBeExploredFrom.empty() &&
4867 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4868 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4869 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4870 }))
4871 return indicatePessimisticFixpoint();
4872 return Change;
4873}
4874
4875/// Liveness information for a call sites.
4876struct AAIsDeadCallSite final : AAIsDeadFunction {
4877 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4878 : AAIsDeadFunction(IRP, A) {}
4879
4880 /// See AbstractAttribute::initialize(...).
4881 void initialize(Attributor &A) override {
4882 // TODO: Once we have call site specific value information we can provide
4883 // call site specific liveness information and then it makes
4884 // sense to specialize attributes for call sites instead of
4885 // redirecting requests to the callee.
4886 llvm_unreachable("Abstract attributes for liveness are not "
4887 "supported for call sites yet!");
4888 }
4889
4890 /// See AbstractAttribute::updateImpl(...).
4891 ChangeStatus updateImpl(Attributor &A) override {
4892 return indicatePessimisticFixpoint();
4893 }
4894
4895 /// See AbstractAttribute::trackStatistics()
4896 void trackStatistics() const override {}
4897};
4898} // namespace
4899
4900/// -------------------- Dereferenceable Argument Attribute --------------------
4901
4902namespace {
4903struct AADereferenceableImpl : AADereferenceable {
4904 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4905 : AADereferenceable(IRP, A) {}
4906 using StateType = DerefState;
4907
4908 /// See AbstractAttribute::initialize(...).
4909 void initialize(Attributor &A) override {
4910 Value &V = *getAssociatedValue().stripPointerCasts();
4912 A.getAttrs(getIRPosition(),
4913 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4914 Attrs, /* IgnoreSubsumingPositions */ false);
4915 for (const Attribute &Attr : Attrs)
4916 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4917
4918 // Ensure we initialize the non-null AA (if necessary).
4919 bool IsKnownNonNull;
4920 AA::hasAssumedIRAttr<Attribute::NonNull>(
4921 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4922
4923 bool CanBeNull, CanBeFreed;
4924 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4925 A.getDataLayout(), CanBeNull, CanBeFreed));
4926
4927 if (Instruction *CtxI = getCtxI())
4928 followUsesInMBEC(*this, A, getState(), *CtxI);
4929 }
4930
4931 /// See AbstractAttribute::getState()
4932 /// {
4933 StateType &getState() override { return *this; }
4934 const StateType &getState() const override { return *this; }
4935 /// }
4936
4937 /// Helper function for collecting accessed bytes in must-be-executed-context
4938 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4939 DerefState &State) {
4940 const Value *UseV = U->get();
4941 if (!UseV->getType()->isPointerTy())
4942 return;
4943
4944 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4945 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4946 return;
4947
4948 int64_t Offset;
4950 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4951 if (Base && Base == &getAssociatedValue())
4952 State.addAccessedBytes(Offset, Loc->Size.getValue());
4953 }
4954
4955 /// See followUsesInMBEC
4956 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4958 bool IsNonNull = false;
4959 bool TrackUse = false;
4960 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4961 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4962 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4963 << " for instruction " << *I << "\n");
4964
4965 addAccessedBytesForUse(A, U, I, State);
4966 State.takeKnownDerefBytesMaximum(DerefBytes);
4967 return TrackUse;
4968 }
4969
4970 /// See AbstractAttribute::manifest(...).
4971 ChangeStatus manifest(Attributor &A) override {
4972