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