LLVM 23.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"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
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) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static inline Access getEmptyKey();
749 static inline Access getTombstoneKey();
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
756 static inline AA::RangeTy getEmptyKey() {
757 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
758 return AA::RangeTy{EmptyKey, EmptyKey};
759 }
760
761 static inline AA::RangeTy getTombstoneKey() {
762 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
763 return AA::RangeTy{TombstoneKey, TombstoneKey};
764 }
765
771
772 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
773 return A == B;
774 }
775};
776
777/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
778/// but the instruction
779struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
782 static inline Access getEmptyKey();
783 static inline Access getTombstoneKey();
784 static unsigned getHashValue(const Access &A);
785 static bool isEqual(const Access &LHS, const Access &RHS);
786};
787
788} // namespace llvm
789
790/// A type to track pointer/struct usage and accesses for AAPointerInfo.
792 /// Return the best possible representable state.
793 static State getBestState(const State &SIS) { return State(); }
794
795 /// Return the worst possible representable state.
796 static State getWorstState(const State &SIS) {
797 State R;
798 R.indicatePessimisticFixpoint();
799 return R;
800 }
801
802 State() = default;
803 State(State &&SIS) = default;
804
805 const State &getAssumed() const { return *this; }
806
807 /// See AbstractState::isValidState().
808 bool isValidState() const override { return BS.isValidState(); }
809
810 /// See AbstractState::isAtFixpoint().
811 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
812
813 /// See AbstractState::indicateOptimisticFixpoint().
815 BS.indicateOptimisticFixpoint();
817 }
818
819 /// See AbstractState::indicatePessimisticFixpoint().
821 BS.indicatePessimisticFixpoint();
823 }
824
825 State &operator=(const State &R) {
826 if (this == &R)
827 return *this;
828 BS = R.BS;
829 AccessList = R.AccessList;
830 OffsetBins = R.OffsetBins;
831 RemoteIMap = R.RemoteIMap;
832 ReturnedOffsets = R.ReturnedOffsets;
833 return *this;
834 }
835
837 if (this == &R)
838 return *this;
839 std::swap(BS, R.BS);
840 std::swap(AccessList, R.AccessList);
841 std::swap(OffsetBins, R.OffsetBins);
842 std::swap(RemoteIMap, R.RemoteIMap);
843 std::swap(ReturnedOffsets, R.ReturnedOffsets);
844 return *this;
845 }
846
847 /// Add a new Access to the state at offset \p Offset and with size \p Size.
848 /// The access is associated with \p I, writes \p Content (if anything), and
849 /// is of kind \p Kind. If an Access already exists for the same \p I and same
850 /// \p RemoteI, the two are combined, potentially losing information about
851 /// offset and size. The resulting access must now be moved from its original
852 /// OffsetBin to the bin for its new offset.
853 ///
854 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
856 Instruction &I, std::optional<Value *> Content,
858 Instruction *RemoteI = nullptr);
859
862 int64_t numOffsetBins() const { return OffsetBins.size(); }
863
864 const AAPointerInfo::Access &getAccess(unsigned Index) const {
865 return AccessList[Index];
866 }
867
868protected:
869 // Every memory instruction results in an Access object. We maintain a list of
870 // all Access objects that we own, along with the following maps:
871 //
872 // - OffsetBins: RangeTy -> { Access }
873 // - RemoteIMap: RemoteI x LocalI -> Access
874 //
875 // A RemoteI is any instruction that accesses memory. RemoteI is different
876 // from LocalI if and only if LocalI is a call; then RemoteI is some
877 // instruction in the callgraph starting from LocalI. Multiple paths in the
878 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
879 // are all combined into a single Access object. This may result in loss of
880 // information in RangeTy in the Access object.
884
885 /// Flag to determine if the underlying pointer is reaching a return statement
886 /// in the associated function or not. Returns in other functions cause
887 /// invalidation.
889
890 /// See AAPointerInfo::forallInterferingAccesses.
891 template <typename F>
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 for (const auto &It : OffsetBins) {
897 AA::RangeTy ItRange = It.getFirst();
898 if (!Range.mayOverlap(ItRange))
899 continue;
900 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
901 for (auto Index : It.getSecond()) {
902 auto &Access = AccessList[Index];
903 if (!CB(Access, IsExact))
904 return false;
905 }
906 }
907 return true;
908 }
909
910 /// See AAPointerInfo::forallInterferingAccesses.
911 template <typename F>
913 AA::RangeTy &Range) const {
914 if (!isValidState() || !ReturnedOffsets.isUnassigned())
915 return false;
916
917 auto LocalList = RemoteIMap.find(&I);
918 if (LocalList == RemoteIMap.end()) {
919 return true;
920 }
921
922 for (unsigned Index : LocalList->getSecond()) {
923 for (auto &R : AccessList[Index]) {
924 Range &= R;
925 if (Range.offsetAndSizeAreUnknown())
926 break;
927 }
928 }
930 }
931
932private:
933 /// State to track fixpoint and validity.
934 BooleanState BS;
935};
936
939 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
940 Instruction *RemoteI) {
941 RemoteI = RemoteI ? RemoteI : &I;
942
943 // Check if we have an access for this instruction, if not, simply add it.
944 auto &LocalList = RemoteIMap[RemoteI];
945 bool AccExists = false;
946 unsigned AccIndex = AccessList.size();
947 for (auto Index : LocalList) {
948 auto &A = AccessList[Index];
949 if (A.getLocalInst() == &I) {
950 AccExists = true;
951 AccIndex = Index;
952 break;
953 }
954 }
955
956 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
957 LLVM_DEBUG(if (ToAdd.size()) dbgs()
958 << "[AAPointerInfo] Inserting access in new offset bins\n";);
959
960 for (auto Key : ToAdd) {
961 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
962 OffsetBins[Key].insert(AccIndex);
963 }
964 };
965
966 if (!AccExists) {
967 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
968 assert((AccessList.size() == AccIndex + 1) &&
969 "New Access should have been at AccIndex");
970 LocalList.push_back(AccIndex);
971 AddToBins(AccessList[AccIndex].getRanges());
973 }
974
975 // Combine the new Access with the existing Access, and then update the
976 // mapping in the offset bins.
977 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
978 auto &Current = AccessList[AccIndex];
979 auto Before = Current;
980 Current &= Acc;
981 if (Current == Before)
983
984 auto &ExistingRanges = Before.getRanges();
985 auto &NewRanges = Current.getRanges();
986
987 // Ranges that are in the old access but not the new access need to be removed
988 // from the offset bins.
990 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
991 LLVM_DEBUG(if (ToRemove.size()) dbgs()
992 << "[AAPointerInfo] Removing access from old offset bins\n";);
993
994 for (auto Key : ToRemove) {
995 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
996 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
997 auto &Bin = OffsetBins[Key];
998 assert(Bin.count(AccIndex) &&
999 "Expected bin to actually contain the Access.");
1000 Bin.erase(AccIndex);
1001 }
1002
1003 // Ranges that are in the new access but not the old access need to be added
1004 // to the offset bins.
1006 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1007 AddToBins(ToAdd);
1008 return ChangeStatus::CHANGED;
1009}
1010
1011namespace {
1012
1013#ifndef NDEBUG
1015 const AAPointerInfo::OffsetInfo &OI) {
1016 OS << llvm::interleaved_array(OI);
1017 return OS;
1018}
1019#endif // NDEBUG
1020
1021struct AAPointerInfoImpl
1022 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1024 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1025
1026 /// See AbstractAttribute::getAsStr().
1027 const std::string getAsStr(Attributor *A) const override {
1028 return std::string("PointerInfo ") +
1029 (isValidState() ? (std::string("#") +
1030 std::to_string(OffsetBins.size()) + " bins")
1031 : "<invalid>") +
1032 (reachesReturn()
1033 ? (" (returned:" +
1034 join(map_range(ReturnedOffsets,
1035 [](int64_t O) { return std::to_string(O); }),
1036 ", ") +
1037 ")")
1038 : "");
1039 }
1040
1041 /// See AbstractAttribute::manifest(...).
1042 ChangeStatus manifest(Attributor &A) override {
1043 return AAPointerInfo::manifest(A);
1044 }
1045
1046 const_bin_iterator begin() const override { return State::begin(); }
1047 const_bin_iterator end() const override { return State::end(); }
1048 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1049 bool reachesReturn() const override {
1050 return !ReturnedOffsets.isUnassigned();
1051 }
1052 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1053 if (ReturnedOffsets.isUnknown()) {
1054 OI.setUnknown();
1055 return;
1056 }
1057
1058 OffsetInfo MergedOI;
1059 for (auto Offset : ReturnedOffsets) {
1060 OffsetInfo TmpOI = OI;
1061 TmpOI.addToAll(Offset);
1062 MergedOI.merge(TmpOI);
1063 }
1064 OI = std::move(MergedOI);
1065 }
1066
1067 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1068 if (ReturnedOffsets.isUnknown())
1069 return ChangeStatus::UNCHANGED;
1070 if (ReachedReturnedOffsets.isUnknown()) {
1071 ReturnedOffsets.setUnknown();
1072 return ChangeStatus::CHANGED;
1073 }
1074 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1075 return ChangeStatus::CHANGED;
1076 return ChangeStatus::UNCHANGED;
1077 }
1078
1079 bool forallInterferingAccesses(
1080 AA::RangeTy Range,
1081 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1082 const override {
1083 return State::forallInterferingAccesses(Range, CB);
1084 }
1085
1086 bool forallInterferingAccesses(
1087 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1088 bool FindInterferingWrites, bool FindInterferingReads,
1089 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1090 AA::RangeTy &Range,
1091 function_ref<bool(const Access &)> SkipCB) const override {
1092 HasBeenWrittenTo = false;
1093
1094 SmallPtrSet<const Access *, 8> DominatingWrites;
1095 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1096
1097 Function &Scope = *I.getFunction();
1098 bool IsKnownNoSync;
1099 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1100 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1101 IsKnownNoSync);
1102 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1103 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1104 bool AllInSameNoSyncFn = IsAssumedNoSync;
1105 bool InstIsExecutedByInitialThreadOnly =
1106 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1107
1108 // If the function is not ending in aligned barriers, we need the stores to
1109 // be in aligned barriers. The load being in one is not sufficient since the
1110 // store might be executed by a thread that disappears after, causing the
1111 // aligned barrier guarding the load to unblock and the load to read a value
1112 // that has no CFG path to the load.
1113 bool InstIsExecutedInAlignedRegion =
1114 FindInterferingReads && ExecDomainAA &&
1115 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1116
1117 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1118 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1119
1120 InformationCache &InfoCache = A.getInfoCache();
1121 bool IsThreadLocalObj =
1122 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1123
1124 // Helper to determine if we need to consider threading, which we cannot
1125 // right now. However, if the function is (assumed) nosync or the thread
1126 // executing all instructions is the main thread only we can ignore
1127 // threading. Also, thread-local objects do not require threading reasoning.
1128 // Finally, we can ignore threading if either access is executed in an
1129 // aligned region.
1130 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1131 if (IsThreadLocalObj || AllInSameNoSyncFn)
1132 return true;
1133 const auto *FnExecDomainAA =
1134 I.getFunction() == &Scope
1135 ? ExecDomainAA
1136 : A.lookupAAFor<AAExecutionDomain>(
1137 IRPosition::function(*I.getFunction()), &QueryingAA,
1138 DepClassTy::NONE);
1139 if (!FnExecDomainAA)
1140 return false;
1141 if (InstIsExecutedInAlignedRegion ||
1142 (FindInterferingWrites &&
1143 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1144 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1145 return true;
1146 }
1147 if (InstIsExecutedByInitialThreadOnly &&
1148 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1149 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1150 return true;
1151 }
1152 return false;
1153 };
1154
1155 // Helper to determine if the access is executed by the same thread as the
1156 // given instruction, for now it is sufficient to avoid any potential
1157 // threading effects as we cannot deal with them anyway.
1158 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1159 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1160 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1161 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1162 };
1163
1164 // TODO: Use inter-procedural reachability and dominance.
1165 bool IsKnownNoRecurse;
1167 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1168 IsKnownNoRecurse);
1169
1170 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1171 // AAExecutionDomain) such that we allow scopes other than kernels as long
1172 // as the reaching kernels are disjoint.
1173 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1174 bool ObjHasKernelLifetime = false;
1175 const bool UseDominanceReasoning =
1176 FindInterferingWrites && IsKnownNoRecurse;
1177 const DominatorTree *DT =
1178 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1179
1180 // Helper to check if a value has "kernel lifetime", that is it will not
1181 // outlive a GPU kernel. This is true for shared, constant, and local
1182 // globals on AMD and NVIDIA GPUs.
1183 auto HasKernelLifetime = [&](Value *V, Module &M) {
1184 if (!AA::isGPU(M))
1185 return false;
1186 unsigned VAS = V->getType()->getPointerAddressSpace();
1187 return AA::isGPUSharedAddressSpace(M, VAS) ||
1190 };
1191
1192 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1193 // to determine if we should look at reachability from the callee. For
1194 // certain pointers we know the lifetime and we do not have to step into the
1195 // callee to determine reachability as the pointer would be dead in the
1196 // callee. See the conditional initialization below.
1197 std::function<bool(const Function &)> IsLiveInCalleeCB;
1198
1199 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1200 // If the alloca containing function is not recursive the alloca
1201 // must be dead in the callee.
1202 const Function *AIFn = AI->getFunction();
1203 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1204 bool IsKnownNoRecurse;
1206 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1207 IsKnownNoRecurse)) {
1208 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1209 }
1210 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1211 // If the global has kernel lifetime we can stop if we reach a kernel
1212 // as it is "dead" in the (unknown) callees.
1213 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1214 if (ObjHasKernelLifetime)
1215 IsLiveInCalleeCB = [&A](const Function &Fn) {
1216 return !A.getInfoCache().isKernel(Fn);
1217 };
1218 }
1219
1220 // Set of accesses/instructions that will overwrite the result and are
1221 // therefore blockers in the reachability traversal.
1222 AA::InstExclusionSetTy ExclusionSet;
1223
1224 auto AccessCB = [&](const Access &Acc, bool Exact) {
1225 Function *AccScope = Acc.getRemoteInst()->getFunction();
1226 bool AccInSameScope = AccScope == &Scope;
1227
1228 // If the object has kernel lifetime we can ignore accesses only reachable
1229 // by other kernels. For now we only skip accesses *in* other kernels.
1230 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1231 A.getInfoCache().isKernel(*AccScope))
1232 return true;
1233
1234 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1235 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1236 ExclusionSet.insert(Acc.getRemoteInst());
1237 }
1238
1239 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1240 (!FindInterferingReads || !Acc.isRead()))
1241 return true;
1242
1243 bool Dominates = FindInterferingWrites && DT && Exact &&
1244 Acc.isMustAccess() && AccInSameScope &&
1245 DT->dominates(Acc.getRemoteInst(), &I);
1246 if (Dominates)
1247 DominatingWrites.insert(&Acc);
1248
1249 // Track if all interesting accesses are in the same `nosync` function as
1250 // the given instruction.
1251 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1252
1253 InterferingAccesses.push_back({&Acc, Exact});
1254 return true;
1255 };
1256 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1257 return false;
1258
1259 HasBeenWrittenTo = !DominatingWrites.empty();
1260
1261 // Dominating writes form a chain, find the least/lowest member.
1262 Instruction *LeastDominatingWriteInst = nullptr;
1263 for (const Access *Acc : DominatingWrites) {
1264 if (!LeastDominatingWriteInst) {
1265 LeastDominatingWriteInst = Acc->getRemoteInst();
1266 } else if (DT->dominates(LeastDominatingWriteInst,
1267 Acc->getRemoteInst())) {
1268 LeastDominatingWriteInst = Acc->getRemoteInst();
1269 }
1270 }
1271
1272 // Helper to determine if we can skip a specific write access.
1273 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1274 if (SkipCB && SkipCB(Acc))
1275 return true;
1276 if (!CanIgnoreThreading(Acc))
1277 return false;
1278
1279 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1280 // If we successfully excluded all effects we are interested in, the
1281 // access can be skipped.
1282 bool ReadChecked = !FindInterferingReads;
1283 bool WriteChecked = !FindInterferingWrites;
1284
1285 // If the instruction cannot reach the access, the former does not
1286 // interfere with what the access reads.
1287 if (!ReadChecked) {
1288 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1289 &ExclusionSet, IsLiveInCalleeCB))
1290 ReadChecked = true;
1291 }
1292 // If the instruction cannot be reach from the access, the latter does not
1293 // interfere with what the instruction reads.
1294 if (!WriteChecked) {
1295 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1296 &ExclusionSet, IsLiveInCalleeCB))
1297 WriteChecked = true;
1298 }
1299
1300 // If we still might be affected by the write of the access but there are
1301 // dominating writes in the function of the instruction
1302 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1303 // by them. This would have happend above if they are all in the same
1304 // function, so we only check the inter-procedural case. Effectively, we
1305 // want to show that there is no call after the dominting write that might
1306 // reach the access, and when it returns reach the instruction with the
1307 // updated value. To this end, we iterate all call sites, check if they
1308 // might reach the instruction without going through another access
1309 // (ExclusionSet) and at the same time might reach the access. However,
1310 // that is all part of AAInterFnReachability.
1311 if (!WriteChecked && HasBeenWrittenTo &&
1312 Acc.getRemoteInst()->getFunction() != &Scope) {
1313
1314 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1315 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1316 if (FnReachabilityAA) {
1317 // Without going backwards in the call tree, can we reach the access
1318 // from the least dominating write. Do not allow to pass the
1319 // instruction itself either.
1320 bool Inserted = ExclusionSet.insert(&I).second;
1321
1322 if (!FnReachabilityAA->instructionCanReach(
1323 A, *LeastDominatingWriteInst,
1324 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1325 WriteChecked = true;
1326
1327 if (Inserted)
1328 ExclusionSet.erase(&I);
1329 }
1330 }
1331
1332 if (ReadChecked && WriteChecked)
1333 return true;
1334
1335 if (!DT || !UseDominanceReasoning)
1336 return false;
1337 if (!DominatingWrites.count(&Acc))
1338 return false;
1339 return LeastDominatingWriteInst != Acc.getRemoteInst();
1340 };
1341
1342 // Run the user callback on all accesses we cannot skip and return if
1343 // that succeeded for all or not.
1344 for (auto &It : InterferingAccesses) {
1345 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1346 !CanSkipAccess(*It.first, It.second)) {
1347 if (!UserCB(*It.first, It.second))
1348 return false;
1349 }
1350 }
1351 return true;
1352 }
1353
1354 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1355 const AAPointerInfo &OtherAA,
1356 CallBase &CB) {
1357 using namespace AA::PointerInfo;
1358 if (!OtherAA.getState().isValidState() || !isValidState())
1359 return indicatePessimisticFixpoint();
1360
1361 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1362 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1363 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1364 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1365
1366 // Combine the accesses bin by bin.
1367 const auto &State = OtherAAImpl.getState();
1368 for (const auto &It : State) {
1369 for (auto Index : It.getSecond()) {
1370 const auto &RAcc = State.getAccess(Index);
1371 if (IsByval && !RAcc.isRead())
1372 continue;
1373 bool UsedAssumedInformation = false;
1374 AccessKind AK = RAcc.getKind();
1375 auto Content = A.translateArgumentToCallSiteContent(
1376 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1377 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1378 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1379
1380 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1381 RAcc.getType(), RAcc.getRemoteInst());
1382 }
1383 }
1384 return Changed;
1385 }
1386
1387 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1388 const OffsetInfo &Offsets, CallBase &CB,
1389 bool IsMustAcc) {
1390 using namespace AA::PointerInfo;
1391 if (!OtherAA.getState().isValidState() || !isValidState())
1392 return indicatePessimisticFixpoint();
1393
1394 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1395
1396 // Combine the accesses bin by bin.
1397 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1398 const auto &State = OtherAAImpl.getState();
1399 for (const auto &It : State) {
1400 for (auto Index : It.getSecond()) {
1401 const auto &RAcc = State.getAccess(Index);
1402 if (!IsMustAcc && RAcc.isAssumption())
1403 continue;
1404 for (auto Offset : Offsets) {
1405 auto NewRanges = Offset == AA::RangeTy::Unknown
1407 : RAcc.getRanges();
1408 if (!NewRanges.isUnknown()) {
1409 NewRanges.addToAllOffsets(Offset);
1410 }
1411 AccessKind AK = RAcc.getKind();
1412 if (!IsMustAcc)
1413 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1414 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1415 RAcc.getType(), RAcc.getRemoteInst());
1416 }
1417 }
1418 }
1419 return Changed;
1420 }
1421
1422 /// Statistic tracking for all AAPointerInfo implementations.
1423 /// See AbstractAttribute::trackStatistics().
1424 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1425
1426 /// Dump the state into \p O.
1427 void dumpState(raw_ostream &O) {
1428 for (auto &It : OffsetBins) {
1429 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1430 << "] : " << It.getSecond().size() << "\n";
1431 for (auto AccIndex : It.getSecond()) {
1432 auto &Acc = AccessList[AccIndex];
1433 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1434 if (Acc.getLocalInst() != Acc.getRemoteInst())
1435 O << " --> " << *Acc.getRemoteInst()
1436 << "\n";
1437 if (!Acc.isWrittenValueYetUndetermined()) {
1438 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1439 O << " - c: func " << Acc.getWrittenValue()->getName()
1440 << "\n";
1441 else if (Acc.getWrittenValue())
1442 O << " - c: " << *Acc.getWrittenValue() << "\n";
1443 else
1444 O << " - c: <unknown>\n";
1445 }
1446 }
1447 }
1448 }
1449};
1450
1451struct AAPointerInfoFloating : public AAPointerInfoImpl {
1453 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1454 : AAPointerInfoImpl(IRP, A) {}
1455
1456 /// Deal with an access and signal if it was handled successfully.
1457 bool handleAccess(Attributor &A, Instruction &I,
1458 std::optional<Value *> Content, AccessKind Kind,
1459 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1460 Type &Ty) {
1461 using namespace AA::PointerInfo;
1463 const DataLayout &DL = A.getDataLayout();
1464 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1465 if (!AccessSize.isScalable())
1466 Size = AccessSize.getFixedValue();
1467
1468 // Make a strictly ascending list of offsets as required by addAccess()
1469 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1470 llvm::sort(OffsetsSorted);
1471
1473 if (!VT || VT->getElementCount().isScalable() ||
1474 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1475 (*Content)->getType() != VT ||
1476 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1477 Changed =
1478 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1479 } else {
1480 // Handle vector stores with constant content element-wise.
1481 // TODO: We could look for the elements or create instructions
1482 // representing them.
1483 // TODO: We need to push the Content into the range abstraction
1484 // (AA::RangeTy) to allow different content values for different
1485 // ranges. ranges. Hence, support vectors storing different values.
1486 Type *ElementType = VT->getElementType();
1487 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1488 auto *ConstContent = cast<Constant>(*Content);
1489 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1490 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1491
1492 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1493 Value *ElementContent = ConstantExpr::getExtractElement(
1494 ConstContent, ConstantInt::get(Int32Ty, i));
1495
1496 // Add the element access.
1497 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1498 ElementContent, Kind, ElementType);
1499
1500 // Advance the offsets for the next element.
1501 for (auto &ElementOffset : ElementOffsets)
1502 ElementOffset += ElementSize;
1503 }
1504 }
1505 return true;
1506 };
1507
1508 /// See AbstractAttribute::updateImpl(...).
1509 ChangeStatus updateImpl(Attributor &A) override;
1510
1511 /// If the indices to \p GEP can be traced to constants, incorporate all
1512 /// of these into \p UsrOI.
1513 ///
1514 /// \return true iff \p UsrOI is updated.
1515 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1516 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1517 const GEPOperator *GEP);
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override {
1521 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1522 }
1523};
1524
1525bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1526 const DataLayout &DL,
1527 OffsetInfo &UsrOI,
1528 const OffsetInfo &PtrOI,
1529 const GEPOperator *GEP) {
1530 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1531 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1532 APInt ConstantOffset(BitWidth, 0);
1533
1534 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1535 "Don't look for constant values if the offset has already been "
1536 "determined to be unknown.");
1537
1538 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1539 UsrOI.setUnknown();
1540 return true;
1541 }
1542
1543 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1544 << (VariableOffsets.empty() ? "" : "not") << " constant "
1545 << *GEP << "\n");
1546
1547 auto Union = PtrOI;
1548 Union.addToAll(ConstantOffset.getSExtValue());
1549
1550 // Each VI in VariableOffsets has a set of potential constant values. Every
1551 // combination of elements, picked one each from these sets, is separately
1552 // added to the original set of offsets, thus resulting in more offsets.
1553 for (const auto &VI : VariableOffsets) {
1554 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1555 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1556 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1557 UsrOI.setUnknown();
1558 return true;
1559 }
1560
1561 // UndefValue is treated as a zero, which leaves Union as is.
1562 if (PotentialConstantsAA->undefIsContained())
1563 continue;
1564
1565 // We need at least one constant in every set to compute an actual offset.
1566 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1567 // don't actually exist. In other words, the absence of constant values
1568 // implies that the operation can be assumed dead for now.
1569 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1570 if (AssumedSet.empty())
1571 return false;
1572
1573 OffsetInfo Product;
1574 for (const auto &ConstOffset : AssumedSet) {
1575 auto CopyPerOffset = Union;
1576 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1577 VI.second.getZExtValue());
1578 Product.merge(CopyPerOffset);
1579 }
1580 Union = Product;
1581 }
1582
1583 UsrOI = std::move(Union);
1584 return true;
1585}
1586
1587ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1588 using namespace AA::PointerInfo;
1590 const DataLayout &DL = A.getDataLayout();
1591 Value &AssociatedValue = getAssociatedValue();
1592
1593 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1594 OffsetInfoMap[&AssociatedValue].insert(0);
1595
1596 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1597 // One does not simply walk into a map and assign a reference to a possibly
1598 // new location. That can cause an invalidation before the assignment
1599 // happens, like so:
1600 //
1601 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1602 //
1603 // The RHS is a reference that may be invalidated by an insertion caused by
1604 // the LHS. So we ensure that the side-effect of the LHS happens first.
1605
1606 assert(OffsetInfoMap.contains(CurPtr) &&
1607 "CurPtr does not exist in the map!");
1608
1609 auto &UsrOI = OffsetInfoMap[Usr];
1610 auto &PtrOI = OffsetInfoMap[CurPtr];
1611 assert(!PtrOI.isUnassigned() &&
1612 "Cannot pass through if the input Ptr was not visited!");
1613 UsrOI.merge(PtrOI);
1614 Follow = true;
1615 return true;
1616 };
1617
1618 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1619 Value *CurPtr = U.get();
1620 User *Usr = U.getUser();
1621 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1622 << "\n");
1623 assert(OffsetInfoMap.count(CurPtr) &&
1624 "The current pointer offset should have been seeded!");
1625 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1626 "Current pointer should be assigned");
1627
1628 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1629 if (CE->isCast())
1630 return HandlePassthroughUser(Usr, CurPtr, Follow);
1631 if (!isa<GEPOperator>(CE)) {
1632 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1633 << "\n");
1634 return false;
1635 }
1636 }
1637 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1638 // Note the order here, the Usr access might change the map, CurPtr is
1639 // already in it though.
1640 auto &UsrOI = OffsetInfoMap[Usr];
1641 auto &PtrOI = OffsetInfoMap[CurPtr];
1642
1643 if (UsrOI.isUnknown())
1644 return true;
1645
1646 if (PtrOI.isUnknown()) {
1647 Follow = true;
1648 UsrOI.setUnknown();
1649 return true;
1650 }
1651
1652 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1653 return true;
1654 }
1655 if (isa<PtrToIntInst>(Usr))
1656 return false;
1657 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1658 return HandlePassthroughUser(Usr, CurPtr, Follow);
1659 // Returns are allowed if they are in the associated functions. Users can
1660 // then check the call site return. Returns from other functions can't be
1661 // tracked and are cause for invalidation.
1662 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1663 if (RI->getFunction() == getAssociatedFunction()) {
1664 auto &PtrOI = OffsetInfoMap[CurPtr];
1665 Changed |= setReachesReturn(PtrOI);
1666 return true;
1667 }
1668 return false;
1669 }
1670
1671 // For PHIs we need to take care of the recurrence explicitly as the value
1672 // might change while we iterate through a loop. For now, we give up if
1673 // the PHI is not invariant.
1674 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1675 // Note the order here, the Usr access might change the map, CurPtr is
1676 // already in it though.
1677 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1678 auto &UsrOI = PhiIt->second;
1679 auto &PtrOI = OffsetInfoMap[CurPtr];
1680
1681 // Check if the PHI operand has already an unknown offset as we can't
1682 // improve on that anymore.
1683 if (PtrOI.isUnknown()) {
1684 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1685 << *CurPtr << " in " << *PHI << "\n");
1686 Follow = !UsrOI.isUnknown();
1687 UsrOI.setUnknown();
1688 return true;
1689 }
1690
1691 // Check if the PHI is invariant (so far).
1692 if (UsrOI == PtrOI) {
1693 assert(!PtrOI.isUnassigned() &&
1694 "Cannot assign if the current Ptr was not visited!");
1695 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1696 return true;
1697 }
1698
1699 // Check if the PHI operand can be traced back to AssociatedValue.
1700 APInt Offset(
1701 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1702 0);
1703 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1704 DL, Offset, /* AllowNonInbounds */ true);
1705 auto It = OffsetInfoMap.find(CurPtrBase);
1706 if (It == OffsetInfoMap.end()) {
1707 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1708 << *CurPtr << " in " << *PHI
1709 << " (base: " << *CurPtrBase << ")\n");
1710 UsrOI.setUnknown();
1711 Follow = true;
1712 return true;
1713 }
1714
1715 // Check if the PHI operand is not dependent on the PHI itself. Every
1716 // recurrence is a cyclic net of PHIs in the data flow, and has an
1717 // equivalent Cycle in the control flow. One of those PHIs must be in the
1718 // header of that control flow Cycle. This is independent of the choice of
1719 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1720 // every Cycle header; if such a node is marked unknown, this will
1721 // eventually propagate through the whole net of PHIs in the recurrence.
1722 const auto *CI =
1723 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1724 *PHI->getFunction());
1725 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1726 auto BaseOI = It->getSecond();
1727 BaseOI.addToAll(Offset.getZExtValue());
1728 if (IsFirstPHIUser || BaseOI == UsrOI) {
1729 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1730 << " in " << *Usr << "\n");
1731 return HandlePassthroughUser(Usr, CurPtr, Follow);
1732 }
1733
1734 LLVM_DEBUG(
1735 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1736 << *CurPtr << " in " << *PHI << "\n");
1737 UsrOI.setUnknown();
1738 Follow = true;
1739 return true;
1740 }
1741
1742 UsrOI.merge(PtrOI);
1743 Follow = true;
1744 return true;
1745 }
1746
1747 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1748 // If the access is to a pointer that may or may not be the associated
1749 // value, e.g. due to a PHI, we cannot assume it will be read.
1750 AccessKind AK = AccessKind::AK_R;
1751 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1752 AK = AccessKind(AK | AccessKind::AK_MUST);
1753 else
1754 AK = AccessKind(AK | AccessKind::AK_MAY);
1755 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1756 OffsetInfoMap[CurPtr].Offsets, Changed,
1757 *LoadI->getType()))
1758 return false;
1759
1760 auto IsAssumption = [](Instruction &I) {
1761 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1762 return II->isAssumeLikeIntrinsic();
1763 return false;
1764 };
1765
1766 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1767 // Check if the assumption and the load are executed together without
1768 // memory modification.
1769 do {
1770 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1771 return true;
1772 FromI = FromI->getNextNode();
1773 } while (FromI && FromI != ToI);
1774 return false;
1775 };
1776
1777 BasicBlock *BB = LoadI->getParent();
1778 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1779 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1780 return false;
1781 BasicBlock *IntrBB = IntrI.getParent();
1782 if (IntrI.getParent() == BB) {
1783 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1784 return false;
1785 } else {
1786 auto PredIt = pred_begin(IntrBB);
1787 if (PredIt == pred_end(IntrBB))
1788 return false;
1789 if ((*PredIt) != BB)
1790 return false;
1791 if (++PredIt != pred_end(IntrBB))
1792 return false;
1793 for (auto *SuccBB : successors(BB)) {
1794 if (SuccBB == IntrBB)
1795 continue;
1796 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1797 continue;
1798 return false;
1799 }
1800 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1801 return false;
1802 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1803 return false;
1804 }
1805 return true;
1806 };
1807
1808 std::pair<Value *, IntrinsicInst *> Assumption;
1809 for (const Use &LoadU : LoadI->uses()) {
1810 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1811 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1812 continue;
1813 for (const Use &CmpU : CmpI->uses()) {
1814 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1815 if (!IsValidAssume(*IntrI))
1816 continue;
1817 int Idx = CmpI->getOperandUse(0) == LoadU;
1818 Assumption = {CmpI->getOperand(Idx), IntrI};
1819 break;
1820 }
1821 }
1822 }
1823 if (Assumption.first)
1824 break;
1825 }
1826
1827 // Check if we found an assumption associated with this load.
1828 if (!Assumption.first || !Assumption.second)
1829 return true;
1830
1831 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1832 << *Assumption.second << ": " << *LoadI
1833 << " == " << *Assumption.first << "\n");
1834 bool UsedAssumedInformation = false;
1835 std::optional<Value *> Content = nullptr;
1836 if (Assumption.first)
1837 Content =
1838 A.getAssumedSimplified(*Assumption.first, *this,
1839 UsedAssumedInformation, AA::Interprocedural);
1840 return handleAccess(
1841 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1842 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1843 }
1844
1845 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1846 ArrayRef<Value *> OtherOps, AccessKind AK) {
1847 for (auto *OtherOp : OtherOps) {
1848 if (OtherOp == CurPtr) {
1849 LLVM_DEBUG(
1850 dbgs()
1851 << "[AAPointerInfo] Escaping use in store like instruction " << I
1852 << "\n");
1853 return false;
1854 }
1855 }
1856
1857 // If the access is to a pointer that may or may not be the associated
1858 // value, e.g. due to a PHI, we cannot assume it will be written.
1859 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1860 AK = AccessKind(AK | AccessKind::AK_MUST);
1861 else
1862 AK = AccessKind(AK | AccessKind::AK_MAY);
1863 bool UsedAssumedInformation = false;
1864 std::optional<Value *> Content = nullptr;
1865 if (ValueOp)
1866 Content = A.getAssumedSimplified(
1867 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1868 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1869 Changed, ValueTy);
1870 };
1871
1872 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1873 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1874 *StoreI->getValueOperand()->getType(),
1875 {StoreI->getValueOperand()}, AccessKind::AK_W);
1876 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1877 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1878 {RMWI->getValOperand()}, AccessKind::AK_RW);
1879 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1880 return HandleStoreLike(
1881 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1882 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1883 AccessKind::AK_RW);
1884
1885 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1886 if (CB->isLifetimeStartOrEnd())
1887 return true;
1888 const auto *TLI =
1889 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1890 if (getFreedOperand(CB, TLI) == U)
1891 return true;
1892 if (CB->isArgOperand(&U)) {
1893 unsigned ArgNo = CB->getArgOperandNo(&U);
1894 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1895 *this, IRPosition::callsite_argument(*CB, ArgNo),
1897 if (!CSArgPI)
1898 return false;
1899 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1900 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1901 IsArgMustAcc) |
1902 Changed;
1903 if (!CSArgPI->reachesReturn())
1904 return isValidState();
1905
1907 if (!Callee || Callee->arg_size() <= ArgNo)
1908 return false;
1909 bool UsedAssumedInformation = false;
1910 auto ReturnedValue = A.getAssumedSimplified(
1911 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1913 auto *ReturnedArg =
1914 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1915 auto *Arg = Callee->getArg(ArgNo);
1916 if (ReturnedArg && Arg != ReturnedArg)
1917 return true;
1918 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1919 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1921 if (!CSRetPI)
1922 return false;
1923 OffsetInfo OI = OffsetInfoMap[CurPtr];
1924 CSArgPI->addReturnedOffsetsTo(OI);
1925 Changed =
1926 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1927 return isValidState();
1928 }
1929 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1930 << "\n");
1931 return false;
1932 }
1933
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1935 return false;
1936 };
1937 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1938 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1939 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1940 if (OffsetInfoMap.count(NewU)) {
1941 LLVM_DEBUG({
1942 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1943 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1944 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1945 << "\n";
1946 }
1947 });
1948 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1949 }
1950 bool Unused;
1951 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1952 };
1953 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1954 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1955 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1956 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1957 return indicatePessimisticFixpoint();
1958 }
1959
1960 LLVM_DEBUG({
1961 dbgs() << "Accesses by bin after update:\n";
1962 dumpState(dbgs());
1963 });
1964
1965 return Changed;
1966}
1967
1968struct AAPointerInfoReturned final : AAPointerInfoImpl {
1969 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1970 : AAPointerInfoImpl(IRP, A) {}
1971
1972 /// See AbstractAttribute::updateImpl(...).
1973 ChangeStatus updateImpl(Attributor &A) override {
1974 return indicatePessimisticFixpoint();
1975 }
1976
1977 /// See AbstractAttribute::trackStatistics()
1978 void trackStatistics() const override {
1979 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1980 }
1981};
1982
1983struct AAPointerInfoArgument final : AAPointerInfoFloating {
1984 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1985 : AAPointerInfoFloating(IRP, A) {}
1986
1987 /// See AbstractAttribute::trackStatistics()
1988 void trackStatistics() const override {
1989 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1990 }
1991};
1992
1993struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1994 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1995 : AAPointerInfoFloating(IRP, A) {}
1996
1997 /// See AbstractAttribute::updateImpl(...).
1998 ChangeStatus updateImpl(Attributor &A) override {
1999 using namespace AA::PointerInfo;
2000 // We handle memory intrinsics explicitly, at least the first (=
2001 // destination) and second (=source) arguments as we know how they are
2002 // accessed.
2003 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2004 int64_t LengthVal = AA::RangeTy::Unknown;
2005 if (auto Length = MI->getLengthInBytes())
2006 LengthVal = Length->getSExtValue();
2007 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2008 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2009 if (ArgNo > 1) {
2010 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2011 << *MI << "\n");
2012 return indicatePessimisticFixpoint();
2013 } else {
2014 auto Kind =
2015 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2016 Changed =
2017 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2018 }
2019 LLVM_DEBUG({
2020 dbgs() << "Accesses by bin after update:\n";
2021 dumpState(dbgs());
2022 });
2023
2024 return Changed;
2025 }
2026
2027 // TODO: Once we have call site specific value information we can provide
2028 // call site specific liveness information and then it makes
2029 // sense to specialize attributes for call sites arguments instead of
2030 // redirecting requests to the callee argument.
2031 Argument *Arg = getAssociatedArgument();
2032 if (Arg) {
2033 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2034 auto *ArgAA =
2035 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2036 if (ArgAA && ArgAA->getState().isValidState())
2037 return translateAndAddStateFromCallee(A, *ArgAA,
2038 *cast<CallBase>(getCtxI()));
2039 if (!Arg->getParent()->isDeclaration())
2040 return indicatePessimisticFixpoint();
2041 }
2042
2043 bool IsKnownNoCapture;
2045 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2046 return indicatePessimisticFixpoint();
2047
2048 bool IsKnown = false;
2049 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2050 return ChangeStatus::UNCHANGED;
2051 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2052 auto Kind =
2053 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2054 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2055 nullptr);
2056 }
2057
2058 /// See AbstractAttribute::trackStatistics()
2059 void trackStatistics() const override {
2060 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2061 }
2062};
2063
2064struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2065 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2066 : AAPointerInfoFloating(IRP, A) {}
2067
2068 /// See AbstractAttribute::trackStatistics()
2069 void trackStatistics() const override {
2070 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2071 }
2072};
2073} // namespace
2074
2075/// -----------------------NoUnwind Function Attribute--------------------------
2076
2077namespace {
2078struct AANoUnwindImpl : AANoUnwind {
2079 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2080
2081 /// See AbstractAttribute::initialize(...).
2082 void initialize(Attributor &A) override {
2083 bool IsKnown;
2085 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2086 (void)IsKnown;
2087 }
2088
2089 const std::string getAsStr(Attributor *A) const override {
2090 return getAssumed() ? "nounwind" : "may-unwind";
2091 }
2092
2093 /// See AbstractAttribute::updateImpl(...).
2094 ChangeStatus updateImpl(Attributor &A) override {
2095 auto Opcodes = {
2096 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2097 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2098 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2099
2100 auto CheckForNoUnwind = [&](Instruction &I) {
2101 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2102 return true;
2103
2104 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2105 bool IsKnownNoUnwind;
2107 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2108 IsKnownNoUnwind);
2109 }
2110 return false;
2111 };
2112
2113 bool UsedAssumedInformation = false;
2114 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2115 UsedAssumedInformation))
2116 return indicatePessimisticFixpoint();
2117
2118 return ChangeStatus::UNCHANGED;
2119 }
2120};
2121
2122struct AANoUnwindFunction final : public AANoUnwindImpl {
2123 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2124 : AANoUnwindImpl(IRP, A) {}
2125
2126 /// See AbstractAttribute::trackStatistics()
2127 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2128};
2129
2130/// NoUnwind attribute deduction for a call sites.
2131struct AANoUnwindCallSite final
2132 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2133 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2134 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2135
2136 /// See AbstractAttribute::trackStatistics()
2137 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2138};
2139} // namespace
2140
2141/// ------------------------ NoSync Function Attribute -------------------------
2142
2143bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2144 switch (CB.getIntrinsicID()) {
2145 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2146 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2147 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2148 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2149 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2150 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2151 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2152 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2153 return true;
2154 case Intrinsic::amdgcn_s_barrier:
2155 if (ExecutedAligned)
2156 return true;
2157 break;
2158 default:
2159 break;
2160 }
2161 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2162}
2163
2165 if (!I->isAtomic())
2166 return false;
2167
2168 if (auto *FI = dyn_cast<FenceInst>(I))
2169 // All legal orderings for fence are stronger than monotonic.
2170 return FI->getSyncScopeID() != SyncScope::SingleThread;
2171 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2172 // Unordered is not a legal ordering for cmpxchg.
2173 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2174 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2175 }
2176
2177 AtomicOrdering Ordering;
2178 switch (I->getOpcode()) {
2179 case Instruction::AtomicRMW:
2180 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2181 break;
2182 case Instruction::Store:
2183 Ordering = cast<StoreInst>(I)->getOrdering();
2184 break;
2185 case Instruction::Load:
2186 Ordering = cast<LoadInst>(I)->getOrdering();
2187 break;
2188 default:
2190 "New atomic operations need to be known in the attributor.");
2191 }
2192
2193 return (Ordering != AtomicOrdering::Unordered &&
2194 Ordering != AtomicOrdering::Monotonic);
2195}
2196
2197/// Return true if this intrinsic is nosync. This is only used for intrinsics
2198/// which would be nosync except that they have a volatile flag. All other
2199/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2201 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2202 return !MI->isVolatile();
2203 return false;
2204}
2205
2206namespace {
2207struct AANoSyncImpl : AANoSync {
2208 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2209
2210 /// See AbstractAttribute::initialize(...).
2211 void initialize(Attributor &A) override {
2212 bool IsKnown;
2213 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2214 DepClassTy::NONE, IsKnown));
2215 (void)IsKnown;
2216 }
2217
2218 const std::string getAsStr(Attributor *A) const override {
2219 return getAssumed() ? "nosync" : "may-sync";
2220 }
2221
2222 /// See AbstractAttribute::updateImpl(...).
2223 ChangeStatus updateImpl(Attributor &A) override;
2224};
2225
2226ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2227
2228 auto CheckRWInstForNoSync = [&](Instruction &I) {
2229 return AA::isNoSyncInst(A, I, *this);
2230 };
2231
2232 auto CheckForNoSync = [&](Instruction &I) {
2233 // At this point we handled all read/write effects and they are all
2234 // nosync, so they can be skipped.
2235 if (I.mayReadOrWriteMemory())
2236 return true;
2237
2238 bool IsKnown;
2239 CallBase &CB = cast<CallBase>(I);
2242 IsKnown))
2243 return true;
2244
2245 // non-convergent and readnone imply nosync.
2246 return !CB.isConvergent();
2247 };
2248
2249 bool UsedAssumedInformation = false;
2250 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2251 UsedAssumedInformation) ||
2252 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2253 UsedAssumedInformation))
2254 return indicatePessimisticFixpoint();
2255
2257}
2258
2259struct AANoSyncFunction final : public AANoSyncImpl {
2260 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2261 : AANoSyncImpl(IRP, A) {}
2262
2263 /// See AbstractAttribute::trackStatistics()
2264 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2265};
2266
2267/// NoSync attribute deduction for a call sites.
2268struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2269 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2270 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2271
2272 /// See AbstractAttribute::trackStatistics()
2273 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2274};
2275} // namespace
2276
2277/// ------------------------ No-Free Attributes ----------------------------
2278
2279namespace {
2280struct AANoFreeImpl : public AANoFree {
2281 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2282
2283 /// See AbstractAttribute::initialize(...).
2284 void initialize(Attributor &A) override {
2285 bool IsKnown;
2286 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2287 DepClassTy::NONE, IsKnown));
2288 (void)IsKnown;
2289 }
2290
2291 /// See AbstractAttribute::updateImpl(...).
2292 ChangeStatus updateImpl(Attributor &A) override {
2293 auto CheckForNoFree = [&](Instruction &I) {
2294 bool IsKnown;
2297 DepClassTy::REQUIRED, IsKnown);
2298 };
2299
2300 bool UsedAssumedInformation = false;
2301 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2302 UsedAssumedInformation))
2303 return indicatePessimisticFixpoint();
2304 return ChangeStatus::UNCHANGED;
2305 }
2306
2307 /// See AbstractAttribute::getAsStr().
2308 const std::string getAsStr(Attributor *A) const override {
2309 return getAssumed() ? "nofree" : "may-free";
2310 }
2311};
2312
2313struct AANoFreeFunction final : public AANoFreeImpl {
2314 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2315 : AANoFreeImpl(IRP, A) {}
2316
2317 /// See AbstractAttribute::trackStatistics()
2318 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2319};
2320
2321/// NoFree attribute deduction for a call sites.
2322struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2323 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2324 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2325
2326 /// See AbstractAttribute::trackStatistics()
2327 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2328};
2329
2330/// NoFree attribute for floating values.
2331struct AANoFreeFloating : AANoFreeImpl {
2332 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2333 : AANoFreeImpl(IRP, A) {}
2334
2335 /// See AbstractAttribute::trackStatistics()
2336 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2337
2338 /// See Abstract Attribute::updateImpl(...).
2339 ChangeStatus updateImpl(Attributor &A) override {
2340 const IRPosition &IRP = getIRPosition();
2341
2342 bool IsKnown;
2345 DepClassTy::OPTIONAL, IsKnown))
2346 return ChangeStatus::UNCHANGED;
2347
2348 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2349 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2350 Instruction *UserI = cast<Instruction>(U.getUser());
2351 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2352 if (CB->isBundleOperand(&U))
2353 return false;
2354 if (!CB->isArgOperand(&U))
2355 return true;
2356 unsigned ArgNo = CB->getArgOperandNo(&U);
2357
2358 bool IsKnown;
2360 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2361 DepClassTy::REQUIRED, IsKnown);
2362 }
2363
2364 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2365 isa<SelectInst>(UserI)) {
2366 Follow = true;
2367 return true;
2368 }
2369 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2370 return true;
2371
2372 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2373 return true;
2374
2375 // Unknown user.
2376 return false;
2377 };
2378 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2379 return indicatePessimisticFixpoint();
2380
2381 return ChangeStatus::UNCHANGED;
2382 }
2383};
2384
2385/// NoFree attribute for a call site argument.
2386struct AANoFreeArgument final : AANoFreeFloating {
2387 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2388 : AANoFreeFloating(IRP, A) {}
2389
2390 /// See AbstractAttribute::trackStatistics()
2391 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2392};
2393
2394/// NoFree attribute for call site arguments.
2395struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2396 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2397 : AANoFreeFloating(IRP, A) {}
2398
2399 /// See AbstractAttribute::updateImpl(...).
2400 ChangeStatus updateImpl(Attributor &A) override {
2401 // TODO: Once we have call site specific value information we can provide
2402 // call site specific liveness information and then it makes
2403 // sense to specialize attributes for call sites arguments instead of
2404 // redirecting requests to the callee argument.
2405 Argument *Arg = getAssociatedArgument();
2406 if (!Arg)
2407 return indicatePessimisticFixpoint();
2408 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2409 bool IsKnown;
2411 DepClassTy::REQUIRED, IsKnown))
2412 return ChangeStatus::UNCHANGED;
2413 return indicatePessimisticFixpoint();
2414 }
2415
2416 /// See AbstractAttribute::trackStatistics()
2417 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2418};
2419
2420/// NoFree attribute for function return value.
2421struct AANoFreeReturned final : AANoFreeFloating {
2422 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2423 : AANoFreeFloating(IRP, A) {
2424 llvm_unreachable("NoFree is not applicable to function returns!");
2425 }
2426
2427 /// See AbstractAttribute::initialize(...).
2428 void initialize(Attributor &A) override {
2429 llvm_unreachable("NoFree is not applicable to function returns!");
2430 }
2431
2432 /// See AbstractAttribute::updateImpl(...).
2433 ChangeStatus updateImpl(Attributor &A) override {
2434 llvm_unreachable("NoFree is not applicable to function returns!");
2435 }
2436
2437 /// See AbstractAttribute::trackStatistics()
2438 void trackStatistics() const override {}
2439};
2440
2441/// NoFree attribute deduction for a call site return value.
2442struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2443 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2444 : AANoFreeFloating(IRP, A) {}
2445
2446 ChangeStatus manifest(Attributor &A) override {
2447 return ChangeStatus::UNCHANGED;
2448 }
2449 /// See AbstractAttribute::trackStatistics()
2450 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2451};
2452} // namespace
2453
2454/// ------------------------ NonNull Argument Attribute ------------------------
2455
2457 Attribute::AttrKind ImpliedAttributeKind,
2458 bool IgnoreSubsumingPositions) {
2460 AttrKinds.push_back(Attribute::NonNull);
2463 AttrKinds.push_back(Attribute::Dereferenceable);
2464 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2465 return true;
2466
2467 DominatorTree *DT = nullptr;
2468 AssumptionCache *AC = nullptr;
2469 InformationCache &InfoCache = A.getInfoCache();
2470 if (const Function *Fn = IRP.getAnchorScope()) {
2471 if (!Fn->isDeclaration()) {
2474 }
2475 }
2476
2478 if (IRP.getPositionKind() != IRP_RETURNED) {
2479 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2480 } else {
2481 bool UsedAssumedInformation = false;
2482 if (!A.checkForAllInstructions(
2483 [&](Instruction &I) {
2484 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2485 return true;
2486 },
2487 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2488 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2489 return false;
2490 }
2491
2492 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2493 return !isKnownNonZero(
2494 VAC.getValue(),
2495 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2496 }))
2497 return false;
2498
2499 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2500 Attribute::NonNull)});
2501 return true;
2502}
2503
2504namespace {
2505static int64_t getKnownNonNullAndDerefBytesForUse(
2506 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2507 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2508 TrackUse = false;
2509
2510 const Value *UseV = U->get();
2511 if (!UseV->getType()->isPointerTy())
2512 return 0;
2513
2514 // We need to follow common pointer manipulation uses to the accesses they
2515 // feed into. We can try to be smart to avoid looking through things we do not
2516 // like for now, e.g., non-inbounds GEPs.
2517 if (isa<CastInst>(I)) {
2518 TrackUse = true;
2519 return 0;
2520 }
2521
2523 TrackUse = true;
2524 return 0;
2525 }
2526
2527 Type *PtrTy = UseV->getType();
2528 const Function *F = I->getFunction();
2531 const DataLayout &DL = A.getInfoCache().getDL();
2532 if (const auto *CB = dyn_cast<CallBase>(I)) {
2533 if (CB->isBundleOperand(U)) {
2534 if (RetainedKnowledge RK = getKnowledgeFromUse(
2535 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2536 IsNonNull |=
2537 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2538 return RK.ArgValue;
2539 }
2540 return 0;
2541 }
2542
2543 if (CB->isCallee(U)) {
2544 IsNonNull |= !NullPointerIsDefined;
2545 return 0;
2546 }
2547
2548 unsigned ArgNo = CB->getArgOperandNo(U);
2549 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2550 // As long as we only use known information there is no need to track
2551 // dependences here.
2552 bool IsKnownNonNull;
2554 DepClassTy::NONE, IsKnownNonNull);
2555 IsNonNull |= IsKnownNonNull;
2556 auto *DerefAA =
2557 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2558 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2559 }
2560
2561 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2562 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2563 Loc->Size.isScalable() || I->isVolatile())
2564 return 0;
2565
2566 int64_t Offset;
2567 const Value *Base =
2568 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2569 if (Base && Base == &AssociatedValue) {
2570 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2571 IsNonNull |= !NullPointerIsDefined;
2572 return std::max(int64_t(0), DerefBytes);
2573 }
2574
2575 /// Corner case when an offset is 0.
2577 /*AllowNonInbounds*/ true);
2578 if (Base && Base == &AssociatedValue && Offset == 0) {
2579 int64_t DerefBytes = Loc->Size.getValue();
2580 IsNonNull |= !NullPointerIsDefined;
2581 return std::max(int64_t(0), DerefBytes);
2582 }
2583
2584 return 0;
2585}
2586
2587struct AANonNullImpl : AANonNull {
2588 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2589
2590 /// See AbstractAttribute::initialize(...).
2591 void initialize(Attributor &A) override {
2592 Value &V = *getAssociatedValue().stripPointerCasts();
2593 if (isa<ConstantPointerNull>(V)) {
2594 indicatePessimisticFixpoint();
2595 return;
2596 }
2597
2598 if (Instruction *CtxI = getCtxI())
2599 followUsesInMBEC(*this, A, getState(), *CtxI);
2600 }
2601
2602 /// See followUsesInMBEC
2603 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2604 AANonNull::StateType &State) {
2605 bool IsNonNull = false;
2606 bool TrackUse = false;
2607 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2608 IsNonNull, TrackUse);
2609 State.setKnown(IsNonNull);
2610 return TrackUse;
2611 }
2612
2613 /// See AbstractAttribute::getAsStr().
2614 const std::string getAsStr(Attributor *A) const override {
2615 return getAssumed() ? "nonnull" : "may-null";
2616 }
2617};
2618
2619/// NonNull attribute for a floating value.
2620struct AANonNullFloating : public AANonNullImpl {
2621 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2622 : AANonNullImpl(IRP, A) {}
2623
2624 /// See AbstractAttribute::updateImpl(...).
2625 ChangeStatus updateImpl(Attributor &A) override {
2626 auto CheckIRP = [&](const IRPosition &IRP) {
2627 bool IsKnownNonNull;
2629 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2630 };
2631
2632 bool Stripped;
2633 bool UsedAssumedInformation = false;
2634 Value *AssociatedValue = &getAssociatedValue();
2636 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2637 AA::AnyScope, UsedAssumedInformation))
2638 Stripped = false;
2639 else
2640 Stripped =
2641 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2642
2643 if (!Stripped) {
2644 bool IsKnown;
2645 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2646 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2647 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2648 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2649 IsKnown);
2650 }))
2651 return ChangeStatus::UNCHANGED;
2652 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2654 A, this, IRPosition::value(*Select->getFalseValue()),
2655 DepClassTy::OPTIONAL, IsKnown) &&
2657 A, this, IRPosition::value(*Select->getTrueValue()),
2658 DepClassTy::OPTIONAL, IsKnown))
2659 return ChangeStatus::UNCHANGED;
2660
2661 // If we haven't stripped anything we might still be able to use a
2662 // different AA, but only if the IRP changes. Effectively when we
2663 // interpret this not as a call site value but as a floating/argument
2664 // value.
2665 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2666 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2667 return indicatePessimisticFixpoint();
2668 return ChangeStatus::UNCHANGED;
2669 }
2670
2671 for (const auto &VAC : Values)
2672 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2673 return indicatePessimisticFixpoint();
2674
2675 return ChangeStatus::UNCHANGED;
2676 }
2677
2678 /// See AbstractAttribute::trackStatistics()
2679 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2680};
2681
2682/// NonNull attribute for function return value.
2683struct AANonNullReturned final
2684 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2685 false, AANonNull::IRAttributeKind, false> {
2686 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2687 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2688 false, Attribute::NonNull, false>(IRP, A) {
2689 }
2690
2691 /// See AbstractAttribute::getAsStr().
2692 const std::string getAsStr(Attributor *A) const override {
2693 return getAssumed() ? "nonnull" : "may-null";
2694 }
2695
2696 /// See AbstractAttribute::trackStatistics()
2697 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2698};
2699
2700/// NonNull attribute for function argument.
2701struct AANonNullArgument final
2702 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2703 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2704 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2705
2706 /// See AbstractAttribute::trackStatistics()
2707 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2708};
2709
2710struct AANonNullCallSiteArgument final : AANonNullFloating {
2711 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2712 : AANonNullFloating(IRP, A) {}
2713
2714 /// See AbstractAttribute::trackStatistics()
2715 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2716};
2717
2718/// NonNull attribute for a call site return position.
2719struct AANonNullCallSiteReturned final
2720 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2721 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2722 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2723
2724 /// See AbstractAttribute::trackStatistics()
2725 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2726};
2727} // namespace
2728
2729/// ------------------------ Must-Progress Attributes --------------------------
2730namespace {
2731struct AAMustProgressImpl : public AAMustProgress {
2732 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2733 : AAMustProgress(IRP, A) {}
2734
2735 /// See AbstractAttribute::initialize(...).
2736 void initialize(Attributor &A) override {
2737 bool IsKnown;
2739 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2740 (void)IsKnown;
2741 }
2742
2743 /// See AbstractAttribute::getAsStr()
2744 const std::string getAsStr(Attributor *A) const override {
2745 return getAssumed() ? "mustprogress" : "may-not-progress";
2746 }
2747};
2748
2749struct AAMustProgressFunction final : AAMustProgressImpl {
2750 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2751 : AAMustProgressImpl(IRP, A) {}
2752
2753 /// See AbstractAttribute::updateImpl(...).
2754 ChangeStatus updateImpl(Attributor &A) override {
2755 bool IsKnown;
2757 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2758 if (IsKnown)
2759 return indicateOptimisticFixpoint();
2760 return ChangeStatus::UNCHANGED;
2761 }
2762
2763 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2764 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2765 bool IsKnownMustProgress;
2767 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2768 /* IgnoreSubsumingPositions */ true);
2769 };
2770
2771 bool AllCallSitesKnown = true;
2772 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2773 /* RequireAllCallSites */ true,
2774 AllCallSitesKnown))
2775 return indicatePessimisticFixpoint();
2776
2777 return ChangeStatus::UNCHANGED;
2778 }
2779
2780 /// See AbstractAttribute::trackStatistics()
2781 void trackStatistics() const override {
2782 STATS_DECLTRACK_FN_ATTR(mustprogress)
2783 }
2784};
2785
2786/// MustProgress attribute deduction for a call sites.
2787struct AAMustProgressCallSite final : AAMustProgressImpl {
2788 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2789 : AAMustProgressImpl(IRP, A) {}
2790
2791 /// See AbstractAttribute::updateImpl(...).
2792 ChangeStatus updateImpl(Attributor &A) override {
2793 // TODO: Once we have call site specific value information we can provide
2794 // call site specific liveness information and then it makes
2795 // sense to specialize attributes for call sites arguments instead of
2796 // redirecting requests to the callee argument.
2797 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2798 bool IsKnownMustProgress;
2800 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2801 return indicatePessimisticFixpoint();
2802 return ChangeStatus::UNCHANGED;
2803 }
2804
2805 /// See AbstractAttribute::trackStatistics()
2806 void trackStatistics() const override {
2807 STATS_DECLTRACK_CS_ATTR(mustprogress);
2808 }
2809};
2810} // namespace
2811
2812/// ------------------------ No-Recurse Attributes ----------------------------
2813
2814namespace {
2815struct AANoRecurseImpl : public AANoRecurse {
2816 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2817
2818 /// See AbstractAttribute::initialize(...).
2819 void initialize(Attributor &A) override {
2820 bool IsKnown;
2822 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2823 (void)IsKnown;
2824 }
2825
2826 /// See AbstractAttribute::getAsStr()
2827 const std::string getAsStr(Attributor *A) const override {
2828 return getAssumed() ? "norecurse" : "may-recurse";
2829 }
2830};
2831
2832struct AANoRecurseFunction final : AANoRecurseImpl {
2833 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2834 : AANoRecurseImpl(IRP, A) {}
2835
2836 /// See AbstractAttribute::updateImpl(...).
2837 ChangeStatus updateImpl(Attributor &A) override {
2838
2839 // If all live call sites are known to be no-recurse, we are as well.
2840 auto CallSitePred = [&](AbstractCallSite ACS) {
2841 bool IsKnownNoRecurse;
2843 A, this,
2844 IRPosition::function(*ACS.getInstruction()->getFunction()),
2845 DepClassTy::NONE, IsKnownNoRecurse))
2846 return false;
2847 return IsKnownNoRecurse;
2848 };
2849 bool UsedAssumedInformation = false;
2850 if (A.checkForAllCallSites(CallSitePred, *this, true,
2851 UsedAssumedInformation)) {
2852 // If we know all call sites and all are known no-recurse, we are done.
2853 // If all known call sites, which might not be all that exist, are known
2854 // to be no-recurse, we are not done but we can continue to assume
2855 // no-recurse. If one of the call sites we have not visited will become
2856 // live, another update is triggered.
2857 if (!UsedAssumedInformation)
2858 indicateOptimisticFixpoint();
2859 return ChangeStatus::UNCHANGED;
2860 }
2861
2862 const AAInterFnReachability *EdgeReachability =
2863 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2864 DepClassTy::REQUIRED);
2865 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2866 return indicatePessimisticFixpoint();
2867 return ChangeStatus::UNCHANGED;
2868 }
2869
2870 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2871};
2872
2873/// NoRecurse attribute deduction for a call sites.
2874struct AANoRecurseCallSite final
2875 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2876 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2877 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2878
2879 /// See AbstractAttribute::trackStatistics()
2880 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2881};
2882} // namespace
2883
2884/// ------------------------ No-Convergent Attribute --------------------------
2885
2886namespace {
2887struct AANonConvergentImpl : public AANonConvergent {
2888 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2889 : AANonConvergent(IRP, A) {}
2890
2891 /// See AbstractAttribute::getAsStr()
2892 const std::string getAsStr(Attributor *A) const override {
2893 return getAssumed() ? "non-convergent" : "may-be-convergent";
2894 }
2895};
2896
2897struct AANonConvergentFunction final : AANonConvergentImpl {
2898 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2899 : AANonConvergentImpl(IRP, A) {}
2900
2901 /// See AbstractAttribute::updateImpl(...).
2902 ChangeStatus updateImpl(Attributor &A) override {
2903 // If all function calls are known to not be convergent, we are not
2904 // convergent.
2905 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2906 CallBase &CB = cast<CallBase>(Inst);
2908 if (!Callee || Callee->isIntrinsic()) {
2909 return false;
2910 }
2911 if (Callee->isDeclaration()) {
2912 return !Callee->hasFnAttribute(Attribute::Convergent);
2913 }
2914 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2915 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2916 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2917 };
2918
2919 bool UsedAssumedInformation = false;
2920 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2921 UsedAssumedInformation)) {
2922 return indicatePessimisticFixpoint();
2923 }
2924 return ChangeStatus::UNCHANGED;
2925 }
2926
2927 ChangeStatus manifest(Attributor &A) override {
2928 if (isKnownNotConvergent() &&
2929 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2930 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2931 return ChangeStatus::CHANGED;
2932 }
2933 return ChangeStatus::UNCHANGED;
2934 }
2935
2936 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2937};
2938} // namespace
2939
2940/// -------------------- Undefined-Behavior Attributes ------------------------
2941
2942namespace {
2943struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2944 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2945 : AAUndefinedBehavior(IRP, A) {}
2946
2947 /// See AbstractAttribute::updateImpl(...).
2948 // through a pointer (i.e. also branches etc.)
2949 ChangeStatus updateImpl(Attributor &A) override {
2950 const size_t UBPrevSize = KnownUBInsts.size();
2951 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2952
2953 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2954 // Volatile accesses on null are not necessarily UB.
2955 if (I.isVolatile())
2956 return true;
2957
2958 // Skip instructions that are already saved.
2959 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2960 return true;
2961
2962 // If we reach here, we know we have an instruction
2963 // that accesses memory through a pointer operand,
2964 // for which getPointerOperand() should give it to us.
2965 Value *PtrOp =
2966 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2967 assert(PtrOp &&
2968 "Expected pointer operand of memory accessing instruction");
2969
2970 // Either we stopped and the appropriate action was taken,
2971 // or we got back a simplified value to continue.
2972 std::optional<Value *> SimplifiedPtrOp =
2973 stopOnUndefOrAssumed(A, PtrOp, &I);
2974 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2975 return true;
2976 const Value *PtrOpVal = *SimplifiedPtrOp;
2977
2978 // A memory access through a pointer is considered UB
2979 // only if the pointer has constant null value.
2980 // TODO: Expand it to not only check constant values.
2981 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2982 AssumedNoUBInsts.insert(&I);
2983 return true;
2984 }
2985 const Type *PtrTy = PtrOpVal->getType();
2986
2987 // Because we only consider instructions inside functions,
2988 // assume that a parent function exists.
2989 const Function *F = I.getFunction();
2990
2991 // A memory access using constant null pointer is only considered UB
2992 // if null pointer is _not_ defined for the target platform.
2994 AssumedNoUBInsts.insert(&I);
2995 else
2996 KnownUBInsts.insert(&I);
2997 return true;
2998 };
2999
3000 auto InspectBrInstForUB = [&](Instruction &I) {
3001 // A conditional branch instruction is considered UB if it has `undef`
3002 // condition.
3003
3004 // Skip instructions that are already saved.
3005 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3006 return true;
3007
3008 // We know we have a branch instruction.
3009 auto *BrInst = cast<CondBrInst>(&I);
3010
3011 // Either we stopped and the appropriate action was taken,
3012 // or we got back a simplified value to continue.
3013 std::optional<Value *> SimplifiedCond =
3014 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3015 if (!SimplifiedCond || !*SimplifiedCond)
3016 return true;
3017 AssumedNoUBInsts.insert(&I);
3018 return true;
3019 };
3020
3021 auto InspectCallSiteForUB = [&](Instruction &I) {
3022 // Check whether a callsite always cause UB or not
3023
3024 // Skip instructions that are already saved.
3025 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3026 return true;
3027
3028 // Check nonnull and noundef argument attribute violation for each
3029 // callsite.
3030 CallBase &CB = cast<CallBase>(I);
3032 if (!Callee)
3033 return true;
3034 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3035 // If current argument is known to be simplified to null pointer and the
3036 // corresponding argument position is known to have nonnull attribute,
3037 // the argument is poison. Furthermore, if the argument is poison and
3038 // the position is known to have noundef attriubte, this callsite is
3039 // considered UB.
3040 if (idx >= Callee->arg_size())
3041 break;
3042 Value *ArgVal = CB.getArgOperand(idx);
3043 if (!ArgVal)
3044 continue;
3045 // Here, we handle three cases.
3046 // (1) Not having a value means it is dead. (we can replace the value
3047 // with undef)
3048 // (2) Simplified to undef. The argument violate noundef attriubte.
3049 // (3) Simplified to null pointer where known to be nonnull.
3050 // The argument is a poison value and violate noundef attribute.
3051 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3052 bool IsKnownNoUndef;
3054 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3055 if (!IsKnownNoUndef)
3056 continue;
3057 bool UsedAssumedInformation = false;
3058 std::optional<Value *> SimplifiedVal =
3059 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3060 UsedAssumedInformation, AA::Interprocedural);
3061 if (UsedAssumedInformation)
3062 continue;
3063 if (SimplifiedVal && !*SimplifiedVal)
3064 return true;
3065 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3066 KnownUBInsts.insert(&I);
3067 continue;
3068 }
3069 if (!ArgVal->getType()->isPointerTy() ||
3070 !isa<ConstantPointerNull>(**SimplifiedVal))
3071 continue;
3072 bool IsKnownNonNull;
3074 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3075 if (IsKnownNonNull)
3076 KnownUBInsts.insert(&I);
3077 }
3078 return true;
3079 };
3080
3081 auto InspectReturnInstForUB = [&](Instruction &I) {
3082 auto &RI = cast<ReturnInst>(I);
3083 // Either we stopped and the appropriate action was taken,
3084 // or we got back a simplified return value to continue.
3085 std::optional<Value *> SimplifiedRetValue =
3086 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3087 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3088 return true;
3089
3090 // Check if a return instruction always cause UB or not
3091 // Note: It is guaranteed that the returned position of the anchor
3092 // scope has noundef attribute when this is called.
3093 // We also ensure the return position is not "assumed dead"
3094 // because the returned value was then potentially simplified to
3095 // `undef` in AAReturnedValues without removing the `noundef`
3096 // attribute yet.
3097
3098 // When the returned position has noundef attriubte, UB occurs in the
3099 // following cases.
3100 // (1) Returned value is known to be undef.
3101 // (2) The value is known to be a null pointer and the returned
3102 // position has nonnull attribute (because the returned value is
3103 // poison).
3104 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3105 bool IsKnownNonNull;
3107 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3108 IsKnownNonNull);
3109 if (IsKnownNonNull)
3110 KnownUBInsts.insert(&I);
3111 }
3112
3113 return true;
3114 };
3115
3116 bool UsedAssumedInformation = false;
3117 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3118 {Instruction::Load, Instruction::Store,
3119 Instruction::AtomicCmpXchg,
3120 Instruction::AtomicRMW},
3121 UsedAssumedInformation,
3122 /* CheckBBLivenessOnly */ true);
3123 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3124 UsedAssumedInformation,
3125 /* CheckBBLivenessOnly */ true);
3126 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3127 UsedAssumedInformation);
3128
3129 // If the returned position of the anchor scope has noundef attriubte, check
3130 // all returned instructions.
3131 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3132 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3133 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3134 bool IsKnownNoUndef;
3136 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3137 if (IsKnownNoUndef)
3138 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3139 {Instruction::Ret}, UsedAssumedInformation,
3140 /* CheckBBLivenessOnly */ true);
3141 }
3142 }
3143
3144 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3145 UBPrevSize != KnownUBInsts.size())
3146 return ChangeStatus::CHANGED;
3147 return ChangeStatus::UNCHANGED;
3148 }
3149
3150 bool isKnownToCauseUB(Instruction *I) const override {
3151 return KnownUBInsts.count(I);
3152 }
3153
3154 bool isAssumedToCauseUB(Instruction *I) const override {
3155 // In simple words, if an instruction is not in the assumed to _not_
3156 // cause UB, then it is assumed UB (that includes those
3157 // in the KnownUBInsts set). The rest is boilerplate
3158 // is to ensure that it is one of the instructions we test
3159 // for UB.
3160
3161 switch (I->getOpcode()) {
3162 case Instruction::Load:
3163 case Instruction::Store:
3164 case Instruction::AtomicCmpXchg:
3165 case Instruction::AtomicRMW:
3166 case Instruction::CondBr:
3167 return !AssumedNoUBInsts.count(I);
3168 default:
3169 return false;
3170 }
3171 return false;
3172 }
3173
3174 ChangeStatus manifest(Attributor &A) override {
3175 if (KnownUBInsts.empty())
3176 return ChangeStatus::UNCHANGED;
3177 for (Instruction *I : KnownUBInsts)
3178 A.changeToUnreachableAfterManifest(I);
3179 return ChangeStatus::CHANGED;
3180 }
3181
3182 /// See AbstractAttribute::getAsStr()
3183 const std::string getAsStr(Attributor *A) const override {
3184 return getAssumed() ? "undefined-behavior" : "no-ub";
3185 }
3186
3187 /// Note: The correctness of this analysis depends on the fact that the
3188 /// following 2 sets will stop changing after some point.
3189 /// "Change" here means that their size changes.
3190 /// The size of each set is monotonically increasing
3191 /// (we only add items to them) and it is upper bounded by the number of
3192 /// instructions in the processed function (we can never save more
3193 /// elements in either set than this number). Hence, at some point,
3194 /// they will stop increasing.
3195 /// Consequently, at some point, both sets will have stopped
3196 /// changing, effectively making the analysis reach a fixpoint.
3197
3198 /// Note: These 2 sets are disjoint and an instruction can be considered
3199 /// one of 3 things:
3200 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3201 /// the KnownUBInsts set.
3202 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3203 /// has a reason to assume it).
3204 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3205 /// could not find a reason to assume or prove that it can cause UB,
3206 /// hence it assumes it doesn't. We have a set for these instructions
3207 /// so that we don't reprocess them in every update.
3208 /// Note however that instructions in this set may cause UB.
3209
3210protected:
3211 /// A set of all live instructions _known_ to cause UB.
3212 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3213
3214private:
3215 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3216 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3217
3218 // Should be called on updates in which if we're processing an instruction
3219 // \p I that depends on a value \p V, one of the following has to happen:
3220 // - If the value is assumed, then stop.
3221 // - If the value is known but undef, then consider it UB.
3222 // - Otherwise, do specific processing with the simplified value.
3223 // We return std::nullopt in the first 2 cases to signify that an appropriate
3224 // action was taken and the caller should stop.
3225 // Otherwise, we return the simplified value that the caller should
3226 // use for specific processing.
3227 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3228 Instruction *I) {
3229 bool UsedAssumedInformation = false;
3230 std::optional<Value *> SimplifiedV =
3231 A.getAssumedSimplified(IRPosition::value(*V), *this,
3232 UsedAssumedInformation, AA::Interprocedural);
3233 if (!UsedAssumedInformation) {
3234 // Don't depend on assumed values.
3235 if (!SimplifiedV) {
3236 // If it is known (which we tested above) but it doesn't have a value,
3237 // then we can assume `undef` and hence the instruction is UB.
3238 KnownUBInsts.insert(I);
3239 return std::nullopt;
3240 }
3241 if (!*SimplifiedV)
3242 return nullptr;
3243 V = *SimplifiedV;
3244 }
3245 if (isa<UndefValue>(V)) {
3246 KnownUBInsts.insert(I);
3247 return std::nullopt;
3248 }
3249 return V;
3250 }
3251};
3252
3253struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3254 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3255 : AAUndefinedBehaviorImpl(IRP, A) {}
3256
3257 /// See AbstractAttribute::trackStatistics()
3258 void trackStatistics() const override {
3259 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3260 "Number of instructions known to have UB");
3261 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3262 KnownUBInsts.size();
3263 }
3264};
3265} // namespace
3266
3267/// ------------------------ Will-Return Attributes ----------------------------
3268
3269namespace {
3270// Helper function that checks whether a function has any cycle which we don't
3271// know if it is bounded or not.
3272// Loops with maximum trip count are considered bounded, any other cycle not.
3273static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3274 ScalarEvolution *SE =
3275 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3276 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3277 // If either SCEV or LoopInfo is not available for the function then we assume
3278 // any cycle to be unbounded cycle.
3279 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3280 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3281 if (!SE || !LI) {
3282 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3283 if (SCCI.hasCycle())
3284 return true;
3285 return false;
3286 }
3287
3288 // If there's irreducible control, the function may contain non-loop cycles.
3290 return true;
3291
3292 // Any loop that does not have a max trip count is considered unbounded cycle.
3293 for (auto *L : LI->getLoopsInPreorder()) {
3294 if (!SE->getSmallConstantMaxTripCount(L))
3295 return true;
3296 }
3297 return false;
3298}
3299
3300struct AAWillReturnImpl : public AAWillReturn {
3301 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3302 : AAWillReturn(IRP, A) {}
3303
3304 /// See AbstractAttribute::initialize(...).
3305 void initialize(Attributor &A) override {
3306 bool IsKnown;
3308 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3309 (void)IsKnown;
3310 }
3311
3312 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3313 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3314 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3315 return false;
3316
3317 bool IsKnown;
3318 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3319 return IsKnown || !KnownOnly;
3320 return false;
3321 }
3322
3323 /// See AbstractAttribute::updateImpl(...).
3324 ChangeStatus updateImpl(Attributor &A) override {
3325 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3326 return ChangeStatus::UNCHANGED;
3327
3328 auto CheckForWillReturn = [&](Instruction &I) {
3330 bool IsKnown;
3332 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3333 if (IsKnown)
3334 return true;
3335 } else {
3336 return false;
3337 }
3338 bool IsKnownNoRecurse;
3340 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3341 };
3342
3343 bool UsedAssumedInformation = false;
3344 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3345 UsedAssumedInformation))
3346 return indicatePessimisticFixpoint();
3347
3348 auto CheckForVolatile = [&](Instruction &I) {
3349 // Volatile operations are not willreturn.
3350 return !I.isVolatile();
3351 };
3352 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3353 {Instruction::Load, Instruction::Store,
3354 Instruction::AtomicCmpXchg,
3355 Instruction::AtomicRMW},
3356 UsedAssumedInformation))
3357 return indicatePessimisticFixpoint();
3358
3359 return ChangeStatus::UNCHANGED;
3360 }
3361
3362 /// See AbstractAttribute::getAsStr()
3363 const std::string getAsStr(Attributor *A) const override {
3364 return getAssumed() ? "willreturn" : "may-noreturn";
3365 }
3366};
3367
3368struct AAWillReturnFunction final : AAWillReturnImpl {
3369 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3370 : AAWillReturnImpl(IRP, A) {}
3371
3372 /// See AbstractAttribute::initialize(...).
3373 void initialize(Attributor &A) override {
3374 AAWillReturnImpl::initialize(A);
3375
3376 Function *F = getAnchorScope();
3377 assert(F && "Did expect an anchor function");
3378 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3379 indicatePessimisticFixpoint();
3380 }
3381
3382 /// See AbstractAttribute::trackStatistics()
3383 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3384};
3385
3386/// WillReturn attribute deduction for a call sites.
3387struct AAWillReturnCallSite final
3388 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3389 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3390 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3391
3392 /// See AbstractAttribute::updateImpl(...).
3393 ChangeStatus updateImpl(Attributor &A) override {
3394 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3395 return ChangeStatus::UNCHANGED;
3396
3397 return AACalleeToCallSite::updateImpl(A);
3398 }
3399
3400 /// See AbstractAttribute::trackStatistics()
3401 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3402};
3403} // namespace
3404
3405/// -------------------AAIntraFnReachability Attribute--------------------------
3406
3407/// All information associated with a reachability query. This boilerplate code
3408/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3409/// different \p ToTy values.
3410template <typename ToTy> struct ReachabilityQueryInfo {
3411 enum class Reachable {
3414 };
3415
3416 /// Start here,
3417 const Instruction *From = nullptr;
3418 /// reach this place,
3419 const ToTy *To = nullptr;
3420 /// without going through any of these instructions,
3422 /// and remember if it worked:
3424
3425 /// Precomputed hash for this RQI.
3426 unsigned Hash = 0;
3427
3428 unsigned computeHashValue() const {
3429 assert(Hash == 0 && "Computed hash twice!");
3432 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3433 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3434 InstSetDMI::getHashValue(ExclusionSet));
3435 }
3436
3438 : From(From), To(To) {}
3439
3440 /// Constructor replacement to ensure unique and stable sets are used for the
3441 /// cache.
3443 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3444 : From(&From), To(&To), ExclusionSet(ES) {
3445
3446 if (!ES || ES->empty()) {
3447 ExclusionSet = nullptr;
3448 } else if (MakeUnique) {
3449 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3450 }
3451 }
3452
3455};
3456
3457namespace llvm {
3458template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3461
3464
3467 return &TombstoneKey;
3468 }
3469 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3470 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3471 }
3472 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3473 const ReachabilityQueryInfo<ToTy> *RHS) {
3474 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3475 return false;
3476 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3477 }
3478};
3479
3480#define DefineKeys(ToTy) \
3481 template <> \
3482 ReachabilityQueryInfo<ToTy> \
3483 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3484 ReachabilityQueryInfo<ToTy>( \
3485 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3486 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3487 template <> \
3488 ReachabilityQueryInfo<ToTy> \
3489 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3490 ReachabilityQueryInfo<ToTy>( \
3491 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3492 DenseMapInfo<const ToTy *>::getTombstoneKey());
3493
3495#undef DefineKeys
3496
3497} // namespace llvm
3498
3499namespace {
3500
3501template <typename BaseTy, typename ToTy>
3502struct CachedReachabilityAA : public BaseTy {
3503 using RQITy = ReachabilityQueryInfo<ToTy>;
3504
3505 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3506
3507 /// See AbstractAttribute::isQueryAA.
3508 bool isQueryAA() const override { return true; }
3509
3510 /// See AbstractAttribute::updateImpl(...).
3511 ChangeStatus updateImpl(Attributor &A) override {
3512 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3513 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3514 RQITy *RQI = QueryVector[u];
3515 if (RQI->Result == RQITy::Reachable::No &&
3516 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3517 Changed = ChangeStatus::CHANGED;
3518 }
3519 return Changed;
3520 }
3521
3522 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3523 bool IsTemporaryRQI) = 0;
3524
3525 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3526 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3527 RQI.Result = Result;
3528
3529 // Remove the temporary RQI from the cache.
3530 if (IsTemporaryRQI)
3531 QueryCache.erase(&RQI);
3532
3533 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3534 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3535 // this query. 2) We did not use the exclusion set, potentially because
3536 // there is none.
3537 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3538 RQITy PlainRQI(RQI.From, RQI.To);
3539 if (!QueryCache.count(&PlainRQI)) {
3540 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3541 RQIPtr->Result = Result;
3542 QueryVector.push_back(RQIPtr);
3543 QueryCache.insert(RQIPtr);
3544 }
3545 }
3546
3547 // Check if we need to insert a new permanent RQI with the exclusion set.
3548 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3549 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3550 "Did not expect empty set!");
3551 RQITy *RQIPtr = new (A.Allocator)
3552 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3553 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3554 RQIPtr->Result = Result;
3555 assert(!QueryCache.count(RQIPtr));
3556 QueryVector.push_back(RQIPtr);
3557 QueryCache.insert(RQIPtr);
3558 }
3559
3560 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3561 A.registerForUpdate(*this);
3562 return Result == RQITy::Reachable::Yes;
3563 }
3564
3565 const std::string getAsStr(Attributor *A) const override {
3566 // TODO: Return the number of reachable queries.
3567 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3568 }
3569
3570 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3571 typename RQITy::Reachable &Result) {
3572 if (!this->getState().isValidState()) {
3573 Result = RQITy::Reachable::Yes;
3574 return true;
3575 }
3576
3577 // If we have an exclusion set we might be able to find our answer by
3578 // ignoring it first.
3579 if (StackRQI.ExclusionSet) {
3580 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3581 auto It = QueryCache.find(&PlainRQI);
3582 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3583 Result = RQITy::Reachable::No;
3584 return true;
3585 }
3586 }
3587
3588 auto It = QueryCache.find(&StackRQI);
3589 if (It != QueryCache.end()) {
3590 Result = (*It)->Result;
3591 return true;
3592 }
3593
3594 // Insert a temporary for recursive queries. We will replace it with a
3595 // permanent entry later.
3596 QueryCache.insert(&StackRQI);
3597 return false;
3598 }
3599
3600private:
3601 SmallVector<RQITy *> QueryVector;
3602 DenseSet<RQITy *> QueryCache;
3603};
3604
3605struct AAIntraFnReachabilityFunction final
3606 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3607 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3608 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3609 : Base(IRP, A) {
3610 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3611 *IRP.getAssociatedFunction());
3612 }
3613
3614 bool isAssumedReachable(
3615 Attributor &A, const Instruction &From, const Instruction &To,
3616 const AA::InstExclusionSetTy *ExclusionSet) const override {
3617 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3618 if (&From == &To)
3619 return true;
3620
3621 RQITy StackRQI(A, From, To, ExclusionSet, false);
3622 RQITy::Reachable Result;
3623 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3624 return NonConstThis->isReachableImpl(A, StackRQI,
3625 /*IsTemporaryRQI=*/true);
3626 return Result == RQITy::Reachable::Yes;
3627 }
3628
3629 ChangeStatus updateImpl(Attributor &A) override {
3630 // We only depend on liveness. DeadEdges is all we care about, check if any
3631 // of them changed.
3632 auto *LivenessAA =
3633 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3634 if (LivenessAA &&
3635 llvm::all_of(DeadEdges,
3636 [&](const auto &DeadEdge) {
3637 return LivenessAA->isEdgeDead(DeadEdge.first,
3638 DeadEdge.second);
3639 }) &&
3640 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3641 return LivenessAA->isAssumedDead(BB);
3642 })) {
3643 return ChangeStatus::UNCHANGED;
3644 }
3645 DeadEdges.clear();
3646 DeadBlocks.clear();
3647 return Base::updateImpl(A);
3648 }
3649
3650 bool isReachableImpl(Attributor &A, RQITy &RQI,
3651 bool IsTemporaryRQI) override {
3652 const Instruction *Origin = RQI.From;
3653 bool UsedExclusionSet = false;
3654
3655 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3656 const AA::InstExclusionSetTy *ExclusionSet) {
3657 const Instruction *IP = &From;
3658 while (IP && IP != &To) {
3659 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3660 UsedExclusionSet = true;
3661 break;
3662 }
3663 IP = IP->getNextNode();
3664 }
3665 return IP == &To;
3666 };
3667
3668 const BasicBlock *FromBB = RQI.From->getParent();
3669 const BasicBlock *ToBB = RQI.To->getParent();
3670 assert(FromBB->getParent() == ToBB->getParent() &&
3671 "Not an intra-procedural query!");
3672
3673 // Check intra-block reachability, however, other reaching paths are still
3674 // possible.
3675 if (FromBB == ToBB &&
3676 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3677 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3678 IsTemporaryRQI);
3679
3680 // Check if reaching the ToBB block is sufficient or if even that would not
3681 // ensure reaching the target. In the latter case we are done.
3682 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3683 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3684 IsTemporaryRQI);
3685
3686 const Function *Fn = FromBB->getParent();
3687 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3688 if (RQI.ExclusionSet)
3689 for (auto *I : *RQI.ExclusionSet)
3690 if (I->getFunction() == Fn)
3691 ExclusionBlocks.insert(I->getParent());
3692
3693 // Check if we make it out of the FromBB block at all.
3694 if (ExclusionBlocks.count(FromBB) &&
3695 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3696 RQI.ExclusionSet))
3697 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3698
3699 auto *LivenessAA =
3700 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3701 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3702 DeadBlocks.insert(ToBB);
3703 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3704 IsTemporaryRQI);
3705 }
3706
3707 SmallPtrSet<const BasicBlock *, 16> Visited;
3709 Worklist.push_back(FromBB);
3710
3711 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3712 while (!Worklist.empty()) {
3713 const BasicBlock *BB = Worklist.pop_back_val();
3714 if (!Visited.insert(BB).second)
3715 continue;
3716 for (const BasicBlock *SuccBB : successors(BB)) {
3717 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3718 LocalDeadEdges.insert({BB, SuccBB});
3719 continue;
3720 }
3721 // We checked before if we just need to reach the ToBB block.
3722 if (SuccBB == ToBB)
3723 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3724 IsTemporaryRQI);
3725 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3726 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3727 IsTemporaryRQI);
3728
3729 if (ExclusionBlocks.count(SuccBB)) {
3730 UsedExclusionSet = true;
3731 continue;
3732 }
3733 Worklist.push_back(SuccBB);
3734 }
3735 }
3736
3737 DeadEdges.insert_range(LocalDeadEdges);
3738 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3739 IsTemporaryRQI);
3740 }
3741
3742 /// See AbstractAttribute::trackStatistics()
3743 void trackStatistics() const override {}
3744
3745private:
3746 // Set of assumed dead blocks we used in the last query. If any changes we
3747 // update the state.
3748 DenseSet<const BasicBlock *> DeadBlocks;
3749
3750 // Set of assumed dead edges we used in the last query. If any changes we
3751 // update the state.
3752 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3753
3754 /// The dominator tree of the function to short-circuit reasoning.
3755 const DominatorTree *DT = nullptr;
3756};
3757} // namespace
3758
3759/// ------------------------ NoAlias Argument Attribute ------------------------
3760
3762 Attribute::AttrKind ImpliedAttributeKind,
3763 bool IgnoreSubsumingPositions) {
3764 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3765 "Unexpected attribute kind");
3766 Value *Val = &IRP.getAssociatedValue();
3768 if (isa<AllocaInst>(Val))
3769 return true;
3770 } else {
3771 IgnoreSubsumingPositions = true;
3772 }
3773
3774 if (isa<UndefValue>(Val))
3775 return true;
3776
3777 if (isa<ConstantPointerNull>(Val) &&
3780 return true;
3781
3782 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3783 IgnoreSubsumingPositions, Attribute::NoAlias))
3784 return true;
3785
3786 return false;
3787}
3788
3789namespace {
3790struct AANoAliasImpl : AANoAlias {
3791 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3792 assert(getAssociatedType()->isPointerTy() &&
3793 "Noalias is a pointer attribute");
3794 }
3795
3796 const std::string getAsStr(Attributor *A) const override {
3797 return getAssumed() ? "noalias" : "may-alias";
3798 }
3799};
3800
3801/// NoAlias attribute for a floating value.
3802struct AANoAliasFloating final : AANoAliasImpl {
3803 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3804 : AANoAliasImpl(IRP, A) {}
3805
3806 /// See AbstractAttribute::updateImpl(...).
3807 ChangeStatus updateImpl(Attributor &A) override {
3808 // TODO: Implement this.
3809 return indicatePessimisticFixpoint();
3810 }
3811
3812 /// See AbstractAttribute::trackStatistics()
3813 void trackStatistics() const override {
3815 }
3816};
3817
3818/// NoAlias attribute for an argument.
3819struct AANoAliasArgument final
3820 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3821 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3822 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3823
3824 /// See AbstractAttribute::update(...).
3825 ChangeStatus updateImpl(Attributor &A) override {
3826 // We have to make sure no-alias on the argument does not break
3827 // synchronization when this is a callback argument, see also [1] below.
3828 // If synchronization cannot be affected, we delegate to the base updateImpl
3829 // function, otherwise we give up for now.
3830
3831 // If the function is no-sync, no-alias cannot break synchronization.
3832 bool IsKnownNoSycn;
3834 A, this, IRPosition::function_scope(getIRPosition()),
3835 DepClassTy::OPTIONAL, IsKnownNoSycn))
3836 return Base::updateImpl(A);
3837
3838 // If the argument is read-only, no-alias cannot break synchronization.
3839 bool IsKnown;
3840 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3841 return Base::updateImpl(A);
3842
3843 // If the argument is never passed through callbacks, no-alias cannot break
3844 // synchronization.
3845 bool UsedAssumedInformation = false;
3846 if (A.checkForAllCallSites(
3847 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3848 true, UsedAssumedInformation))
3849 return Base::updateImpl(A);
3850
3851 // TODO: add no-alias but make sure it doesn't break synchronization by
3852 // introducing fake uses. See:
3853 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3854 // International Workshop on OpenMP 2018,
3855 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3856
3857 return indicatePessimisticFixpoint();
3858 }
3859
3860 /// See AbstractAttribute::trackStatistics()
3861 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3862};
3863
3864struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3865 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3866 : AANoAliasImpl(IRP, A) {}
3867
3868 /// Determine if the underlying value may alias with the call site argument
3869 /// \p OtherArgNo of \p ICS (= the underlying call site).
3870 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3871 const AAMemoryBehavior &MemBehaviorAA,
3872 const CallBase &CB, unsigned OtherArgNo) {
3873 // We do not need to worry about aliasing with the underlying IRP.
3874 if (this->getCalleeArgNo() == (int)OtherArgNo)
3875 return false;
3876
3877 // If it is not a pointer or pointer vector we do not alias.
3878 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3879 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3880 return false;
3881
3882 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3883 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3884
3885 // If the argument is readnone, there is no read-write aliasing.
3886 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3887 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3888 return false;
3889 }
3890
3891 // If the argument is readonly and the underlying value is readonly, there
3892 // is no read-write aliasing.
3893 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3894 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3895 IsReadOnly) {
3896 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3897 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3898 return false;
3899 }
3900
3901 // We have to utilize actual alias analysis queries so we need the object.
3902 if (!AAR)
3903 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3904 *getAnchorScope());
3905
3906 // Try to rule it out at the call site.
3907 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3908 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3909 "callsite arguments: "
3910 << getAssociatedValue() << " " << *ArgOp << " => "
3911 << (IsAliasing ? "" : "no-") << "alias \n");
3912
3913 return IsAliasing;
3914 }
3915
3916 bool isKnownNoAliasDueToNoAliasPreservation(
3917 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3918 // We can deduce "noalias" if the following conditions hold.
3919 // (i) Associated value is assumed to be noalias in the definition.
3920 // (ii) Associated value is assumed to be no-capture in all the uses
3921 // possibly executed before this callsite.
3922 // (iii) There is no other pointer argument which could alias with the
3923 // value.
3924
3925 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3926 const Function *ScopeFn = VIRP.getAnchorScope();
3927 // Check whether the value is captured in the scope using AANoCapture.
3928 // Look at CFG and check only uses possibly executed before this
3929 // callsite.
3930 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3931 Instruction *UserI = cast<Instruction>(U.getUser());
3932
3933 // If UserI is the curr instruction and there is a single potential use of
3934 // the value in UserI we allow the use.
3935 // TODO: We should inspect the operands and allow those that cannot alias
3936 // with the value.
3937 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3938 return true;
3939
3940 if (ScopeFn) {
3941 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3942 if (CB->isArgOperand(&U)) {
3943
3944 unsigned ArgNo = CB->getArgOperandNo(&U);
3945
3946 bool IsKnownNoCapture;
3948 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3949 DepClassTy::OPTIONAL, IsKnownNoCapture))
3950 return true;
3951 }
3952 }
3953
3955 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3956 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3957 return true;
3958 }
3959
3960 // TODO: We should track the capturing uses in AANoCapture but the problem
3961 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3962 // a value in the module slice.
3963 // TODO(captures): Make this more precise.
3964 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3965 if (capturesNothing(CI))
3966 return true;
3967 if (CI.isPassthrough()) {
3968 Follow = true;
3969 return true;
3970 }
3971 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3972 return false;
3973 };
3974
3975 bool IsKnownNoCapture;
3976 const AANoCapture *NoCaptureAA = nullptr;
3977 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3978 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3979 if (!IsAssumedNoCapture &&
3980 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3981 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3982 LLVM_DEBUG(
3983 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3984 << " cannot be noalias as it is potentially captured\n");
3985 return false;
3986 }
3987 }
3988 if (NoCaptureAA)
3989 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3990
3991 // Check there is no other pointer argument which could alias with the
3992 // value passed at this call site.
3993 // TODO: AbstractCallSite
3994 const auto &CB = cast<CallBase>(getAnchorValue());
3995 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3996 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3997 return false;
3998
3999 return true;
4000 }
4001
4002 /// See AbstractAttribute::updateImpl(...).
4003 ChangeStatus updateImpl(Attributor &A) override {
4004 // If the argument is readnone we are done as there are no accesses via the
4005 // argument.
4006 auto *MemBehaviorAA =
4007 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4008 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4009 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4010 return ChangeStatus::UNCHANGED;
4011 }
4012
4013 bool IsKnownNoAlias;
4014 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4016 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4017 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4018 << " is not no-alias at the definition\n");
4019 return indicatePessimisticFixpoint();
4020 }
4021
4022 AAResults *AAR = nullptr;
4023 if (MemBehaviorAA &&
4024 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4025 LLVM_DEBUG(
4026 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4027 return ChangeStatus::UNCHANGED;
4028 }
4029
4030 return indicatePessimisticFixpoint();
4031 }
4032
4033 /// See AbstractAttribute::trackStatistics()
4034 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4035};
4036
4037/// NoAlias attribute for function return value.
4038struct AANoAliasReturned final : AANoAliasImpl {
4039 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4040 : AANoAliasImpl(IRP, A) {}
4041
4042 /// See AbstractAttribute::updateImpl(...).
4043 ChangeStatus updateImpl(Attributor &A) override {
4044
4045 auto CheckReturnValue = [&](Value &RV) -> bool {
4046 if (Constant *C = dyn_cast<Constant>(&RV))
4047 if (C->isNullValue() || isa<UndefValue>(C))
4048 return true;
4049
4050 /// For now, we can only deduce noalias if we have call sites.
4051 /// FIXME: add more support.
4052 if (!isa<CallBase>(&RV))
4053 return false;
4054
4055 const IRPosition &RVPos = IRPosition::value(RV);
4056 bool IsKnownNoAlias;
4058 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4059 return false;
4060
4061 bool IsKnownNoCapture;
4062 const AANoCapture *NoCaptureAA = nullptr;
4063 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4064 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4065 &NoCaptureAA);
4066 return IsAssumedNoCapture ||
4067 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4068 };
4069
4070 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4071 return indicatePessimisticFixpoint();
4072
4073 return ChangeStatus::UNCHANGED;
4074 }
4075
4076 /// See AbstractAttribute::trackStatistics()
4077 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4078};
4079
4080/// NoAlias attribute deduction for a call site return value.
4081struct AANoAliasCallSiteReturned final
4082 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4083 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4084 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4085
4086 /// See AbstractAttribute::trackStatistics()
4087 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4088};
4089} // namespace
4090
4091/// -------------------AAIsDead Function Attribute-----------------------
4092
4093namespace {
4094struct AAIsDeadValueImpl : public AAIsDead {
4095 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4096
4097 /// See AAIsDead::isAssumedDead().
4098 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4099
4100 /// See AAIsDead::isKnownDead().
4101 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4102
4103 /// See AAIsDead::isAssumedDead(BasicBlock *).
4104 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4105
4106 /// See AAIsDead::isKnownDead(BasicBlock *).
4107 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4108
4109 /// See AAIsDead::isAssumedDead(Instruction *I).
4110 bool isAssumedDead(const Instruction *I) const override {
4111 return I == getCtxI() && isAssumedDead();
4112 }
4113
4114 /// See AAIsDead::isKnownDead(Instruction *I).
4115 bool isKnownDead(const Instruction *I) const override {
4116 return isAssumedDead(I) && isKnownDead();
4117 }
4118
4119 /// See AbstractAttribute::getAsStr().
4120 const std::string getAsStr(Attributor *A) const override {
4121 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4122 }
4123
4124 /// Check if all uses are assumed dead.
4125 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4126 // Callers might not check the type, void has no uses.
4127 if (V.getType()->isVoidTy() || V.use_empty())
4128 return true;
4129
4130 // If we replace a value with a constant there are no uses left afterwards.
4131 if (!isa<Constant>(V)) {
4132 if (auto *I = dyn_cast<Instruction>(&V))
4133 if (!A.isRunOn(*I->getFunction()))
4134 return false;
4135 bool UsedAssumedInformation = false;
4136 std::optional<Constant *> C =
4137 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4138 if (!C || *C)
4139 return true;
4140 }
4141
4142 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4143 // Explicitly set the dependence class to required because we want a long
4144 // chain of N dependent instructions to be considered live as soon as one is
4145 // without going through N update cycles. This is not required for
4146 // correctness.
4147 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4148 DepClassTy::REQUIRED,
4149 /* IgnoreDroppableUses */ false);
4150 }
4151
4152 /// Determine if \p I is assumed to be side-effect free.
4153 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4155 return true;
4156
4157 if (!I->isTerminator() && !I->mayHaveSideEffects())
4158 return true;
4159
4160 auto *CB = dyn_cast<CallBase>(I);
4161 if (!CB || isa<IntrinsicInst>(CB))
4162 return false;
4163
4164 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4165
4166 bool IsKnownNoUnwind;
4168 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4169 return false;
4170
4171 bool IsKnown;
4172 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4173 }
4174};
4175
4176struct AAIsDeadFloating : public AAIsDeadValueImpl {
4177 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4178 : AAIsDeadValueImpl(IRP, A) {}
4179
4180 /// See AbstractAttribute::initialize(...).
4181 void initialize(Attributor &A) override {
4182 AAIsDeadValueImpl::initialize(A);
4183
4184 if (isa<UndefValue>(getAssociatedValue())) {
4185 indicatePessimisticFixpoint();
4186 return;
4187 }
4188
4189 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4190 if (!isAssumedSideEffectFree(A, I)) {
4192 indicatePessimisticFixpoint();
4193 else
4194 removeAssumedBits(HAS_NO_EFFECT);
4195 }
4196 }
4197
4198 bool isDeadFence(Attributor &A, FenceInst &FI) {
4199 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4200 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4201 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4202 return false;
4203 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4204 return true;
4205 }
4206
4207 bool isDeadStore(Attributor &A, StoreInst &SI,
4208 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4209 // Lang ref now states volatile store is not UB/dead, let's skip them.
4210 if (SI.isVolatile())
4211 return false;
4212
4213 // If we are collecting assumes to be deleted we are in the manifest stage.
4214 // It's problematic to collect the potential copies again now so we use the
4215 // cached ones.
4216 bool UsedAssumedInformation = false;
4217 if (!AssumeOnlyInst) {
4218 PotentialCopies.clear();
4219 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4220 UsedAssumedInformation)) {
4221 LLVM_DEBUG(
4222 dbgs()
4223 << "[AAIsDead] Could not determine potential copies of store!\n");
4224 return false;
4225 }
4226 }
4227 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4228 << " potential copies.\n");
4229
4230 InformationCache &InfoCache = A.getInfoCache();
4231 return llvm::all_of(PotentialCopies, [&](Value *V) {
4232 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4233 UsedAssumedInformation))
4234 return true;
4235 if (auto *LI = dyn_cast<LoadInst>(V)) {
4236 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4237 auto &UserI = cast<Instruction>(*U.getUser());
4238 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4239 if (AssumeOnlyInst)
4240 AssumeOnlyInst->insert(&UserI);
4241 return true;
4242 }
4243 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4244 })) {
4245 return true;
4246 }
4247 }
4248 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4249 << " is assumed live!\n");
4250 return false;
4251 });
4252 }
4253
4254 /// See AbstractAttribute::getAsStr().
4255 const std::string getAsStr(Attributor *A) const override {
4256 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4258 if (isValidState())
4259 return "assumed-dead-store";
4261 if (isValidState())
4262 return "assumed-dead-fence";
4263 return AAIsDeadValueImpl::getAsStr(A);
4264 }
4265
4266 /// See AbstractAttribute::updateImpl(...).
4267 ChangeStatus updateImpl(Attributor &A) override {
4268 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4269 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4270 if (!isDeadStore(A, *SI))
4271 return indicatePessimisticFixpoint();
4272 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4273 if (!isDeadFence(A, *FI))
4274 return indicatePessimisticFixpoint();
4275 } else {
4276 if (!isAssumedSideEffectFree(A, I))
4277 return indicatePessimisticFixpoint();
4278 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4279 return indicatePessimisticFixpoint();
4280 }
4282 }
4283
4284 bool isRemovableStore() const override {
4285 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4286 }
4287
4288 /// See AbstractAttribute::manifest(...).
4289 ChangeStatus manifest(Attributor &A) override {
4290 Value &V = getAssociatedValue();
4291 if (auto *I = dyn_cast<Instruction>(&V)) {
4292 // If we get here we basically know the users are all dead. We check if
4293 // isAssumedSideEffectFree returns true here again because it might not be
4294 // the case and only the users are dead but the instruction (=call) is
4295 // still needed.
4296 if (auto *SI = dyn_cast<StoreInst>(I)) {
4297 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4298 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4299 (void)IsDead;
4300 assert(IsDead && "Store was assumed to be dead!");
4301 A.deleteAfterManifest(*I);
4302 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4303 Instruction *AOI = AssumeOnlyInst[i];
4304 for (auto *Usr : AOI->users())
4305 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4306 A.deleteAfterManifest(*AOI);
4307 }
4308 return ChangeStatus::CHANGED;
4309 }
4310 if (auto *FI = dyn_cast<FenceInst>(I)) {
4311 assert(isDeadFence(A, *FI));
4312 A.deleteAfterManifest(*FI);
4313 return ChangeStatus::CHANGED;
4314 }
4315 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4316 A.deleteAfterManifest(*I);
4317 return ChangeStatus::CHANGED;
4318 }
4319 }
4321 }
4322
4323 /// See AbstractAttribute::trackStatistics()
4324 void trackStatistics() const override {
4326 }
4327
4328private:
4329 // The potential copies of a dead store, used for deletion during manifest.
4330 SmallSetVector<Value *, 4> PotentialCopies;
4331};
4332
4333struct AAIsDeadArgument : public AAIsDeadFloating {
4334 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4335 : AAIsDeadFloating(IRP, A) {}
4336
4337 /// See AbstractAttribute::manifest(...).
4338 ChangeStatus manifest(Attributor &A) override {
4339 Argument &Arg = *getAssociatedArgument();
4340 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4341 if (A.registerFunctionSignatureRewrite(
4342 Arg, /* ReplacementTypes */ {},
4345 return ChangeStatus::CHANGED;
4346 }
4347 return ChangeStatus::UNCHANGED;
4348 }
4349
4350 /// See AbstractAttribute::trackStatistics()
4351 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4352};
4353
4354struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4355 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4356 : AAIsDeadValueImpl(IRP, A) {}
4357
4358 /// See AbstractAttribute::initialize(...).
4359 void initialize(Attributor &A) override {
4360 AAIsDeadValueImpl::initialize(A);
4361 if (isa<UndefValue>(getAssociatedValue()))
4362 indicatePessimisticFixpoint();
4363 }
4364
4365 /// See AbstractAttribute::updateImpl(...).
4366 ChangeStatus updateImpl(Attributor &A) override {
4367 // TODO: Once we have call site specific value information we can provide
4368 // call site specific liveness information and then it makes
4369 // sense to specialize attributes for call sites arguments instead of
4370 // redirecting requests to the callee argument.
4371 Argument *Arg = getAssociatedArgument();
4372 if (!Arg)
4373 return indicatePessimisticFixpoint();
4374 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4375 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4376 if (!ArgAA)
4377 return indicatePessimisticFixpoint();
4378 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4379 }
4380
4381 /// See AbstractAttribute::manifest(...).
4382 ChangeStatus manifest(Attributor &A) override {
4383 CallBase &CB = cast<CallBase>(getAnchorValue());
4384 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4385 assert(!isa<UndefValue>(U.get()) &&
4386 "Expected undef values to be filtered out!");
4387 UndefValue &UV = *UndefValue::get(U->getType());
4388 if (A.changeUseAfterManifest(U, UV))
4389 return ChangeStatus::CHANGED;
4390 return ChangeStatus::UNCHANGED;
4391 }
4392
4393 /// See AbstractAttribute::trackStatistics()
4394 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4395};
4396
4397struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4398 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4399 : AAIsDeadFloating(IRP, A) {}
4400
4401 /// See AAIsDead::isAssumedDead().
4402 bool isAssumedDead() const override {
4403 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4404 }
4405
4406 /// See AbstractAttribute::initialize(...).
4407 void initialize(Attributor &A) override {
4408 AAIsDeadFloating::initialize(A);
4409 if (isa<UndefValue>(getAssociatedValue())) {
4410 indicatePessimisticFixpoint();
4411 return;
4412 }
4413
4414 // We track this separately as a secondary state.
4415 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4416 }
4417
4418 /// See AbstractAttribute::updateImpl(...).
4419 ChangeStatus updateImpl(Attributor &A) override {
4420 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4421 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4422 IsAssumedSideEffectFree = false;
4423 Changed = ChangeStatus::CHANGED;
4424 }
4425 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4426 return indicatePessimisticFixpoint();
4427 return Changed;
4428 }
4429
4430 /// See AbstractAttribute::trackStatistics()
4431 void trackStatistics() const override {
4432 if (IsAssumedSideEffectFree)
4434 else
4435 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4436 }
4437
4438 /// See AbstractAttribute::getAsStr().
4439 const std::string getAsStr(Attributor *A) const override {
4440 return isAssumedDead()
4441 ? "assumed-dead"
4442 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4443 }
4444
4445private:
4446 bool IsAssumedSideEffectFree = true;
4447};
4448
4449struct AAIsDeadReturned : public AAIsDeadValueImpl {
4450 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4451 : AAIsDeadValueImpl(IRP, A) {}
4452
4453 /// See AbstractAttribute::updateImpl(...).
4454 ChangeStatus updateImpl(Attributor &A) override {
4455
4456 bool UsedAssumedInformation = false;
4457 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4458 {Instruction::Ret}, UsedAssumedInformation);
4459
4460 auto PredForCallSite = [&](AbstractCallSite ACS) {
4461 if (ACS.isCallbackCall() || !ACS.getInstruction())
4462 return false;
4463 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4464 };
4465
4466 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4467 UsedAssumedInformation))
4468 return indicatePessimisticFixpoint();
4469
4470 return ChangeStatus::UNCHANGED;
4471 }
4472
4473 /// See AbstractAttribute::manifest(...).
4474 ChangeStatus manifest(Attributor &A) override {
4475 // TODO: Rewrite the signature to return void?
4476 bool AnyChange = false;
4477 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4478 auto RetInstPred = [&](Instruction &I) {
4479 ReturnInst &RI = cast<ReturnInst>(I);
4481 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4482 return true;
4483 };
4484 bool UsedAssumedInformation = false;
4485 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4486 UsedAssumedInformation);
4487 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4488 }
4489
4490 /// See AbstractAttribute::trackStatistics()
4491 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4492};
4493
4494struct AAIsDeadFunction : public AAIsDead {
4495 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4496
4497 /// See AbstractAttribute::initialize(...).
4498 void initialize(Attributor &A) override {
4499 Function *F = getAnchorScope();
4500 assert(F && "Did expect an anchor function");
4501 if (!isAssumedDeadInternalFunction(A)) {
4502 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4503 assumeLive(A, F->getEntryBlock());
4504 }
4505 }
4506
4507 bool isAssumedDeadInternalFunction(Attributor &A) {
4508 if (!getAnchorScope()->hasLocalLinkage())
4509 return false;
4510 bool UsedAssumedInformation = false;
4511 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4512 true, UsedAssumedInformation);
4513 }
4514
4515 /// See AbstractAttribute::getAsStr().
4516 const std::string getAsStr(Attributor *A) const override {
4517 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4518 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4519 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4520 std::to_string(KnownDeadEnds.size()) + "]";
4521 }
4522
4523 /// See AbstractAttribute::manifest(...).
4524 ChangeStatus manifest(Attributor &A) override {
4525 assert(getState().isValidState() &&
4526 "Attempted to manifest an invalid state!");
4527
4528 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4529 Function &F = *getAnchorScope();
4530
4531 if (AssumedLiveBlocks.empty()) {
4532 A.deleteAfterManifest(F);
4533 return ChangeStatus::CHANGED;
4534 }
4535
4536 // Flag to determine if we can change an invoke to a call assuming the
4537 // callee is nounwind. This is not possible if the personality of the
4538 // function allows to catch asynchronous exceptions.
4539 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4540
4541 KnownDeadEnds.set_union(ToBeExploredFrom);
4542 for (const Instruction *DeadEndI : KnownDeadEnds) {
4543 auto *CB = dyn_cast<CallBase>(DeadEndI);
4544 if (!CB)
4545 continue;
4546 bool IsKnownNoReturn;
4548 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4549 IsKnownNoReturn);
4550 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4551 continue;
4552
4553 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4554 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4555 else
4556 A.changeToUnreachableAfterManifest(
4557 const_cast<Instruction *>(DeadEndI->getNextNode()));
4558 HasChanged = ChangeStatus::CHANGED;
4559 }
4560
4561 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4562 for (BasicBlock &BB : F)
4563 if (!AssumedLiveBlocks.count(&BB)) {
4564 A.deleteAfterManifest(BB);
4565 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4566 HasChanged = ChangeStatus::CHANGED;
4567 }
4568
4569 return HasChanged;
4570 }
4571
4572 /// See AbstractAttribute::updateImpl(...).
4573 ChangeStatus updateImpl(Attributor &A) override;
4574
4575 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4576 assert(From->getParent() == getAnchorScope() &&
4577 To->getParent() == getAnchorScope() &&
4578 "Used AAIsDead of the wrong function");
4579 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4580 }
4581
4582 /// See AbstractAttribute::trackStatistics()
4583 void trackStatistics() const override {}
4584
4585 /// Returns true if the function is assumed dead.
4586 bool isAssumedDead() const override { return false; }
4587
4588 /// See AAIsDead::isKnownDead().
4589 bool isKnownDead() const override { return false; }
4590
4591 /// See AAIsDead::isAssumedDead(BasicBlock *).
4592 bool isAssumedDead(const BasicBlock *BB) const override {
4593 assert(BB->getParent() == getAnchorScope() &&
4594 "BB must be in the same anchor scope function.");
4595
4596 if (!getAssumed())
4597 return false;
4598 return !AssumedLiveBlocks.count(BB);
4599 }
4600
4601 /// See AAIsDead::isKnownDead(BasicBlock *).
4602 bool isKnownDead(const BasicBlock *BB) const override {
4603 return getKnown() && isAssumedDead(BB);
4604 }
4605
4606 /// See AAIsDead::isAssumed(Instruction *I).
4607 bool isAssumedDead(const Instruction *I) const override {
4608 assert(I->getParent()->getParent() == getAnchorScope() &&
4609 "Instruction must be in the same anchor scope function.");
4610
4611 if (!getAssumed())
4612 return false;
4613
4614 // If it is not in AssumedLiveBlocks then it for sure dead.
4615 // Otherwise, it can still be after noreturn call in a live block.
4616 if (!AssumedLiveBlocks.count(I->getParent()))
4617 return true;
4618
4619 // If it is not after a liveness barrier it is live.
4620 const Instruction *PrevI = I->getPrevNode();
4621 while (PrevI) {
4622 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4623 return true;
4624 PrevI = PrevI->getPrevNode();
4625 }
4626 return false;
4627 }
4628
4629 /// See AAIsDead::isKnownDead(Instruction *I).
4630 bool isKnownDead(const Instruction *I) const override {
4631 return getKnown() && isAssumedDead(I);
4632 }
4633
4634 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4635 /// that internal function called from \p BB should now be looked at.
4636 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4637 if (!AssumedLiveBlocks.insert(&BB).second)
4638 return false;
4639
4640 // We assume that all of BB is (probably) live now and if there are calls to
4641 // internal functions we will assume that those are now live as well. This
4642 // is a performance optimization for blocks with calls to a lot of internal
4643 // functions. It can however cause dead functions to be treated as live.
4644 for (const Instruction &I : BB)
4645 if (const auto *CB = dyn_cast<CallBase>(&I))
4647 if (F->hasLocalLinkage())
4648 A.markLiveInternalFunction(*F);
4649 return true;
4650 }
4651
4652 /// Collection of instructions that need to be explored again, e.g., we
4653 /// did assume they do not transfer control to (one of their) successors.
4654 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4655
4656 /// Collection of instructions that are known to not transfer control.
4657 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4658
4659 /// Collection of all assumed live edges
4660 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4661
4662 /// Collection of all assumed live BasicBlocks.
4663 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4664};
4665
4666static bool
4667identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4668 AbstractAttribute &AA,
4669 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4670 const IRPosition &IPos = IRPosition::callsite_function(CB);
4671
4672 bool IsKnownNoReturn;
4674 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4675 return !IsKnownNoReturn;
4676 if (CB.isTerminator())
4677 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4678 else
4679 AliveSuccessors.push_back(CB.getNextNode());
4680 return false;
4681}
4682
4683static bool
4684identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4685 AbstractAttribute &AA,
4686 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4687 bool UsedAssumedInformation =
4688 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4689
4690 // First, determine if we can change an invoke to a call assuming the
4691 // callee is nounwind. This is not possible if the personality of the
4692 // function allows to catch asynchronous exceptions.
4693 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4694 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4695 } else {
4696 const IRPosition &IPos = IRPosition::callsite_function(II);
4697
4698 bool IsKnownNoUnwind;
4700 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4701 UsedAssumedInformation |= !IsKnownNoUnwind;
4702 } else {
4703 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4704 }
4705 }
4706 return UsedAssumedInformation;
4707}
4708
4709static bool
4710identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4711 AbstractAttribute &,
4712 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4713 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4714 return false;
4715}
4716
4717static bool
4718identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4719 AbstractAttribute &AA,
4720 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4721 bool UsedAssumedInformation = false;
4722 std::optional<Constant *> C =
4723 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4724 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4725 // No value yet, assume both edges are dead.
4726 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4727 const BasicBlock *SuccBB =
4728 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4729 AliveSuccessors.push_back(&SuccBB->front());
4730 } else {
4731 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4732 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4733 UsedAssumedInformation = false;
4734 }
4735 return UsedAssumedInformation;
4736}
4737
4738static bool
4739identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4740 AbstractAttribute &AA,
4741 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4742 bool UsedAssumedInformation = false;
4744 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4745 Values, AA::AnyScope,
4746 UsedAssumedInformation)) {
4747 // Something went wrong, assume all successors are live.
4748 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4749 AliveSuccessors.push_back(&SuccBB->front());
4750 return false;
4751 }
4752
4753 if (Values.empty() ||
4754 (Values.size() == 1 &&
4755 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4756 // No valid value yet, assume all edges are dead.
4757 return UsedAssumedInformation;
4758 }
4759
4760 Type &Ty = *SI.getCondition()->getType();
4761 SmallPtrSet<ConstantInt *, 8> Constants;
4762 auto CheckForConstantInt = [&](Value *V) {
4763 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4764 Constants.insert(CI);
4765 return true;
4766 }
4767 return false;
4768 };
4769
4770 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4771 return CheckForConstantInt(VAC.getValue());
4772 })) {
4773 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4774 AliveSuccessors.push_back(&SuccBB->front());
4775 return UsedAssumedInformation;
4776 }
4777
4778 unsigned MatchedCases = 0;
4779 for (const auto &CaseIt : SI.cases()) {
4780 if (Constants.count(CaseIt.getCaseValue())) {
4781 ++MatchedCases;
4782 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4783 }
4784 }
4785
4786 // If all potential values have been matched, we will not visit the default
4787 // case.
4788 if (MatchedCases < Constants.size())
4789 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4790 return UsedAssumedInformation;
4791}
4792
4793ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4795
4796 if (AssumedLiveBlocks.empty()) {
4797 if (isAssumedDeadInternalFunction(A))
4799
4800 Function *F = getAnchorScope();
4801 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4802 assumeLive(A, F->getEntryBlock());
4803 Change = ChangeStatus::CHANGED;
4804 }
4805
4806 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4807 << getAnchorScope()->size() << "] BBs and "
4808 << ToBeExploredFrom.size() << " exploration points and "
4809 << KnownDeadEnds.size() << " known dead ends\n");
4810
4811 // Copy and clear the list of instructions we need to explore from. It is
4812 // refilled with instructions the next update has to look at.
4813 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4814 ToBeExploredFrom.end());
4815 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4816
4818 while (!Worklist.empty()) {
4819 const Instruction *I = Worklist.pop_back_val();
4820 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4821
4822 // Fast forward for uninteresting instructions. We could look for UB here
4823 // though.
4824 while (!I->isTerminator() && !isa<CallBase>(I))
4825 I = I->getNextNode();
4826
4827 AliveSuccessors.clear();
4828
4829 bool UsedAssumedInformation = false;
4830 switch (I->getOpcode()) {
4831 // TODO: look for (assumed) UB to backwards propagate "deadness".
4832 default:
4833 assert(I->isTerminator() &&
4834 "Expected non-terminators to be handled already!");
4835 for (const BasicBlock *SuccBB : successors(I->getParent()))
4836 AliveSuccessors.push_back(&SuccBB->front());
4837 break;
4838 case Instruction::Call:
4839 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4840 *this, AliveSuccessors);
4841 break;
4842 case Instruction::Invoke:
4843 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4844 *this, AliveSuccessors);
4845 break;
4846 case Instruction::UncondBr:
4847 UsedAssumedInformation = identifyAliveSuccessors(
4848 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4849 break;
4850 case Instruction::CondBr:
4851 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4852 *this, AliveSuccessors);
4853 break;
4854 case Instruction::Switch:
4855 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4856 *this, AliveSuccessors);
4857 break;
4858 }
4859
4860 if (UsedAssumedInformation) {
4861 NewToBeExploredFrom.insert(I);
4862 } else if (AliveSuccessors.empty() ||
4863 (I->isTerminator() &&
4864 AliveSuccessors.size() < I->getNumSuccessors())) {
4865 if (KnownDeadEnds.insert(I))
4866 Change = ChangeStatus::CHANGED;
4867 }
4868
4869 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4870 << AliveSuccessors.size() << " UsedAssumedInformation: "
4871 << UsedAssumedInformation << "\n");
4872
4873 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4874 if (!I->isTerminator()) {
4875 assert(AliveSuccessors.size() == 1 &&
4876 "Non-terminator expected to have a single successor!");
4877 Worklist.push_back(AliveSuccessor);
4878 } else {
4879 // record the assumed live edge
4880 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4881 if (AssumedLiveEdges.insert(Edge).second)
4882 Change = ChangeStatus::CHANGED;
4883 if (assumeLive(A, *AliveSuccessor->getParent()))
4884 Worklist.push_back(AliveSuccessor);
4885 }
4886 }
4887 }
4888
4889 // Check if the content of ToBeExploredFrom changed, ignore the order.
4890 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4891 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4892 return !ToBeExploredFrom.count(I);
4893 })) {
4894 Change = ChangeStatus::CHANGED;
4895 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4896 }
4897
4898 // If we know everything is live there is no need to query for liveness.
4899 // Instead, indicating a pessimistic fixpoint will cause the state to be
4900 // "invalid" and all queries to be answered conservatively without lookups.
4901 // To be in this state we have to (1) finished the exploration and (3) not
4902 // discovered any non-trivial dead end and (2) not ruled unreachable code
4903 // dead.
4904 if (ToBeExploredFrom.empty() &&
4905 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4906 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4907 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4908 }))
4909 return indicatePessimisticFixpoint();
4910 return Change;
4911}
4912
4913/// Liveness information for a call sites.
4914struct AAIsDeadCallSite final : AAIsDeadFunction {
4915 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4916 : AAIsDeadFunction(IRP, A) {}
4917
4918 /// See AbstractAttribute::initialize(...).
4919 void initialize(Attributor &A) override {
4920 // TODO: Once we have call site specific value information we can provide
4921 // call site specific liveness information and then it makes
4922 // sense to specialize attributes for call sites instead of
4923 // redirecting requests to the callee.
4924 llvm_unreachable("Abstract attributes for liveness are not "
4925 "supported for call sites yet!");
4926 }
4927
4928 /// See AbstractAttribute::updateImpl(...).
4929 ChangeStatus updateImpl(Attributor &A) override {
4930 return indicatePessimisticFixpoint();
4931 }
4932
4933 /// See AbstractAttribute::trackStatistics()
4934 void trackStatistics() const override {}
4935};
4936} // namespace
4937
4938/// -------------------- Dereferenceable Argument Attribute --------------------
4939
4940namespace {
4941struct AADereferenceableImpl : AADereferenceable {
4942 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4943 : AADereferenceable(IRP, A) {}
4944 using StateType = DerefState;
4945
4946 /// See AbstractAttribute::initialize(...).
4947 void initialize(Attributor &A) override {
4948 Value &V = *getAssociatedValue().stripPointerCasts();
4950 A.getAttrs(getIRPosition(),
4951 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4952 Attrs, /* IgnoreSubsumingPositions */ false);
4953 for (const Attribute &Attr : Attrs)
4954 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4955
4956 // Ensure we initialize the non-null AA (if necessary).
4957 bool IsKnownNonNull;
4959 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4960
4961 bool CanBeNull, CanBeFreed;
4962 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4963 A.getDataLayout(), CanBeNull, CanBeFreed));
4964
4965 if (Instruction *CtxI = getCtxI())
4966 followUsesInMBEC(*this, A, getState(), *CtxI);
4967 }
4968
4969 /// See AbstractAttribute::getState()
4970 /// {
4971 StateType &getState() override { return *this; }
4972 const StateType &getState() const override { return *this; }
4973 /// }
4974
4975 /// Helper function for collecting accessed bytes in must-be-executed-context
4976 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4977 DerefState &State) {
4978 const Value *UseV = U->get();
4979 if (!UseV->getType()->isPointerTy())
4980 return;
4981
4982 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4983 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4984 return;
4985
4986 int64_t Offset;
4988 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4989 if (Base && Base == &getAssociatedValue())
4990 State.addAccessedBytes(Offset, Loc->Size.getValue());
4991 }
4992
4993 /// See followUsesInMBEC
4994 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4995 AADereferenceable::StateType &State) {
4996 bool IsNonNull = false;
4997 bool TrackUse = false;
4998 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4999 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5000 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5001 << " for instruction " << *I << "\n");
5002
5003 addAccessedBytesForUse(A, U, I, State);
5004 State.takeKnownDerefBytesMaximum(DerefBytes);
5005 return TrackUse;
5006 }
5007
5008 /// See AbstractAttribute::manifest(...).
5009 ChangeStatus manifest(Attributor &A) override {
5010 ChangeStatus Change = AADereferenceable::manifest(A);
5011 bool IsKnownNonNull;
5012 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5013 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5014 if (IsAssumedNonNull &&
5015 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5016 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5017 return ChangeStatus::CHANGED;
5018 }
5019 return Change;
5020 }
5021
5022 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5023 SmallVectorImpl<Attribute> &Attrs) const override {
5024 // TODO: Add *_globally support
5025 bool IsKnownNonNull;
5026 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5027 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5028 if (IsAssumedNonNull)
5029 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5030 Ctx, getAssumedDereferenceableBytes()));
5031 else
5032 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5033 Ctx, getAssumedDereferenceableBytes()));
5034 }
5035
5036 /// See AbstractAttribute::getAsStr().
5037 const std::string getAsStr(Attributor *A) const override {
5038 if (!getAssumedDereferenceableBytes())
5039 return "unknown-dereferenceable";
5040 bool IsKnownNonNull;
5041 bool IsAssumedNonNull = false;
5042 if (A)
5044 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5045 return std::string("dereferenceable") +
5046 (IsAssumedNonNull ? "" : "_or_null") +
5047 (isAssumedGlobal() ? "_globally" : "") + "<" +
5048 std::to_string(getKnownDereferenceableBytes()) + "-" +
5049 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5050 (!A ? " [non-null is unknown]" : "");
5051 }
5052};
5053
5054/// Dereferenceable attribute for a floating value.
5055struct AADereferenceableFloating : AADereferenceableImpl {
5056 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5057 : AADereferenceableImpl(IRP, A) {}
5058
5059 /// See AbstractAttribute::updateImpl(...).
5060 ChangeStatus updateImpl(Attributor &A) override {
5061 bool Stripped;
5062 bool UsedAssumedInformation = false;
5064 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5065 AA::AnyScope, UsedAssumedInformation)) {
5066 Values.push_back({getAssociatedValue(), getCtxI()});
5067 Stripped = false;
5068 } else {
5069 Stripped = Values.size() != 1 ||
5070 Values.front().getValue() != &getAssociatedValue();
5071 }
5072
5073 const DataLayout &DL = A.getDataLayout();
5074 DerefState T;
5075
5076 auto VisitValueCB = [&](const Value &V) -> bool {
5077 unsigned IdxWidth =
5078 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5079 APInt Offset(IdxWidth, 0);
5081 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5082 /* AllowNonInbounds */ true);
5083
5084 const auto *AA = A.getAAFor<AADereferenceable>(
5085 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5086 int64_t DerefBytes = 0;
5087 if (!AA || (!Stripped && this == AA)) {
5088 // Use IR information if we did not strip anything.
5089 // TODO: track globally.
5090 bool CanBeNull, CanBeFreed;
5091 DerefBytes =
5092 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5093 T.GlobalState.indicatePessimisticFixpoint();
5094 } else {
5095 const DerefState &DS = AA->getState();
5096 DerefBytes = DS.DerefBytesState.getAssumed();
5097 T.GlobalState &= DS.GlobalState;
5098 }
5099
5100 // For now we do not try to "increase" dereferenceability due to negative
5101 // indices as we first have to come up with code to deal with loops and
5102 // for overflows of the dereferenceable bytes.
5103 int64_t OffsetSExt = Offset.getSExtValue();
5104 if (OffsetSExt < 0)
5105 OffsetSExt = 0;
5106
5107 T.takeAssumedDerefBytesMinimum(
5108 std::max(int64_t(0), DerefBytes - OffsetSExt));
5109
5110 if (this == AA) {
5111 if (!Stripped) {
5112 // If nothing was stripped IR information is all we got.
5113 T.takeKnownDerefBytesMaximum(
5114 std::max(int64_t(0), DerefBytes - OffsetSExt));
5115 T.indicatePessimisticFixpoint();
5116 } else if (OffsetSExt > 0) {
5117 // If something was stripped but there is circular reasoning we look
5118 // for the offset. If it is positive we basically decrease the
5119 // dereferenceable bytes in a circular loop now, which will simply
5120 // drive them down to the known value in a very slow way which we
5121 // can accelerate.
5122 T.indicatePessimisticFixpoint();
5123 }
5124 }
5125
5126 return T.isValidState();
5127 };
5128
5129 for (const auto &VAC : Values)
5130 if (!VisitValueCB(*VAC.getValue()))
5131 return indicatePessimisticFixpoint();
5132
5133 return clampStateAndIndicateChange(getState(), T);
5134 }
5135
5136 /// See AbstractAttribute::trackStatistics()
5137 void trackStatistics() const override {
5138 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5139 }
5140};
5141
5142/// Dereferenceable attribute for a return value.
5143struct AADereferenceableReturned final
5144 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5145 using Base =
5146 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5147 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5148 : Base(IRP, A) {}
5149
5150 /// See AbstractAttribute::trackStatistics()
5151 void trackStatistics() const override {
5152 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5153 }
5154};
5155
5156/// Dereferenceable attribute for an argument
5157struct AADereferenceableArgument final
5158 : AAArgumentFromCallSiteArguments<AADereferenceable,
5159 AADereferenceableImpl> {
5160 using Base =
5161 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5162 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5163 : Base(IRP, A) {}
5164
5165 /// See AbstractAttribute::trackStatistics()
5166 void trackStatistics() const override {
5167 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5168 }
5169};
5170
5171/// Dereferenceable attribute for a call site argument.
5172struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5173 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5174 : AADereferenceableFloating(IRP, A) {}
5175
5176 /// See AbstractAttribute::trackStatistics()
5177 void trackStatistics() const override {
5178 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5179 }
5180};
5181
5182/// Dereferenceable attribute deduction for a call site return value.
5183struct AADereferenceableCallSiteReturned final
5184 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5185 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5186 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5187 : Base(IRP, A) {}
5188
5189 /// See AbstractAttribute::trackStatistics()
5190 void trackStatistics() const override {
5191 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5192 }
5193};
5194} // namespace
5195
5196// ------------------------ Align Argument Attribute ------------------------
5197
5198namespace {
5199
5200static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5201 Value &AssociatedValue, const Use *U,
5202 const Instruction *I, bool &TrackUse) {
5203 // We need to follow common pointer manipulation uses to the accesses they
5204 // feed into.
5205 if (isa<CastInst>(I)) {
5206 // Follow all but ptr2int casts.
5207 TrackUse = !isa<PtrToIntInst>(I);
5208 return 0;
5209 }
5210 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5211 if (GEP->hasAllConstantIndices())
5212 TrackUse = true;
5213 return 0;
5214 }
5215 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5216 switch (II->getIntrinsicID()) {
5217 case Intrinsic::ptrmask: {
5218 // Is it appropriate to pull attribute in initialization?
5219 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5220 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5221 const auto *AlignAA = A.getAAFor<AAAlign>(
5222 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5223 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5224 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5226 Align ConstAlign(UINT64_C(1) << ShiftValue);
5227 if (ConstAlign >= AlignAA->getKnownAlign())
5228 return Align(1).value();
5229 }
5230 if (AlignAA)
5231 return AlignAA->getKnownAlign().value();
5232 break;
5233 }
5234 case Intrinsic::amdgcn_make_buffer_rsrc: {
5235 const auto *AlignAA = A.getAAFor<AAAlign>(
5236 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5237 if (AlignAA)
5238 return AlignAA->getKnownAlign().value();
5239 break;
5240 }
5241 default:
5242 break;
5243 }
5244
5245 MaybeAlign MA;
5246 if (const auto *CB = dyn_cast<CallBase>(I)) {
5247 if (CB->isBundleOperand(U) || CB->isCallee(U))
5248 return 0;
5249
5250 unsigned ArgNo = CB->getArgOperandNo(U);
5251 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5252 // As long as we only use known information there is no need to track
5253 // dependences here.
5254 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5255 if (AlignAA)
5256 MA = MaybeAlign(AlignAA->getKnownAlign());
5257 }
5258
5259 const DataLayout &DL = A.getDataLayout();
5260 const Value *UseV = U->get();
5261 if (auto *SI = dyn_cast<StoreInst>(I)) {
5262 if (SI->getPointerOperand() == UseV)
5263 MA = SI->getAlign();
5264 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5265 if (LI->getPointerOperand() == UseV)
5266 MA = LI->getAlign();
5267 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5268 if (AI->getPointerOperand() == UseV)
5269 MA = AI->getAlign();
5270 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5271 if (AI->getPointerOperand() == UseV)
5272 MA = AI->getAlign();
5273 }
5274
5275 if (!MA || *MA <= QueryingAA.getKnownAlign())
5276 return 0;
5277
5278 unsigned Alignment = MA->value();
5279 int64_t Offset;
5280
5281 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5282 if (Base == &AssociatedValue) {
5283 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5284 // So we can say that the maximum power of two which is a divisor of
5285 // gcd(Offset, Alignment) is an alignment.
5286
5287 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5288 Alignment = llvm::bit_floor(gcd);
5289 }
5290 }
5291
5292 return Alignment;
5293}
5294
5295struct AAAlignImpl : AAAlign {
5296 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5297
5298 /// See AbstractAttribute::initialize(...).
5299 void initialize(Attributor &A) override {
5301 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5302 for (const Attribute &Attr : Attrs)
5303 takeKnownMaximum(Attr.getValueAsInt());
5304
5305 Value &V = *getAssociatedValue().stripPointerCasts();
5306 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5307
5308 if (Instruction *CtxI = getCtxI())
5309 followUsesInMBEC(*this, A, getState(), *CtxI);
5310 }
5311
5312 /// See AbstractAttribute::manifest(...).
5313 ChangeStatus manifest(Attributor &A) override {
5314 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5315
5316 // Check for users that allow alignment annotations.
5317 Value &AssociatedValue = getAssociatedValue();
5318 if (isa<ConstantData>(AssociatedValue))
5319 return ChangeStatus::UNCHANGED;
5320
5321 for (const Use &U : AssociatedValue.uses()) {
5322 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5323 if (SI->getPointerOperand() == &AssociatedValue)
5324 if (SI->getAlign() < getAssumedAlign()) {
5325 STATS_DECLTRACK(AAAlign, Store,
5326 "Number of times alignment added to a store");
5327 SI->setAlignment(getAssumedAlign());
5328 InstrChanged = ChangeStatus::CHANGED;
5329 }
5330 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5331 if (LI->getPointerOperand() == &AssociatedValue)
5332 if (LI->getAlign() < getAssumedAlign()) {
5333 LI->setAlignment(getAssumedAlign());
5334 STATS_DECLTRACK(AAAlign, Load,
5335 "Number of times alignment added to a load");
5336 InstrChanged = ChangeStatus::CHANGED;
5337 }
5338 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5339 if (RMW->getPointerOperand() == &AssociatedValue) {
5340 if (RMW->getAlign() < getAssumedAlign()) {
5341 STATS_DECLTRACK(AAAlign, AtomicRMW,
5342 "Number of times alignment added to atomicrmw");
5343
5344 RMW->setAlignment(getAssumedAlign());
5345 InstrChanged = ChangeStatus::CHANGED;
5346 }
5347 }
5348 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5349 if (CAS->getPointerOperand() == &AssociatedValue) {
5350 if (CAS->getAlign() < getAssumedAlign()) {
5351 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5352 "Number of times alignment added to cmpxchg");
5353 CAS->setAlignment(getAssumedAlign());
5354 InstrChanged = ChangeStatus::CHANGED;
5355 }
5356 }
5357 }
5358 }
5359
5360 ChangeStatus Changed = AAAlign::manifest(A);
5361
5362 Align InheritAlign =
5363 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5364 if (InheritAlign >= getAssumedAlign())
5365 return InstrChanged;
5366 return Changed | InstrChanged;
5367 }
5368
5369 // TODO: Provide a helper to determine the implied ABI alignment and check in
5370 // the existing manifest method and a new one for AAAlignImpl that value
5371 // to avoid making the alignment explicit if it did not improve.
5372
5373 /// See AbstractAttribute::getDeducedAttributes
5374 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5375 SmallVectorImpl<Attribute> &Attrs) const override {
5376 if (getAssumedAlign() > 1)
5377 Attrs.emplace_back(
5378 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5379 }
5380
5381 /// See followUsesInMBEC
5382 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5383 AAAlign::StateType &State) {
5384 bool TrackUse = false;
5385
5386 unsigned int KnownAlign =
5387 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5388 State.takeKnownMaximum(KnownAlign);
5389
5390 return TrackUse;
5391 }
5392
5393 /// See AbstractAttribute::getAsStr().
5394 const std::string getAsStr(Attributor *A) const override {
5395 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5396 std::to_string(getAssumedAlign().value()) + ">";
5397 }
5398};
5399
5400/// Align attribute for a floating value.
5401struct AAAlignFloating : AAAlignImpl {
5402 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5403
5404 /// See AbstractAttribute::updateImpl(...).
5405 ChangeStatus updateImpl(Attributor &A) override {
5406 const DataLayout &DL = A.getDataLayout();
5407
5408 bool Stripped;
5409 bool UsedAssumedInformation = false;
5411 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5412 AA::AnyScope, UsedAssumedInformation)) {
5413 Values.push_back({getAssociatedValue(), getCtxI()});
5414 Stripped = false;
5415 } else {
5416 Stripped = Values.size() != 1 ||
5417 Values.front().getValue() != &getAssociatedValue();
5418 }
5419
5420 StateType T;
5421 auto VisitValueCB = [&](Value &V) -> bool {
5423 return true;
5424 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5425 DepClassTy::REQUIRED);
5426 if (!AA || (!Stripped && this == AA)) {
5427 int64_t Offset;
5428 unsigned Alignment = 1;
5429 if (const Value *Base =
5431 // TODO: Use AAAlign for the base too.
5432 Align PA = Base->getPointerAlignment(DL);
5433 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5434 // So we can say that the maximum power of two which is a divisor of
5435 // gcd(Offset, Alignment) is an alignment.
5436
5437 uint32_t gcd =
5438 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5439 Alignment = llvm::bit_floor(gcd);
5440 } else {
5441 Alignment = V.getPointerAlignment(DL).value();
5442 }
5443 // Use only IR information if we did not strip anything.
5444 T.takeKnownMaximum(Alignment);
5445 T.indicatePessimisticFixpoint();
5446 } else {
5447 // Use abstract attribute information.
5448 const AAAlign::StateType &DS = AA->getState();
5449 T ^= DS;
5450 }
5451 return T.isValidState();
5452 };
5453
5454 for (const auto &VAC : Values) {
5455 if (!VisitValueCB(*VAC.getValue()))
5456 return indicatePessimisticFixpoint();
5457 }
5458
5459 // TODO: If we know we visited all incoming values, thus no are assumed
5460 // dead, we can take the known information from the state T.
5461 return clampStateAndIndicateChange(getState(), T);
5462 }
5463
5464 /// See AbstractAttribute::trackStatistics()
5465 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5466};
5467
5468/// Align attribute for function return value.
5469struct AAAlignReturned final
5470 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5471 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5472 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5473
5474 /// See AbstractAttribute::trackStatistics()
5475 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5476};
5477
5478/// Align attribute for function argument.
5479struct AAAlignArgument final
5480 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5481 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5482 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5483
5484 /// See AbstractAttribute::manifest(...).
5485 ChangeStatus manifest(Attributor &A) override {
5486 // If the associated argument is involved in a must-tail call we give up
5487 // because we would need to keep the argument alignments of caller and
5488 // callee in-sync. Just does not seem worth the trouble right now.
5489 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5490 return ChangeStatus::UNCHANGED;
5491 return Base::manifest(A);
5492 }
5493
5494 /// See AbstractAttribute::trackStatistics()
5495 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5496};
5497
5498struct AAAlignCallSiteArgument final : AAAlignFloating {
5499 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5500 : AAAlignFloating(IRP, A) {}
5501
5502 /// See AbstractAttribute::manifest(...).
5503 ChangeStatus manifest(Attributor &A) override {
5504 // If the associated argument is involved in a must-tail call we give up
5505 // because we would need to keep the argument alignments of caller and
5506 // callee in-sync. Just does not seem worth the trouble right now.
5507 if (Argument *Arg = getAssociatedArgument())
5508 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5509 return ChangeStatus::UNCHANGED;
5510 ChangeStatus Changed = AAAlignImpl::manifest(A);
5511 Align InheritAlign =
5512 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5513 if (InheritAlign >= getAssumedAlign())
5514 Changed = ChangeStatus::UNCHANGED;
5515 return Changed;
5516 }
5517
5518 /// See AbstractAttribute::updateImpl(Attributor &A).
5519 ChangeStatus updateImpl(Attributor &A) override {
5520 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5521 if (Argument *Arg = getAssociatedArgument()) {
5522 // We only take known information from the argument
5523 // so we do not need to track a dependence.
5524 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5525 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5526 if (ArgAlignAA)
5527 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5528 }
5529 return Changed;
5530 }
5531
5532 /// See AbstractAttribute::trackStatistics()
5533 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5534};
5535
5536/// Align attribute deduction for a call site return value.
5537struct AAAlignCallSiteReturned final
5538 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5539 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5540 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5541 : Base(IRP, A) {}
5542
5543 ChangeStatus updateImpl(Attributor &A) override {
5544 Instruction *I = getIRPosition().getCtxI();
5545 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5546 switch (II->getIntrinsicID()) {
5547 case Intrinsic::ptrmask: {
5548 Align Alignment;
5549 bool Valid = false;
5550
5551 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5552 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5553 if (ConstVals && ConstVals->isValidState()) {
5554 unsigned ShiftValue =
5555 std::min(ConstVals->getAssumedMinTrailingZeros(),
5556 Value::MaxAlignmentExponent);
5557 Alignment = Align(UINT64_C(1) << ShiftValue);
5558 Valid = true;
5559 }
5560
5561 const auto *AlignAA =
5562 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5563 DepClassTy::REQUIRED);
5564 if (AlignAA) {
5565 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5566 Valid = true;
5567 }
5568
5569 if (Valid)
5571 this->getState(),
5572 std::min(this->getAssumedAlign(), Alignment).value());
5573 break;
5574 }
5575 // FIXME: Should introduce target specific sub-attributes and letting
5576 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5577 // specific intrinsics.
5578 case Intrinsic::amdgcn_make_buffer_rsrc: {
5579 const auto *AlignAA =
5580 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5581 DepClassTy::REQUIRED);
5582 if (AlignAA)
5584 this->getState(), AlignAA->getAssumedAlign().value());
5585 break;
5586 }
5587 default:
5588 break;
5589 }
5590 }
5591 return Base::updateImpl(A);
5592 };
5593 /// See AbstractAttribute::trackStatistics()
5594 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5595};
5596} // namespace
5597
5598/// ------------------ Function No-Return Attribute ----------------------------
5599namespace {
5600struct AANoReturnImpl : public AANoReturn {
5601 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5602
5603 /// See AbstractAttribute::initialize(...).
5604 void initialize(Attributor &A) override {
5605 bool IsKnown;
5607 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5608 (void)IsKnown;
5609 }
5610
5611 /// See AbstractAttribute::getAsStr().
5612 const std::string getAsStr(Attributor *A) const override {
5613 return getAssumed() ? "noreturn" : "may-return";
5614 }
5615
5616 /// See AbstractAttribute::updateImpl(Attributor &A).
5617 ChangeStatus updateImpl(Attributor &A) override {
5618 auto CheckForNoReturn = [](Instruction &) { return false; };
5619 bool UsedAssumedInformation = false;
5620 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5621 {(unsigned)Instruction::Ret},
5622 UsedAssumedInformation))
5623 return indicatePessimisticFixpoint();
5624 return ChangeStatus::UNCHANGED;
5625 }
5626};
5627
5628struct AANoReturnFunction final : AANoReturnImpl {
5629 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5630 : AANoReturnImpl(IRP, A) {}
5631
5632 /// See AbstractAttribute::trackStatistics()
5633 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5634};
5635
5636/// NoReturn attribute deduction for a call sites.
5637struct AANoReturnCallSite final
5638 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5639 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5640 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5641
5642 /// See AbstractAttribute::trackStatistics()
5643 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5644};
5645} // namespace
5646
5647/// ----------------------- Instance Info ---------------------------------
5648
5649namespace {
5650/// A class to hold the state of for no-capture attributes.
5651struct AAInstanceInfoImpl : public AAInstanceInfo {
5652 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5653 : AAInstanceInfo(IRP, A) {}
5654
5655 /// See AbstractAttribute::initialize(...).
5656 void initialize(Attributor &A) override {
5657 Value &V = getAssociatedValue();
5658 if (auto *C = dyn_cast<Constant>(&V)) {
5659 if (C->isThreadDependent())
5660 indicatePessimisticFixpoint();
5661 else
5662 indicateOptimisticFixpoint();
5663 return;
5664 }
5665 if (auto *CB = dyn_cast<CallBase>(&V))
5666 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5667 !CB->mayReadFromMemory()) {
5668 indicateOptimisticFixpoint();
5669 return;
5670 }
5671 if (auto *I = dyn_cast<Instruction>(&V)) {
5672 const auto *CI =
5673 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5674 *I->getFunction());
5675 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5676 indicatePessimisticFixpoint();
5677 return;
5678 }
5679 }
5680 }
5681
5682 /// See AbstractAttribute::updateImpl(...).
5683 ChangeStatus updateImpl(Attributor &A) override {
5684 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5685
5686 Value &V = getAssociatedValue();
5687 const Function *Scope = nullptr;
5688 if (auto *I = dyn_cast<Instruction>(&V))
5689 Scope = I->getFunction();
5690 if (auto *A = dyn_cast<Argument>(&V)) {
5691 Scope = A->getParent();
5692 if (!Scope->hasLocalLinkage())
5693 return Changed;
5694 }
5695 if (!Scope)
5696 return indicateOptimisticFixpoint();
5697
5698 bool IsKnownNoRecurse;
5700 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5701 IsKnownNoRecurse))
5702 return Changed;
5703
5704 auto UsePred = [&](const Use &U, bool &Follow) {
5705 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5706 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5707 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5708 Follow = true;
5709 return true;
5710 }
5711 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5712 (isa<StoreInst>(UserI) &&
5713 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5714 return true;
5715 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5716 // This check is not guaranteeing uniqueness but for now that we cannot
5717 // end up with two versions of \p U thinking it was one.
5719 if (!Callee || !Callee->hasLocalLinkage())
5720 return true;
5721 if (!CB->isArgOperand(&U))
5722 return false;
5723 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5725 DepClassTy::OPTIONAL);
5726 if (!ArgInstanceInfoAA ||
5727 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5728 return false;
5729 // If this call base might reach the scope again we might forward the
5730 // argument back here. This is very conservative.
5732 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5733 [Scope](const Function &Fn) { return &Fn != Scope; }))
5734 return false;
5735 return true;
5736 }
5737 return false;
5738 };
5739
5740 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5741 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5742 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5743 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5744 AA::isDynamicallyUnique(A, *this, *Ptr))
5745 return true;
5746 }
5747 return false;
5748 };
5749
5750 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5751 DepClassTy::OPTIONAL,
5752 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5753 return indicatePessimisticFixpoint();
5754
5755 return Changed;
5756 }
5757
5758 /// See AbstractState::getAsStr().
5759 const std::string getAsStr(Attributor *A) const override {
5760 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5761 }
5762
5763 /// See AbstractAttribute::trackStatistics()
5764 void trackStatistics() const override {}
5765};
5766
5767/// InstanceInfo attribute for floating values.
5768struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5769 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5770 : AAInstanceInfoImpl(IRP, A) {}
5771};
5772
5773/// NoCapture attribute for function arguments.
5774struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5775 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5776 : AAInstanceInfoFloating(IRP, A) {}
5777};
5778
5779/// InstanceInfo attribute for call site arguments.
5780struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5781 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5782 : AAInstanceInfoImpl(IRP, A) {}
5783
5784 /// See AbstractAttribute::updateImpl(...).
5785 ChangeStatus updateImpl(Attributor &A) override {
5786 // TODO: Once we have call site specific value information we can provide
5787 // call site specific liveness information and then it makes
5788 // sense to specialize attributes for call sites arguments instead of
5789 // redirecting requests to the callee argument.
5790 Argument *Arg = getAssociatedArgument();
5791 if (!Arg)
5792 return indicatePessimisticFixpoint();
5793 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5794 auto *ArgAA =
5795 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5796 if (!ArgAA)
5797 return indicatePessimisticFixpoint();
5798 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5799 }
5800};
5801
5802/// InstanceInfo attribute for function return value.
5803struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5804 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5805 : AAInstanceInfoImpl(IRP, A) {
5806 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5807 }
5808
5809 /// See AbstractAttribute::initialize(...).
5810 void initialize(Attributor &A) override {
5811 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5812 }
5813
5814 /// See AbstractAttribute::updateImpl(...).
5815 ChangeStatus updateImpl(Attributor &A) override {
5816 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5817 }
5818};
5819
5820/// InstanceInfo attribute deduction for a call site return value.
5821struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5822 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5823 : AAInstanceInfoFloating(IRP, A) {}
5824};
5825} // namespace
5826
5827/// ----------------------- Variable Capturing ---------------------------------
5829 Attribute::AttrKind ImpliedAttributeKind,
5830 bool IgnoreSubsumingPositions) {
5831 assert(ImpliedAttributeKind == Attribute::Captures &&
5832 "Unexpected attribute kind");
5833 Value &V = IRP.getAssociatedValue();
5834 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5835 return V.use_empty();
5836
5837 // You cannot "capture" null in the default address space.
5838 //
5839 // FIXME: This should use NullPointerIsDefined to account for the function
5840 // attribute.
5842 V.getType()->getPointerAddressSpace() == 0)) {
5843 return true;
5844 }
5845
5847 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5848 /* IgnoreSubsumingPositions */ true);
5849 for (const Attribute &Attr : Attrs)
5850 if (capturesNothing(Attr.getCaptureInfo()))
5851 return true;
5852
5854 if (Argument *Arg = IRP.getAssociatedArgument()) {
5856 A.getAttrs(IRPosition::argument(*Arg),
5857 {Attribute::Captures, Attribute::ByVal}, Attrs,
5858 /* IgnoreSubsumingPositions */ true);
5859 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5860 return Attr.getKindAsEnum() == Attribute::ByVal ||
5862 });
5863 if (ArgNoCapture) {
5864 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5865 V.getContext(), CaptureInfo::none()));
5866 return true;
5867 }
5868 }
5869
5870 if (const Function *F = IRP.getAssociatedFunction()) {
5871 // Check what state the associated function can actually capture.
5874 if (State.isKnown(NO_CAPTURE)) {
5875 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5877 return true;
5878 }
5879 }
5880
5881 return false;
5882}
5883
5884/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5885/// depending on the ability of the function associated with \p IRP to capture
5886/// state in memory and through "returning/throwing", respectively.
5888 const Function &F,
5889 BitIntegerState &State) {
5890 // TODO: Once we have memory behavior attributes we should use them here.
5891
5892 // If we know we cannot communicate or write to memory, we do not care about
5893 // ptr2int anymore.
5894 bool ReadOnly = F.onlyReadsMemory();
5895 bool NoThrow = F.doesNotThrow();
5896 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5897 if (ReadOnly && NoThrow && IsVoidReturn) {
5898 State.addKnownBits(NO_CAPTURE);
5899 return;
5900 }
5901
5902 // A function cannot capture state in memory if it only reads memory, it can
5903 // however return/throw state and the state might be influenced by the
5904 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5905 if (ReadOnly)
5906 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5907
5908 // A function cannot communicate state back if it does not through
5909 // exceptions and doesn not return values.
5910 if (NoThrow && IsVoidReturn)
5911 State.addKnownBits(NOT_CAPTURED_IN_RET);
5912
5913 // Check existing "returned" attributes.
5914 int ArgNo = IRP.getCalleeArgNo();
5915 if (!NoThrow || ArgNo < 0 ||
5916 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5917 return;
5918
5919 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5920 if (F.hasParamAttribute(U, Attribute::Returned)) {
5921 if (U == unsigned(ArgNo))
5922 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5923 else if (ReadOnly)
5924 State.addKnownBits(NO_CAPTURE);
5925 else
5926 State.addKnownBits(NOT_CAPTURED_IN_RET);
5927 break;
5928 }
5929}
5930
5931namespace {
5932/// A class to hold the state of for no-capture attributes.
5933struct AANoCaptureImpl : public AANoCapture {
5934 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5935
5936 /// See AbstractAttribute::initialize(...).
5937 void initialize(Attributor &A) override {
5938 bool IsKnown;
5940 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5941 (void)IsKnown;
5942 }
5943
5944 /// See AbstractAttribute::updateImpl(...).
5945 ChangeStatus updateImpl(Attributor &A) override;
5946
5947 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5948 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5949 SmallVectorImpl<Attribute> &Attrs) const override {
5950 if (!isAssumedNoCaptureMaybeReturned())
5951 return;
5952
5953 if (isArgumentPosition()) {
5954 if (isAssumedNoCapture())
5955 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5956 else if (ManifestInternal)
5957 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5958 }
5959 }
5960
5961 /// See AbstractState::getAsStr().
5962 const std::string getAsStr(Attributor *A) const override {
5963 if (isKnownNoCapture())
5964 return "known not-captured";
5965 if (isAssumedNoCapture())
5966 return "assumed not-captured";
5967 if (isKnownNoCaptureMaybeReturned())
5968 return "known not-captured-maybe-returned";
5969 if (isAssumedNoCaptureMaybeReturned())
5970 return "assumed not-captured-maybe-returned";
5971 return "assumed-captured";
5972 }
5973
5974 /// Check the use \p U and update \p State accordingly. Return true if we
5975 /// should continue to update the state.
5976 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5977 bool &Follow) {
5978 Instruction *UInst = cast<Instruction>(U.getUser());
5979 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5980 << *UInst << "\n");
5981
5982 // Deal with ptr2int by following uses.
5983 if (isa<PtrToIntInst>(UInst)) {
5984 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5985 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5986 /* Return */ true);
5987 }
5988
5989 // For stores we already checked if we can follow them, if they make it
5990 // here we give up.
5991 if (isa<StoreInst>(UInst))
5992 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5993 /* Return */ true);
5994
5995 // Explicitly catch return instructions.
5996 if (isa<ReturnInst>(UInst)) {
5997 if (UInst->getFunction() == getAnchorScope())
5998 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5999 /* Return */ true);
6000 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6001 /* Return */ true);
6002 }
6003
6004 // For now we only use special logic for call sites. However, the tracker
6005 // itself knows about a lot of other non-capturing cases already.
6006 auto *CB = dyn_cast<CallBase>(UInst);
6007 if (!CB || !CB->isArgOperand(&U))
6008 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6009 /* Return */ true);
6010
6011 unsigned ArgNo = CB->getArgOperandNo(&U);
6012 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6013 // If we have a abstract no-capture attribute for the argument we can use
6014 // it to justify a non-capture attribute here. This allows recursion!
6015 bool IsKnownNoCapture;
6016 const AANoCapture *ArgNoCaptureAA = nullptr;
6017 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6018 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6019 &ArgNoCaptureAA);
6020 if (IsAssumedNoCapture)
6021 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6022 /* Return */ false);
6023 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6024 Follow = true;
6025 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6026 /* Return */ false);
6027 }
6028
6029 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6030 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6031 /* Return */ true);
6032 }
6033
6034 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6035 /// \p CapturedInRet, then return true if we should continue updating the
6036 /// state.
6037 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6038 bool CapturedInInt, bool CapturedInRet) {
6039 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6040 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6041 if (CapturedInMem)
6042 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6043 if (CapturedInInt)
6044 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6045 if (CapturedInRet)
6046 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6047 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6048 }
6049};
6050
6051ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6052 const IRPosition &IRP = getIRPosition();
6053 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6054 : &IRP.getAssociatedValue();
6055 if (!V)
6056 return indicatePessimisticFixpoint();
6057
6058 const Function *F =
6059 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6060
6061 // TODO: Is the checkForAllUses below useful for constants?
6062 if (!F)
6063 return indicatePessimisticFixpoint();
6064
6066 const IRPosition &FnPos = IRPosition::function(*F);
6067
6068 // Readonly means we cannot capture through memory.
6069 bool IsKnown;
6070 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6071 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6072 if (IsKnown)
6073 addKnownBits(NOT_CAPTURED_IN_MEM);
6074 }
6075
6076 // Make sure all returned values are different than the underlying value.
6077 // TODO: we could do this in a more sophisticated way inside
6078 // AAReturnedValues, e.g., track all values that escape through returns
6079 // directly somehow.
6080 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6082 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6084 UsedAssumedInformation))
6085 return false;
6086 bool SeenConstant = false;
6087 for (const AA::ValueAndContext &VAC : Values) {
6088 if (isa<Constant>(VAC.getValue())) {
6089 if (SeenConstant)
6090 return false;
6091 SeenConstant = true;
6092 } else if (!isa<Argument>(VAC.getValue()) ||
6093 VAC.getValue() == getAssociatedArgument())
6094 return false;
6095 }
6096 return true;
6097 };
6098
6099 bool IsKnownNoUnwind;
6101 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6102 bool IsVoidTy = F->getReturnType()->isVoidTy();
6103 bool UsedAssumedInformation = false;
6104 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6105 T.addKnownBits(NOT_CAPTURED_IN_RET);
6106 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6108 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6109 addKnownBits(NOT_CAPTURED_IN_RET);
6110 if (isKnown(NOT_CAPTURED_IN_MEM))
6111 return indicateOptimisticFixpoint();
6112 }
6113 }
6114 }
6115
6116 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6117 // TODO(captures): Make this more precise.
6118 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6119 if (capturesNothing(CI))
6120 return true;
6121 if (CI.isPassthrough()) {
6122 Follow = true;
6123 return true;
6124 }
6125 return checkUse(A, T, U, Follow);
6126 };
6127
6128 if (!A.checkForAllUses(UseCheck, *this, *V))
6129 return indicatePessimisticFixpoint();
6130
6131 AANoCapture::StateType &S = getState();
6132 auto Assumed = S.getAssumed();
6133 S.intersectAssumedBits(T.getAssumed());
6134 if (!isAssumedNoCaptureMaybeReturned())
6135 return indicatePessimisticFixpoint();
6136 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6138}
6139
6140/// NoCapture attribute for function arguments.
6141struct AANoCaptureArgument final : AANoCaptureImpl {
6142 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6143 : AANoCaptureImpl(IRP, A) {}
6144
6145 /// See AbstractAttribute::trackStatistics()
6146 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6147};
6148
6149/// NoCapture attribute for call site arguments.
6150struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6151 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6152 : AANoCaptureImpl(IRP, A) {}
6153
6154 /// See AbstractAttribute::updateImpl(...).
6155 ChangeStatus updateImpl(Attributor &A) override {
6156 // TODO: Once we have call site specific value information we can provide
6157 // call site specific liveness information and then it makes
6158 // sense to specialize attributes for call sites arguments instead of
6159 // redirecting requests to the callee argument.
6160 Argument *Arg = getAssociatedArgument();
6161 if (!Arg)
6162 return indicatePessimisticFixpoint();
6163 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6164 bool IsKnownNoCapture;
6165 const AANoCapture *ArgAA = nullptr;
6167 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6168 &ArgAA))
6169 return ChangeStatus::UNCHANGED;
6170 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6171 return indicatePessimisticFixpoint();
6172 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6173 }
6174
6175 /// See AbstractAttribute::trackStatistics()
6176 void trackStatistics() const override {
6178 };
6179};
6180
6181/// NoCapture attribute for floating values.
6182struct AANoCaptureFloating final : AANoCaptureImpl {
6183 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6184 : AANoCaptureImpl(IRP, A) {}
6185
6186 /// See AbstractAttribute::trackStatistics()
6187 void trackStatistics() const override {
6189 }
6190};
6191
6192/// NoCapture attribute for function return value.
6193struct AANoCaptureReturned final : AANoCaptureImpl {
6194 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6195 : AANoCaptureImpl(IRP, A) {
6196 llvm_unreachable("NoCapture is not applicable to function returns!");
6197 }
6198
6199 /// See AbstractAttribute::initialize(...).
6200 void initialize(Attributor &A) override {
6201 llvm_unreachable("NoCapture is not applicable to function returns!");
6202 }
6203
6204 /// See AbstractAttribute::updateImpl(...).
6205 ChangeStatus updateImpl(Attributor &A) override {
6206 llvm_unreachable("NoCapture is not applicable to function returns!");
6207 }
6208
6209 /// See AbstractAttribute::trackStatistics()
6210 void trackStatistics() const override {}
6211};
6212
6213/// NoCapture attribute deduction for a call site return value.
6214struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6215 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6216 : AANoCaptureImpl(IRP, A) {}
6217
6218 /// See AbstractAttribute::initialize(...).
6219 void initialize(Attributor &A) override {
6220 const Function *F = getAnchorScope();
6221 // Check what state the associated function can actually capture.
6222 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6223 }
6224
6225 /// See AbstractAttribute::trackStatistics()
6226 void trackStatistics() const override {
6228 }
6229};
6230} // namespace
6231
6232/// ------------------ Value Simplify Attribute ----------------------------
6233
6234bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6235 // FIXME: Add a typecast support.
6238 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6239 return false;
6240
6241 LLVM_DEBUG({
6243 dbgs() << "[ValueSimplify] is assumed to be "
6244 << **SimplifiedAssociatedValue << "\n";
6245 else
6246 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6247 });
6248 return true;
6249}
6250
6251namespace {
6252struct AAValueSimplifyImpl : AAValueSimplify {
6253 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6254 : AAValueSimplify(IRP, A) {}
6255
6256 /// See AbstractAttribute::initialize(...).
6257 void initialize(Attributor &A) override {
6258 if (getAssociatedValue().getType()->isVoidTy())
6259 indicatePessimisticFixpoint();
6260 if (A.hasSimplificationCallback(getIRPosition()))
6261 indicatePessimisticFixpoint();
6262 }
6263
6264 /// See AbstractAttribute::getAsStr().
6265 const std::string getAsStr(Attributor *A) const override {
6266 LLVM_DEBUG({
6267 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6268 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6269 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6270 });
6271 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6272 : "not-simple";
6273 }
6274
6275 /// See AbstractAttribute::trackStatistics()
6276 void trackStatistics() const override {}
6277
6278 /// See AAValueSimplify::getAssumedSimplifiedValue()
6279 std::optional<Value *>
6280 getAssumedSimplifiedValue(Attributor &A) const override {
6281 return SimplifiedAssociatedValue;
6282 }
6283
6284 /// Ensure the return value is \p V with type \p Ty, if not possible return
6285 /// nullptr. If \p Check is true we will only verify such an operation would
6286 /// suceed and return a non-nullptr value if that is the case. No IR is
6287 /// generated or modified.
6288 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6289 bool Check) {
6290 if (auto *TypedV = AA::getWithType(V, Ty))
6291 return TypedV;
6292 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6293 return Check ? &V
6294 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6295 &V, &Ty, "", CtxI->getIterator());
6296 return nullptr;
6297 }
6298
6299 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6300 /// If \p Check is true we will only verify such an operation would suceed and
6301 /// return a non-nullptr value if that is the case. No IR is generated or
6302 /// modified.
6303 static Value *reproduceInst(Attributor &A,
6304 const AbstractAttribute &QueryingAA,
6305 Instruction &I, Type &Ty, Instruction *CtxI,
6306 bool Check, ValueToValueMapTy &VMap) {
6307 assert(CtxI && "Cannot reproduce an instruction without context!");
6308 if (Check && (I.mayReadFromMemory() ||
6309 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6310 /* TLI */ nullptr)))
6311 return nullptr;
6312 for (Value *Op : I.operands()) {
6313 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6314 if (!NewOp) {
6315 assert(Check && "Manifest of new value unexpectedly failed!");
6316 return nullptr;
6317 }
6318 if (!Check)
6319 VMap[Op] = NewOp;
6320 }
6321 if (Check)
6322 return &I;
6323
6324 Instruction *CloneI = I.clone();
6325 // TODO: Try to salvage debug information here.
6326 CloneI->setDebugLoc(DebugLoc());
6327 VMap[&I] = CloneI;
6328 CloneI->insertBefore(CtxI->getIterator());
6329 RemapInstruction(CloneI, VMap);
6330 return CloneI;
6331 }
6332
6333 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6334 /// If \p Check is true we will only verify such an operation would suceed and
6335 /// return a non-nullptr value if that is the case. No IR is generated or
6336 /// modified.
6337 static Value *reproduceValue(Attributor &A,
6338 const AbstractAttribute &QueryingAA, Value &V,
6339 Type &Ty, Instruction *CtxI, bool Check,
6340 ValueToValueMapTy &VMap) {
6341 if (const auto &NewV = VMap.lookup(&V))
6342 return NewV;
6343 bool UsedAssumedInformation = false;
6344 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6345 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6346 if (!SimpleV.has_value())
6347 return PoisonValue::get(&Ty);
6348 Value *EffectiveV = &V;
6349 if (*SimpleV)
6350 EffectiveV = *SimpleV;
6351 if (auto *C = dyn_cast<Constant>(EffectiveV))
6352 return C;
6353 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6354 A.getInfoCache()))
6355 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6356 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6357 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6358 return ensureType(A, *NewV, Ty, CtxI, Check);
6359 return nullptr;
6360 }
6361
6362 /// Return a value we can use as replacement for the associated one, or
6363 /// nullptr if we don't have one that makes sense.
6364 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6365 Value *NewV = SimplifiedAssociatedValue
6366 ? *SimplifiedAssociatedValue
6367 : UndefValue::get(getAssociatedType());
6368 if (NewV && NewV != &getAssociatedValue()) {
6369 ValueToValueMapTy VMap;
6370 // First verify we can reprduce the value with the required type at the
6371 // context location before we actually start modifying the IR.
6372 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6373 /* CheckOnly */ true, VMap))
6374 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6375 /* CheckOnly */ false, VMap);
6376 }
6377 return nullptr;
6378 }
6379
6380 /// Helper function for querying AAValueSimplify and updating candidate.
6381 /// \param IRP The value position we are trying to unify with SimplifiedValue
6382 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6383 const IRPosition &IRP, bool Simplify = true) {
6384 bool UsedAssumedInformation = false;
6385 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6386 if (Simplify)
6387 QueryingValueSimplified = A.getAssumedSimplified(
6388 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6389 return unionAssumed(QueryingValueSimplified);
6390 }
6391
6392 /// Returns a candidate is found or not
6393 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6394 if (!getAssociatedValue().getType()->isIntegerTy())
6395 return false;
6396
6397 // This will also pass the call base context.
6398 const auto *AA =
6399 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6400 if (!AA)
6401 return false;
6402
6403 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6404
6405 if (!COpt) {
6406 SimplifiedAssociatedValue = std::nullopt;
6407 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6408 return true;
6409 }
6410 if (auto *C = *COpt) {
6411 SimplifiedAssociatedValue = C;
6412 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6413 return true;
6414 }
6415 return false;
6416 }
6417
6418 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6419 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6420 return true;
6421 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6422 return true;
6423 return false;
6424 }
6425
6426 /// See AbstractAttribute::manifest(...).
6427 ChangeStatus manifest(Attributor &A) override {
6428 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6429 for (auto &U : getAssociatedValue().uses()) {
6430 // Check if we need to adjust the insertion point to make sure the IR is
6431 // valid.
6432 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6433 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6434 IP = PHI->getIncomingBlock(U)->getTerminator();
6435 if (auto *NewV = manifestReplacementValue(A, IP)) {
6436 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6437 << " -> " << *NewV << " :: " << *this << "\n");
6438 if (A.changeUseAfterManifest(U, *NewV))
6439 Changed = ChangeStatus::CHANGED;
6440 }
6441 }
6442
6443 return Changed | AAValueSimplify::manifest(A);
6444 }
6445
6446 /// See AbstractState::indicatePessimisticFixpoint(...).
6447 ChangeStatus indicatePessimisticFixpoint() override {
6448 SimplifiedAssociatedValue = &getAssociatedValue();
6449 return AAValueSimplify::indicatePessimisticFixpoint();
6450 }
6451};
6452
6453struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6454 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6455 : AAValueSimplifyImpl(IRP, A) {}
6456
6457 void initialize(Attributor &A) override {
6458 AAValueSimplifyImpl::initialize(A);
6459 if (A.hasAttr(getIRPosition(),
6460 {Attribute::InAlloca, Attribute::Preallocated,
6461 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6462 /* IgnoreSubsumingPositions */ true))
6463 indicatePessimisticFixpoint();
6464 }
6465
6466 /// See AbstractAttribute::updateImpl(...).
6467 ChangeStatus updateImpl(Attributor &A) override {
6468 // Byval is only replacable if it is readonly otherwise we would write into
6469 // the replaced value and not the copy that byval creates implicitly.
6470 Argument *Arg = getAssociatedArgument();
6471 if (Arg->hasByValAttr()) {
6472 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6473 // there is no race by not copying a constant byval.
6474 bool IsKnown;
6475 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6476 return indicatePessimisticFixpoint();
6477 }
6478
6479 auto Before = SimplifiedAssociatedValue;
6480
6481 auto PredForCallSite = [&](AbstractCallSite ACS) {
6482 const IRPosition &ACSArgPos =
6483 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6484 // Check if a coresponding argument was found or if it is on not
6485 // associated (which can happen for callback calls).
6486 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6487 return false;
6488
6489 // Simplify the argument operand explicitly and check if the result is
6490 // valid in the current scope. This avoids refering to simplified values
6491 // in other functions, e.g., we don't want to say a an argument in a
6492 // static function is actually an argument in a different function.
6493 bool UsedAssumedInformation = false;
6494 std::optional<Constant *> SimpleArgOp =
6495 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6496 if (!SimpleArgOp)
6497 return true;
6498 if (!*SimpleArgOp)
6499 return false;
6500 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6501 return false;
6502 return unionAssumed(*SimpleArgOp);
6503 };
6504
6505 // Generate a answer specific to a call site context.
6506 bool Success;
6507 bool UsedAssumedInformation = false;
6508 if (hasCallBaseContext() &&
6509 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6510 Success = PredForCallSite(
6511 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6512 else
6513 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6514 UsedAssumedInformation);
6515
6516 if (!Success)
6517 if (!askSimplifiedValueForOtherAAs(A))
6518 return indicatePessimisticFixpoint();
6519
6520 // If a candidate was found in this update, return CHANGED.
6521 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6522 : ChangeStatus ::CHANGED;
6523 }
6524
6525 /// See AbstractAttribute::trackStatistics()
6526 void trackStatistics() const override {
6527 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6528 }
6529};
6530
6531struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6532 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6533 : AAValueSimplifyImpl(IRP, A) {}
6534
6535 /// See AAValueSimplify::getAssumedSimplifiedValue()
6536 std::optional<Value *>
6537 getAssumedSimplifiedValue(Attributor &A) const override {
6538 if (!isValidState())
6539 return nullptr;
6540 return SimplifiedAssociatedValue;
6541 }
6542
6543 /// See AbstractAttribute::updateImpl(...).
6544 ChangeStatus updateImpl(Attributor &A) override {
6545 auto Before = SimplifiedAssociatedValue;
6546
6547 auto ReturnInstCB = [&](Instruction &I) {
6548 auto &RI = cast<ReturnInst>(I);
6549 return checkAndUpdate(
6550 A, *this,
6551 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6552 };
6553
6554 bool UsedAssumedInformation = false;
6555 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6556 UsedAssumedInformation))
6557 if (!askSimplifiedValueForOtherAAs(A))
6558 return indicatePessimisticFixpoint();
6559
6560 // If a candidate was found in this update, return CHANGED.
6561 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6562 : ChangeStatus ::CHANGED;
6563 }
6564
6565 ChangeStatus manifest(Attributor &A) override {
6566 // We queried AAValueSimplify for the returned values so they will be
6567 // replaced if a simplified form was found. Nothing to do here.
6568 return ChangeStatus::UNCHANGED;
6569 }
6570
6571 /// See AbstractAttribute::trackStatistics()
6572 void trackStatistics() const override {
6573 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6574 }
6575};
6576
6577struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6578 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6579 : AAValueSimplifyImpl(IRP, A) {}
6580
6581 /// See AbstractAttribute::initialize(...).
6582 void initialize(Attributor &A) override {
6583 AAValueSimplifyImpl::initialize(A);
6584 Value &V = getAnchorValue();
6585
6586 // TODO: add other stuffs
6587 if (isa<Constant>(V))
6588 indicatePessimisticFixpoint();
6589 }
6590
6591 /// See AbstractAttribute::updateImpl(...).
6592 ChangeStatus updateImpl(Attributor &A) override {
6593 auto Before = SimplifiedAssociatedValue;
6594 if (!askSimplifiedValueForOtherAAs(A))
6595 return indicatePessimisticFixpoint();
6596
6597 // If a candidate was found in this update, return CHANGED.
6598 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6599 : ChangeStatus ::CHANGED;
6600 }
6601
6602 /// See AbstractAttribute::trackStatistics()
6603 void trackStatistics() const override {
6604 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6605 }
6606};
6607
6608struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6609 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6610 : AAValueSimplifyImpl(IRP, A) {}
6611
6612 /// See AbstractAttribute::initialize(...).
6613 void initialize(Attributor &A) override {
6614 SimplifiedAssociatedValue = nullptr;
6615 indicateOptimisticFixpoint();
6616 }
6617 /// See AbstractAttribute::initialize(...).
6618 ChangeStatus updateImpl(Attributor &A) override {
6620 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6621 }
6622 /// See AbstractAttribute::trackStatistics()
6623 void trackStatistics() const override {
6624 STATS_DECLTRACK_FN_ATTR(value_simplify)
6625 }
6626};
6627
6628struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6629 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6630 : AAValueSimplifyFunction(IRP, A) {}
6631 /// See AbstractAttribute::trackStatistics()
6632 void trackStatistics() const override {
6633 STATS_DECLTRACK_CS_ATTR(value_simplify)
6634 }
6635};
6636
6637struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6638 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6639 : AAValueSimplifyImpl(IRP, A) {}
6640
6641 void initialize(Attributor &A) override {
6642 AAValueSimplifyImpl::initialize(A);
6643 Function *Fn = getAssociatedFunction();
6644 assert(Fn && "Did expect an associted function");
6645 for (Argument &Arg : Fn->args()) {
6646 if (Arg.hasReturnedAttr()) {
6647 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6648 Arg.getArgNo());
6650 checkAndUpdate(A, *this, IRP))
6651 indicateOptimisticFixpoint();
6652 else
6653 indicatePessimisticFixpoint();
6654 return;
6655 }
6656 }
6657 }
6658
6659 /// See AbstractAttribute::updateImpl(...).
6660 ChangeStatus updateImpl(Attributor &A) override {
6661 return indicatePessimisticFixpoint();
6662 }
6663
6664 void trackStatistics() const override {
6665 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6666 }
6667};
6668
6669struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6670 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6671 : AAValueSimplifyFloating(IRP, A) {}
6672
6673 /// See AbstractAttribute::manifest(...).
6674 ChangeStatus manifest(Attributor &A) override {
6675 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6676 // TODO: We should avoid simplification duplication to begin with.
6677 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6678 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6679 if (FloatAA && FloatAA->getState().isValidState())
6680 return Changed;
6681
6682 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6683 Use &U = cast<CallBase>(&getAnchorValue())
6684 ->getArgOperandUse(getCallSiteArgNo());
6685 if (A.changeUseAfterManifest(U, *NewV))
6686 Changed = ChangeStatus::CHANGED;
6687 }
6688
6689 return Changed | AAValueSimplify::manifest(A);
6690 }
6691
6692 void trackStatistics() const override {
6693 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6694 }
6695};
6696} // namespace
6697
6698/// ----------------------- Heap-To-Stack Conversion ---------------------------
6699namespace {
6700struct AAHeapToStackFunction final : public AAHeapToStack {
6701
6702 static bool isGlobalizedLocal(const CallBase &CB) {
6703 Attribute A = CB.getFnAttr("alloc-family");
6704 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6705 }
6706
6707 struct AllocationInfo {
6708 /// The call that allocates the memory.
6709 CallBase *const CB;
6710
6711 /// Whether this allocation is an OpenMP globalized local variable.
6712 bool IsGlobalizedLocal = false;
6713
6714 /// The status wrt. a rewrite.
6715 enum {
6716 STACK_DUE_TO_USE,
6717 STACK_DUE_TO_FREE,
6718 INVALID,
6719 } Status = STACK_DUE_TO_USE;
6720
6721 /// Flag to indicate if we encountered a use that might free this allocation
6722 /// but which is not in the deallocation infos.
6723 bool HasPotentiallyFreeingUnknownUses = false;
6724
6725 /// Flag to indicate that we should place the new alloca in the function
6726 /// entry block rather than where the call site (CB) is.
6727 bool MoveAllocaIntoEntry = true;
6728
6729 /// The set of free calls that use this allocation.
6730 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6731 };
6732
6733 struct DeallocationInfo {
6734 /// The call that deallocates the memory.
6735 CallBase *const CB;
6736 /// The value freed by the call.
6737 Value *FreedOp;
6738
6739 /// Flag to indicate if we don't know all objects this deallocation might
6740 /// free.
6741 bool MightFreeUnknownObjects = false;
6742
6743 /// The set of allocation calls that are potentially freed.
6744 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6745 };
6746
6747 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6748 : AAHeapToStack(IRP, A) {}
6749
6750 ~AAHeapToStackFunction() override {
6751 // Ensure we call the destructor so we release any memory allocated in the
6752 // sets.
6753 for (auto &It : AllocationInfos)
6754 It.second->~AllocationInfo();
6755 for (auto &It : DeallocationInfos)
6756 It.second->~DeallocationInfo();
6757 }
6758
6759 void initialize(Attributor &A) override {
6760 AAHeapToStack::initialize(A);
6761
6762 const Function *F = getAnchorScope();
6763 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6764
6765 auto AllocationIdentifierCB = [&](Instruction &I) {
6766 CallBase *CB = dyn_cast<CallBase>(&I);
6767 if (!CB)
6768 return true;
6769 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6770 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6771 return true;
6772 }
6773 // To do heap to stack, we need to know that the allocation itself is
6774 // removable once uses are rewritten, and that we can initialize the
6775 // alloca to the same pattern as the original allocation result.
6776 if (isRemovableAlloc(CB, TLI)) {
6777 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6778 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6779 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6780 AllocationInfos[CB] = AI;
6781 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6782 }
6783 }
6784 return true;
6785 };
6786
6787 bool UsedAssumedInformation = false;
6788 bool Success = A.checkForAllCallLikeInstructions(
6789 AllocationIdentifierCB, *this, UsedAssumedInformation,
6790 /* CheckBBLivenessOnly */ false,
6791 /* CheckPotentiallyDead */ true);
6792 (void)Success;
6793 assert(Success && "Did not expect the call base visit callback to fail!");
6794
6796 [](const IRPosition &, const AbstractAttribute *,
6797 bool &) -> std::optional<Value *> { return nullptr; };
6798 for (const auto &It : AllocationInfos)
6799 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6800 SCB);
6801 for (const auto &It : DeallocationInfos)
6802 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6803 SCB);
6804 }
6805
6806 const std::string getAsStr(Attributor *A) const override {
6807 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6808 for (const auto &It : AllocationInfos) {
6809 if (It.second->Status == AllocationInfo::INVALID)
6810 ++NumInvalidMallocs;
6811 else
6812 ++NumH2SMallocs;
6813 }
6814 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6815 std::to_string(NumInvalidMallocs);
6816 }
6817
6818 /// See AbstractAttribute::trackStatistics().
6819 void trackStatistics() const override {
6820 STATS_DECL(
6821 MallocCalls, Function,
6822 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6823 for (const auto &It : AllocationInfos)
6824 if (It.second->Status != AllocationInfo::INVALID)
6825 ++BUILD_STAT_NAME(MallocCalls, Function);
6826 }
6827
6828 bool isAssumedHeapToStack(const CallBase &CB) const override {
6829 if (isValidState())
6830 if (AllocationInfo *AI =
6831 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6832 return AI->Status != AllocationInfo::INVALID;
6833 return false;
6834 }
6835
6836 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6837 if (!isValidState())
6838 return false;
6839
6840 for (const auto &It : AllocationInfos) {
6841 AllocationInfo &AI = *It.second;
6842 if (AI.Status == AllocationInfo::INVALID)
6843 continue;
6844
6845 if (AI.PotentialFreeCalls.count(&CB))
6846 return true;
6847 }
6848
6849 return false;
6850 }
6851
6852 ChangeStatus manifest(Attributor &A) override {
6853 assert(getState().isValidState() &&
6854 "Attempted to manifest an invalid state!");
6855
6856 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6857 Function *F = getAnchorScope();
6858 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6859
6860 for (auto &It : AllocationInfos) {
6861 AllocationInfo &AI = *It.second;
6862 if (AI.Status == AllocationInfo::INVALID)
6863 continue;
6864
6865 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6866 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6867 A.deleteAfterManifest(*FreeCall);
6868 HasChanged = ChangeStatus::CHANGED;
6869 }
6870
6871 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6872 << "\n");
6873
6874 auto Remark = [&](OptimizationRemark OR) {
6875 if (AI.IsGlobalizedLocal)
6876 return OR << "Moving globalized variable to the stack.";
6877 return OR << "Moving memory allocation from the heap to the stack.";
6878 };
6879 if (AI.IsGlobalizedLocal)
6880 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6881 else
6882 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6883
6884 const DataLayout &DL = A.getInfoCache().getDL();
6885 Value *Size;
6886 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6887 if (SizeAPI) {
6888 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6889 } else {
6890 LLVMContext &Ctx = AI.CB->getContext();
6891 ObjectSizeOpts Opts;
6892 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6893 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6894 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6895 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6896 Size = SizeOffsetPair.Size;
6897 }
6898
6899 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6900 ? F->getEntryBlock().begin()
6901 : AI.CB->getIterator();
6902
6903 Align Alignment(1);
6904 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6905 Alignment = std::max(Alignment, *RetAlign);
6906 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6907 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6908 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6909 "Expected an alignment during manifest!");
6910 Alignment =
6911 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6912 }
6913
6914 // TODO: Hoist the alloca towards the function entry.
6915 unsigned AS = DL.getAllocaAddrSpace();
6916 Instruction *Alloca =
6917 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6918 AI.CB->getName() + ".h2s", IP);
6919
6920 if (Alloca->getType() != AI.CB->getType())
6921 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6922 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6923
6924 auto *I8Ty = Type::getInt8Ty(F->getContext());
6925 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6926 assert(InitVal &&
6927 "Must be able to materialize initial memory state of allocation");
6928
6929 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6930
6931 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6932 auto *NBB = II->getNormalDest();
6933 UncondBrInst::Create(NBB, AI.CB->getParent());
6934 A.deleteAfterManifest(*AI.CB);
6935 } else {
6936 A.deleteAfterManifest(*AI.CB);
6937 }
6938
6939 // Initialize the alloca with the same value as used by the allocation
6940 // function. We can skip undef as the initial value of an alloc is
6941 // undef, and the memset would simply end up being DSEd.
6942 if (!isa<UndefValue>(InitVal)) {
6943 IRBuilder<> Builder(Alloca->getNextNode());
6944 // TODO: Use alignment above if align!=1
6945 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6946 }
6947 HasChanged = ChangeStatus::CHANGED;
6948 }
6949
6950 return HasChanged;
6951 }
6952
6953 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6954 Value &V) {
6955 bool UsedAssumedInformation = false;
6956 std::optional<Constant *> SimpleV =
6957 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6958 if (!SimpleV)
6959 return APInt(64, 0);
6960 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6961 return CI->getValue();
6962 return std::nullopt;
6963 }
6964
6965 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6966 AllocationInfo &AI) {
6967 auto Mapper = [&](const Value *V) -> const Value * {
6968 bool UsedAssumedInformation = false;
6969 if (std::optional<Constant *> SimpleV =
6970 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6971 if (*SimpleV)
6972 return *SimpleV;
6973 return V;
6974 };
6975
6976 const Function *F = getAnchorScope();
6977 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6978 return getAllocSize(AI.CB, TLI, Mapper);
6979 }
6980
6981 /// Collection of all malloc-like calls in a function with associated
6982 /// information.
6983 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6984
6985 /// Collection of all free-like calls in a function with associated
6986 /// information.
6987 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6988
6989 ChangeStatus updateImpl(Attributor &A) override;
6990};
6991
6992ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6994 const Function *F = getAnchorScope();
6995 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6996
6997 const auto *LivenessAA =
6998 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6999
7000 MustBeExecutedContextExplorer *Explorer =
7001 A.getInfoCache().getMustBeExecutedContextExplorer();
7002
7003 bool StackIsAccessibleByOtherThreads =
7004 A.getInfoCache().stackIsAccessibleByOtherThreads();
7005
7006 LoopInfo *LI =
7007 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7008 std::optional<bool> MayContainIrreducibleControl;
7009 auto IsInLoop = [&](BasicBlock &BB) {
7010 if (&F->getEntryBlock() == &BB)
7011 return false;
7012 if (!MayContainIrreducibleControl.has_value())
7013 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7014 if (*MayContainIrreducibleControl)
7015 return true;
7016 if (!LI)
7017 return true;
7018 return LI->getLoopFor(&BB) != nullptr;
7019 };
7020
7021 // Flag to ensure we update our deallocation information at most once per
7022 // updateImpl call and only if we use the free check reasoning.
7023 bool HasUpdatedFrees = false;
7024
7025 auto UpdateFrees = [&]() {
7026 HasUpdatedFrees = true;
7027
7028 for (auto &It : DeallocationInfos) {
7029 DeallocationInfo &DI = *It.second;
7030 // For now we cannot use deallocations that have unknown inputs, skip
7031 // them.
7032 if (DI.MightFreeUnknownObjects)
7033 continue;
7034
7035 // No need to analyze dead calls, ignore them instead.
7036 bool UsedAssumedInformation = false;
7037 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7038 /* CheckBBLivenessOnly */ true))
7039 continue;
7040
7041 // Use the non-optimistic version to get the freed object.
7042 Value *Obj = getUnderlyingObject(DI.FreedOp);
7043 if (!Obj) {
7044 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7045 DI.MightFreeUnknownObjects = true;
7046 continue;
7047 }
7048
7049 // Free of null and undef can be ignored as no-ops (or UB in the latter
7050 // case).
7052 continue;
7053
7054 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7055 if (!ObjCB) {
7056 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7057 << "\n");
7058 DI.MightFreeUnknownObjects = true;
7059 continue;
7060 }
7061
7062 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7063 if (!AI) {
7064 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7065 << "\n");
7066 DI.MightFreeUnknownObjects = true;
7067 continue;
7068 }
7069
7070 DI.PotentialAllocationCalls.insert(ObjCB);
7071 }
7072 };
7073
7074 auto FreeCheck = [&](AllocationInfo &AI) {
7075 // If the stack is not accessible by other threads, the "must-free" logic
7076 // doesn't apply as the pointer could be shared and needs to be places in
7077 // "shareable" memory.
7078 if (!StackIsAccessibleByOtherThreads) {
7079 bool IsKnownNoSycn;
7081 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7082 LLVM_DEBUG(
7083 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7084 "other threads and function is not nosync:\n");
7085 return false;
7086 }
7087 }
7088 if (!HasUpdatedFrees)
7089 UpdateFrees();
7090
7091 // TODO: Allow multi exit functions that have different free calls.
7092 if (AI.PotentialFreeCalls.size() != 1) {
7093 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7094 << AI.PotentialFreeCalls.size() << "\n");
7095 return false;
7096 }
7097 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7098 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7099 if (!DI) {
7100 LLVM_DEBUG(
7101 dbgs() << "[H2S] unique free call was not known as deallocation call "
7102 << *UniqueFree << "\n");
7103 return false;
7104 }
7105 if (DI->MightFreeUnknownObjects) {
7106 LLVM_DEBUG(
7107 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7108 return false;
7109 }
7110 if (DI->PotentialAllocationCalls.empty())
7111 return true;
7112 if (DI->PotentialAllocationCalls.size() > 1) {
7113 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7114 << DI->PotentialAllocationCalls.size()
7115 << " different allocations\n");
7116 return false;
7117 }
7118 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7119 LLVM_DEBUG(
7120 dbgs()
7121 << "[H2S] unique free call not known to free this allocation but "
7122 << **DI->PotentialAllocationCalls.begin() << "\n");
7123 return false;
7124 }
7125
7126 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7127 if (!AI.IsGlobalizedLocal) {
7128 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7129 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7130 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7131 "with the allocation "
7132 << *UniqueFree << "\n");
7133 return false;
7134 }
7135 }
7136 return true;
7137 };
7138
7139 auto UsesCheck = [&](AllocationInfo &AI) {
7140 bool ValidUsesOnly = true;
7141
7142 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7143 Instruction *UserI = cast<Instruction>(U.getUser());
7144 if (isa<LoadInst>(UserI))
7145 return true;
7146 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7147 if (SI->getValueOperand() == U.get()) {
7149 << "[H2S] escaping store to memory: " << *UserI << "\n");
7150 ValidUsesOnly = false;
7151 } else {
7152 // A store into the malloc'ed memory is fine.
7153 }
7154 return true;
7155 }
7156 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7157 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7158 return true;
7159 if (DeallocationInfos.count(CB)) {
7160 AI.PotentialFreeCalls.insert(CB);
7161 return true;
7162 }
7163
7164 unsigned ArgNo = CB->getArgOperandNo(&U);
7165 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7166
7167 bool IsKnownNoCapture;
7168 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7169 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7170
7171 // If a call site argument use is nofree, we are fine.
7172 bool IsKnownNoFree;
7173 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7174 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7175
7176 if (!IsAssumedNoCapture ||
7177 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7178 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7179
7180 // Emit a missed remark if this is missed OpenMP globalization.
7181 auto Remark = [&](OptimizationRemarkMissed ORM) {
7182 return ORM
7183 << "Could not move globalized variable to the stack. "
7184 "Variable is potentially captured in call. Mark "
7185 "parameter as `__attribute__((noescape))` to override.";
7186 };
7187
7188 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7189 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7190
7191 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7192 ValidUsesOnly = false;
7193 }
7194 return true;
7195 }
7196
7197 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7198 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7199 Follow = true;
7200 return true;
7201 }
7202 // Unknown user for which we can not track uses further (in a way that
7203 // makes sense).
7204 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7205 ValidUsesOnly = false;
7206 return true;
7207 };
7208 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7209 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7210 [&](const Use &OldU, const Use &NewU) {
7211 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7212 return !SI || StackIsAccessibleByOtherThreads ||
7213 AA::isAssumedThreadLocalObject(
7214 A, *SI->getPointerOperand(), *this);
7215 }))
7216 return false;
7217 return ValidUsesOnly;
7218 };
7219
7220 // The actual update starts here. We look at all allocations and depending on
7221 // their status perform the appropriate check(s).
7222 for (auto &It : AllocationInfos) {
7223 AllocationInfo &AI = *It.second;
7224 if (AI.Status == AllocationInfo::INVALID)
7225 continue;
7226
7227 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7228 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7229 if (!APAlign) {
7230 // Can't generate an alloca which respects the required alignment
7231 // on the allocation.
7232 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7233 << "\n");
7234 AI.Status = AllocationInfo::INVALID;
7236 continue;
7237 }
7238 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7239 !APAlign->isPowerOf2()) {
7240 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7241 << "\n");
7242 AI.Status = AllocationInfo::INVALID;
7244 continue;
7245 }
7246 }
7247
7248 std::optional<APInt> Size = getSize(A, *this, AI);
7249 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7250 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7251 LLVM_DEBUG({
7252 if (!Size)
7253 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7254 else
7255 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7256 << MaxHeapToStackSize << "\n";
7257 });
7258
7259 AI.Status = AllocationInfo::INVALID;
7261 continue;
7262 }
7263 }
7264
7265 switch (AI.Status) {
7266 case AllocationInfo::STACK_DUE_TO_USE:
7267 if (UsesCheck(AI))
7268 break;
7269 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7270 [[fallthrough]];
7271 case AllocationInfo::STACK_DUE_TO_FREE:
7272 if (FreeCheck(AI))
7273 break;
7274 AI.Status = AllocationInfo::INVALID;
7276 break;
7277 case AllocationInfo::INVALID:
7278 llvm_unreachable("Invalid allocations should never reach this point!");
7279 };
7280
7281 // Check if we still think we can move it into the entry block. If the
7282 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7283 // ignore the potential complications associated with loops.
7284 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7285 if (AI.MoveAllocaIntoEntry &&
7286 (!Size.has_value() ||
7287 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7288 AI.MoveAllocaIntoEntry = false;
7289 }
7290
7291 return Changed;
7292}
7293} // namespace
7294
7295/// ----------------------- Privatizable Pointers ------------------------------
7296namespace {
7297struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7298 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7299 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7300
7301 ChangeStatus indicatePessimisticFixpoint() override {
7302 AAPrivatizablePtr::indicatePessimisticFixpoint();
7303 PrivatizableType = nullptr;
7304 return ChangeStatus::CHANGED;
7305 }
7306
7307 /// Identify the type we can chose for a private copy of the underlying
7308 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7309 /// none.
7310 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7311
7312 /// Return a privatizable type that encloses both T0 and T1.
7313 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7314 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7315 std::optional<Type *> T1) {
7316 if (!T0)
7317 return T1;
7318 if (!T1)
7319 return T0;
7320 if (T0 == T1)
7321 return T0;
7322 return nullptr;
7323 }
7324
7325 std::optional<Type *> getPrivatizableType() const override {
7326 return PrivatizableType;
7327 }
7328
7329 const std::string getAsStr(Attributor *A) const override {
7330 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7331 }
7332
7333protected:
7334 std::optional<Type *> PrivatizableType;
7335};
7336
7337// TODO: Do this for call site arguments (probably also other values) as well.
7338
7339struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7340 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7341 : AAPrivatizablePtrImpl(IRP, A) {}
7342
7343 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7344 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7345 // If this is a byval argument and we know all the call sites (so we can
7346 // rewrite them), there is no need to check them explicitly.
7347 bool UsedAssumedInformation = false;
7349 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7350 /* IgnoreSubsumingPositions */ true);
7351 if (!Attrs.empty() &&
7352 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7353 true, UsedAssumedInformation))
7354 return Attrs[0].getValueAsType();
7355
7356 std::optional<Type *> Ty;
7357 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7358
7359 // Make sure the associated call site argument has the same type at all call
7360 // sites and it is an allocation we know is safe to privatize, for now that
7361 // means we only allow alloca instructions.
7362 // TODO: We can additionally analyze the accesses in the callee to create
7363 // the type from that information instead. That is a little more
7364 // involved and will be done in a follow up patch.
7365 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7366 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7367 // Check if a coresponding argument was found or if it is one not
7368 // associated (which can happen for callback calls).
7369 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7370 return false;
7371
7372 // Check that all call sites agree on a type.
7373 auto *PrivCSArgAA =
7374 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7375 if (!PrivCSArgAA)
7376 return false;
7377 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7378
7379 LLVM_DEBUG({
7380 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7381 if (CSTy && *CSTy)
7382 (*CSTy)->print(dbgs());
7383 else if (CSTy)
7384 dbgs() << "<nullptr>";
7385 else
7386 dbgs() << "<none>";
7387 });
7388
7389 Ty = combineTypes(Ty, CSTy);
7390
7391 LLVM_DEBUG({
7392 dbgs() << " : New Type: ";
7393 if (Ty && *Ty)
7394 (*Ty)->print(dbgs());
7395 else if (Ty)
7396 dbgs() << "<nullptr>";
7397 else
7398 dbgs() << "<none>";
7399 dbgs() << "\n";
7400 });
7401
7402 return !Ty || *Ty;
7403 };
7404
7405 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7406 UsedAssumedInformation))
7407 return nullptr;
7408 return Ty;
7409 }
7410
7411 /// See AbstractAttribute::updateImpl(...).
7412 ChangeStatus updateImpl(Attributor &A) override {
7413 PrivatizableType = identifyPrivatizableType(A);
7414 if (!PrivatizableType)
7415 return ChangeStatus::UNCHANGED;
7416 if (!*PrivatizableType)
7417 return indicatePessimisticFixpoint();
7418
7419 // The dependence is optional so we don't give up once we give up on the
7420 // alignment.
7421 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7422 DepClassTy::OPTIONAL);
7423
7424 // Avoid arguments with padding for now.
7425 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7426 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7427 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7428 return indicatePessimisticFixpoint();
7429 }
7430
7431 // Collect the types that will replace the privatizable type in the function
7432 // signature.
7433 SmallVector<Type *, 16> ReplacementTypes;
7434 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7435
7436 // Verify callee and caller agree on how the promoted argument would be
7437 // passed.
7438 Function &Fn = *getIRPosition().getAnchorScope();
7439 const auto *TTI =
7440 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7441 if (!TTI) {
7442 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7443 << Fn.getName() << "\n");
7444 return indicatePessimisticFixpoint();
7445 }
7446
7447 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7448 CallBase *CB = ACS.getInstruction();
7449 return TTI->areTypesABICompatible(
7450 CB->getCaller(),
7452 ReplacementTypes);
7453 };
7454 bool UsedAssumedInformation = false;
7455 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7456 UsedAssumedInformation)) {
7457 LLVM_DEBUG(
7458 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7459 << Fn.getName() << "\n");
7460 return indicatePessimisticFixpoint();
7461 }
7462
7463 // Register a rewrite of the argument.
7464 Argument *Arg = getAssociatedArgument();
7465 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7466 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7467 return indicatePessimisticFixpoint();
7468 }
7469
7470 unsigned ArgNo = Arg->getArgNo();
7471
7472 // Helper to check if for the given call site the associated argument is
7473 // passed to a callback where the privatization would be different.
7474 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7475 SmallVector<const Use *, 4> CallbackUses;
7476 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7477 for (const Use *U : CallbackUses) {
7478 AbstractCallSite CBACS(U);
7479 assert(CBACS && CBACS.isCallbackCall());
7480 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7481 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7482
7483 LLVM_DEBUG({
7484 dbgs()
7485 << "[AAPrivatizablePtr] Argument " << *Arg
7486 << "check if can be privatized in the context of its parent ("
7487 << Arg->getParent()->getName()
7488 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7489 "callback ("
7490 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7491 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7492 << CBACS.getCallArgOperand(CBArg) << " vs "
7493 << CB.getArgOperand(ArgNo) << "\n"
7494 << "[AAPrivatizablePtr] " << CBArg << " : "
7495 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7496 });
7497
7498 if (CBArgNo != int(ArgNo))
7499 continue;
7500 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7501 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7502 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7503 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7504 if (!CBArgPrivTy)
7505 continue;
7506 if (*CBArgPrivTy == PrivatizableType)
7507 continue;
7508 }
7509
7510 LLVM_DEBUG({
7511 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7512 << " cannot be privatized in the context of its parent ("
7513 << Arg->getParent()->getName()
7514 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7515 "callback ("
7516 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7517 << ").\n[AAPrivatizablePtr] for which the argument "
7518 "privatization is not compatible.\n";
7519 });
7520 return false;
7521 }
7522 }
7523 return true;
7524 };
7525
7526 // Helper to check if for the given call site the associated argument is
7527 // passed to a direct call where the privatization would be different.
7528 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7529 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7530 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7531 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7532 "Expected a direct call operand for callback call operand");
7533
7534 Function *DCCallee =
7536 LLVM_DEBUG({
7537 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7538 << " check if be privatized in the context of its parent ("
7539 << Arg->getParent()->getName()
7540 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7541 "direct call of ("
7542 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7543 });
7544
7545 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7546 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7547 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7548 DepClassTy::REQUIRED);
7549 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7550 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7551 if (!DCArgPrivTy)
7552 return true;
7553 if (*DCArgPrivTy == PrivatizableType)
7554 return true;
7555 }
7556 }
7557
7558 LLVM_DEBUG({
7559 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7560 << " cannot be privatized in the context of its parent ("
7561 << Arg->getParent()->getName()
7562 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7563 "direct call of ("
7565 << ").\n[AAPrivatizablePtr] for which the argument "
7566 "privatization is not compatible.\n";
7567 });
7568 return false;
7569 };
7570
7571 // Helper to check if the associated argument is used at the given abstract
7572 // call site in a way that is incompatible with the privatization assumed
7573 // here.
7574 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7575 if (ACS.isDirectCall())
7576 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7577 if (ACS.isCallbackCall())
7578 return IsCompatiblePrivArgOfDirectCS(ACS);
7579 return false;
7580 };
7581
7582 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7583 UsedAssumedInformation))
7584 return indicatePessimisticFixpoint();
7585
7586 return ChangeStatus::UNCHANGED;
7587 }
7588
7589 /// Given a type to private \p PrivType, collect the constituates (which are
7590 /// used) in \p ReplacementTypes.
7591 static void
7592 identifyReplacementTypes(Type *PrivType,
7593 SmallVectorImpl<Type *> &ReplacementTypes) {
7594 // TODO: For now we expand the privatization type to the fullest which can
7595 // lead to dead arguments that need to be removed later.
7596 assert(PrivType && "Expected privatizable type!");
7597
7598 // Traverse the type, extract constituate types on the outermost level.
7599 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7600 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7601 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7602 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7603 ReplacementTypes.append(PrivArrayType->getNumElements(),
7604 PrivArrayType->getElementType());
7605 } else {
7606 ReplacementTypes.push_back(PrivType);
7607 }
7608 }
7609
7610 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7611 /// The values needed are taken from the arguments of \p F starting at
7612 /// position \p ArgNo.
7613 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7614 unsigned ArgNo, BasicBlock::iterator IP) {
7615 assert(PrivType && "Expected privatizable type!");
7616
7617 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7618 const DataLayout &DL = F.getDataLayout();
7619
7620 // Traverse the type, build GEPs and stores.
7621 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7622 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7623 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7624 Value *Ptr =
7625 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7626 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7627 }
7628 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7629 Type *PointeeTy = PrivArrayType->getElementType();
7630 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7631 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7632 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7633 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7634 }
7635 } else {
7636 new StoreInst(F.getArg(ArgNo), &Base, IP);
7637 }
7638 }
7639
7640 /// Extract values from \p Base according to the type \p PrivType at the
7641 /// call position \p ACS. The values are appended to \p ReplacementValues.
7642 void createReplacementValues(Align Alignment, Type *PrivType,
7643 AbstractCallSite ACS, Value *Base,
7644 SmallVectorImpl<Value *> &ReplacementValues) {
7645 assert(Base && "Expected base value!");
7646 assert(PrivType && "Expected privatizable type!");
7647 Instruction *IP = ACS.getInstruction();
7648
7649 IRBuilder<NoFolder> IRB(IP);
7650 const DataLayout &DL = IP->getDataLayout();
7651
7652 // Traverse the type, build GEPs and loads.
7653 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7654 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7655 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7656 Type *PointeeTy = PrivStructType->getElementType(u);
7657 Value *Ptr =
7658 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7659 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7660 L->setAlignment(Alignment);
7661 ReplacementValues.push_back(L);
7662 }
7663 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7664 Type *PointeeTy = PrivArrayType->getElementType();
7665 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7666 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7667 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7668 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7669 L->setAlignment(Alignment);
7670 ReplacementValues.push_back(L);
7671 }
7672 } else {
7673 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7674 L->setAlignment(Alignment);
7675 ReplacementValues.push_back(L);
7676 }
7677 }
7678
7679 /// See AbstractAttribute::manifest(...)
7680 ChangeStatus manifest(Attributor &A) override {
7681 if (!PrivatizableType)
7682 return ChangeStatus::UNCHANGED;
7683 assert(*PrivatizableType && "Expected privatizable type!");
7684
7685 // Collect all tail calls in the function as we cannot allow new allocas to
7686 // escape into tail recursion.
7687 // TODO: Be smarter about new allocas escaping into tail calls.
7689 bool UsedAssumedInformation = false;
7690 if (!A.checkForAllInstructions(
7691 [&](Instruction &I) {
7692 CallInst &CI = cast<CallInst>(I);
7693 if (CI.isTailCall())
7694 TailCalls.push_back(&CI);
7695 return true;
7696 },
7697 *this, {Instruction::Call}, UsedAssumedInformation))
7698 return ChangeStatus::UNCHANGED;
7699
7700 Argument *Arg = getAssociatedArgument();
7701 // Query AAAlign attribute for alignment of associated argument to
7702 // determine the best alignment of loads.
7703 const auto *AlignAA =
7704 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7705
7706 // Callback to repair the associated function. A new alloca is placed at the
7707 // beginning and initialized with the values passed through arguments. The
7708 // new alloca replaces the use of the old pointer argument.
7710 [=](const Attributor::ArgumentReplacementInfo &ARI,
7711 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7712 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7714 const DataLayout &DL = IP->getDataLayout();
7715 unsigned AS = DL.getAllocaAddrSpace();
7716 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7717 Arg->getName() + ".priv", IP);
7718 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7719 ArgIt->getArgNo(), IP);
7720
7721 if (AI->getType() != Arg->getType())
7722 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7723 AI, Arg->getType(), "", IP);
7724 Arg->replaceAllUsesWith(AI);
7725
7726 for (CallInst *CI : TailCalls)
7727 CI->setTailCall(false);
7728 };
7729
7730 // Callback to repair a call site of the associated function. The elements
7731 // of the privatizable type are loaded prior to the call and passed to the
7732 // new function version.
7734 [=](const Attributor::ArgumentReplacementInfo &ARI,
7735 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7736 // When no alignment is specified for the load instruction,
7737 // natural alignment is assumed.
7738 createReplacementValues(
7739 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7740 *PrivatizableType, ACS,
7741 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7742 NewArgOperands);
7743 };
7744
7745 // Collect the types that will replace the privatizable type in the function
7746 // signature.
7747 SmallVector<Type *, 16> ReplacementTypes;
7748 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7749
7750 // Register a rewrite of the argument.
7751 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7752 std::move(FnRepairCB),
7753 std::move(ACSRepairCB)))
7754 return ChangeStatus::CHANGED;
7755 return ChangeStatus::UNCHANGED;
7756 }
7757
7758 /// See AbstractAttribute::trackStatistics()
7759 void trackStatistics() const override {
7760 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7761 }
7762};
7763
7764struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7765 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7766 : AAPrivatizablePtrImpl(IRP, A) {}
7767
7768 /// See AbstractAttribute::initialize(...).
7769 void initialize(Attributor &A) override {
7770 // TODO: We can privatize more than arguments.
7771 indicatePessimisticFixpoint();
7772 }
7773
7774 ChangeStatus updateImpl(Attributor &A) override {
7775 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7776 "updateImpl will not be called");
7777 }
7778
7779 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7780 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7781 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7782 if (!Obj) {
7783 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7784 return nullptr;
7785 }
7786
7787 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7788 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7789 if (CI->isOne())
7790 return AI->getAllocatedType();
7791 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7792 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7793 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7794 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7795 return PrivArgAA->getPrivatizableType();
7796 }
7797
7798 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7799 "alloca nor privatizable argument: "
7800 << *Obj << "!\n");
7801 return nullptr;
7802 }
7803
7804 /// See AbstractAttribute::trackStatistics()
7805 void trackStatistics() const override {
7806 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7807 }
7808};
7809
7810struct AAPrivatizablePtrCallSiteArgument final
7811 : public AAPrivatizablePtrFloating {
7812 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7813 : AAPrivatizablePtrFloating(IRP, A) {}
7814
7815 /// See AbstractAttribute::initialize(...).
7816 void initialize(Attributor &A) override {
7817 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7818 indicateOptimisticFixpoint();
7819 }
7820
7821 /// See AbstractAttribute::updateImpl(...).
7822 ChangeStatus updateImpl(Attributor &A) override {
7823 PrivatizableType = identifyPrivatizableType(A);
7824 if (!PrivatizableType)
7825 return ChangeStatus::UNCHANGED;
7826 if (!*PrivatizableType)
7827 return indicatePessimisticFixpoint();
7828
7829 const IRPosition &IRP = getIRPosition();
7830 bool IsKnownNoCapture;
7831 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7832 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7833 if (!IsAssumedNoCapture) {
7834 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7835 return indicatePessimisticFixpoint();
7836 }
7837
7838 bool IsKnownNoAlias;
7840 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7841 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7842 return indicatePessimisticFixpoint();
7843 }
7844
7845 bool IsKnown;
7846 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7847 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7848 return indicatePessimisticFixpoint();
7849 }
7850
7851 return ChangeStatus::UNCHANGED;
7852 }
7853
7854 /// See AbstractAttribute::trackStatistics()
7855 void trackStatistics() const override {
7856 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7857 }
7858};
7859
7860struct AAPrivatizablePtrCallSiteReturned final
7861 : public AAPrivatizablePtrFloating {
7862 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7863 : AAPrivatizablePtrFloating(IRP, A) {}
7864
7865 /// See AbstractAttribute::initialize(...).
7866 void initialize(Attributor &A) override {
7867 // TODO: We can privatize more than arguments.
7868 indicatePessimisticFixpoint();
7869 }
7870
7871 /// See AbstractAttribute::trackStatistics()
7872 void trackStatistics() const override {
7873 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7874 }
7875};
7876
7877struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7878 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7879 : AAPrivatizablePtrFloating(IRP, A) {}
7880
7881 /// See AbstractAttribute::initialize(...).
7882 void initialize(Attributor &A) override {
7883 // TODO: We can privatize more than arguments.
7884 indicatePessimisticFixpoint();
7885 }
7886
7887 /// See AbstractAttribute::trackStatistics()
7888 void trackStatistics() const override {
7889 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7890 }
7891};
7892} // namespace
7893
7894/// -------------------- Memory Behavior Attributes ----------------------------
7895/// Includes read-none, read-only, and write-only.
7896/// ----------------------------------------------------------------------------
7897namespace {
7898struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7899 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7900 : AAMemoryBehavior(IRP, A) {}
7901
7902 /// See AbstractAttribute::initialize(...).
7903 void initialize(Attributor &A) override {
7904 intersectAssumedBits(BEST_STATE);
7905 getKnownStateFromValue(A, getIRPosition(), getState());
7906 AAMemoryBehavior::initialize(A);
7907 }
7908
7909 /// Return the memory behavior information encoded in the IR for \p IRP.
7910 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7911 BitIntegerState &State,
7912 bool IgnoreSubsumingPositions = false) {
7914 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7915 for (const Attribute &Attr : Attrs) {
7916 switch (Attr.getKindAsEnum()) {
7917 case Attribute::ReadNone:
7918 State.addKnownBits(NO_ACCESSES);
7919 break;
7920 case Attribute::ReadOnly:
7921 State.addKnownBits(NO_WRITES);
7922 break;
7923 case Attribute::WriteOnly:
7924 State.addKnownBits(NO_READS);
7925 break;
7926 default:
7927 llvm_unreachable("Unexpected attribute!");
7928 }
7929 }
7930
7931 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7932 if (!I->mayReadFromMemory())
7933 State.addKnownBits(NO_READS);
7934 if (!I->mayWriteToMemory())
7935 State.addKnownBits(NO_WRITES);
7936 }
7937 }
7938
7939 /// See AbstractAttribute::getDeducedAttributes(...).
7940 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7941 SmallVectorImpl<Attribute> &Attrs) const override {
7942 assert(Attrs.size() == 0);
7943 if (isAssumedReadNone())
7944 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7945 else if (isAssumedReadOnly())
7946 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7947 else if (isAssumedWriteOnly())
7948 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7949 assert(Attrs.size() <= 1);
7950 }
7951
7952 /// See AbstractAttribute::manifest(...).
7953 ChangeStatus manifest(Attributor &A) override {
7954 const IRPosition &IRP = getIRPosition();
7955
7956 if (A.hasAttr(IRP, Attribute::ReadNone,
7957 /* IgnoreSubsumingPositions */ true))
7958 return ChangeStatus::UNCHANGED;
7959
7960 // Check if we would improve the existing attributes first.
7961 SmallVector<Attribute, 4> DeducedAttrs;
7962 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7963 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7964 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7965 /* IgnoreSubsumingPositions */ true);
7966 }))
7967 return ChangeStatus::UNCHANGED;
7968
7969 // Clear existing attributes.
7970 A.removeAttrs(IRP, AttrKinds);
7971 // Clear conflicting writable attribute.
7972 if (isAssumedReadOnly())
7973 A.removeAttrs(IRP, Attribute::Writable);
7974
7975 // Use the generic manifest method.
7976 return IRAttribute::manifest(A);
7977 }
7978
7979 /// See AbstractState::getAsStr().
7980 const std::string getAsStr(Attributor *A) const override {
7981 if (isAssumedReadNone())
7982 return "readnone";
7983 if (isAssumedReadOnly())
7984 return "readonly";
7985 if (isAssumedWriteOnly())
7986 return "writeonly";
7987 return "may-read/write";
7988 }
7989
7990 /// The set of IR attributes AAMemoryBehavior deals with.
7991 static const Attribute::AttrKind AttrKinds[3];
7992};
7993
7994const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7995 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7996
7997/// Memory behavior attribute for a floating value.
7998struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7999 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8000 : AAMemoryBehaviorImpl(IRP, A) {}
8001
8002 /// See AbstractAttribute::updateImpl(...).
8003 ChangeStatus updateImpl(Attributor &A) override;
8004
8005 /// See AbstractAttribute::trackStatistics()
8006 void trackStatistics() const override {
8007 if (isAssumedReadNone())
8009 else if (isAssumedReadOnly())
8011 else if (isAssumedWriteOnly())
8013 }
8014
8015private:
8016 /// Return true if users of \p UserI might access the underlying
8017 /// variable/location described by \p U and should therefore be analyzed.
8018 bool followUsersOfUseIn(Attributor &A, const Use &U,
8019 const Instruction *UserI);
8020
8021 /// Update the state according to the effect of use \p U in \p UserI.
8022 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8023};
8024
8025/// Memory behavior attribute for function argument.
8026struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8027 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8028 : AAMemoryBehaviorFloating(IRP, A) {}
8029
8030 /// See AbstractAttribute::initialize(...).
8031 void initialize(Attributor &A) override {
8032 intersectAssumedBits(BEST_STATE);
8033 const IRPosition &IRP = getIRPosition();
8034 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8035 // can query it when we use has/getAttr. That would allow us to reuse the
8036 // initialize of the base class here.
8037 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8038 /* IgnoreSubsumingPositions */ true);
8039 getKnownStateFromValue(A, IRP, getState(),
8040 /* IgnoreSubsumingPositions */ HasByVal);
8041 }
8042
8043 ChangeStatus manifest(Attributor &A) override {
8044 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8045 if (!getAssociatedValue().getType()->isPointerTy())
8046 return ChangeStatus::UNCHANGED;
8047
8048 // TODO: From readattrs.ll: "inalloca parameters are always
8049 // considered written"
8050 if (A.hasAttr(getIRPosition(),
8051 {Attribute::InAlloca, Attribute::Preallocated})) {
8052 removeKnownBits(NO_WRITES);
8053 removeAssumedBits(NO_WRITES);
8054 }
8055 A.removeAttrs(getIRPosition(), AttrKinds);
8056 return AAMemoryBehaviorFloating::manifest(A);
8057 }
8058
8059 /// See AbstractAttribute::trackStatistics()
8060 void trackStatistics() const override {
8061 if (isAssumedReadNone())
8062 STATS_DECLTRACK_ARG_ATTR(readnone)
8063 else if (isAssumedReadOnly())
8064 STATS_DECLTRACK_ARG_ATTR(readonly)
8065 else if (isAssumedWriteOnly())
8066 STATS_DECLTRACK_ARG_ATTR(writeonly)
8067 }
8068};
8069
8070struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8071 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8072 : AAMemoryBehaviorArgument(IRP, A) {}
8073
8074 /// See AbstractAttribute::initialize(...).
8075 void initialize(Attributor &A) override {
8076 // If we don't have an associated attribute this is either a variadic call
8077 // or an indirect call, either way, nothing to do here.
8078 Argument *Arg = getAssociatedArgument();
8079 if (!Arg) {
8080 indicatePessimisticFixpoint();
8081 return;
8082 }
8083 if (Arg->hasByValAttr()) {
8084 addKnownBits(NO_WRITES);
8085 removeKnownBits(NO_READS);
8086 removeAssumedBits(NO_READS);
8087 }
8088 AAMemoryBehaviorArgument::initialize(A);
8089 if (getAssociatedFunction()->isDeclaration())
8090 indicatePessimisticFixpoint();
8091 }
8092
8093 /// See AbstractAttribute::updateImpl(...).
8094 ChangeStatus updateImpl(Attributor &A) override {
8095 // TODO: Once we have call site specific value information we can provide
8096 // call site specific liveness liveness information and then it makes
8097 // sense to specialize attributes for call sites arguments instead of
8098 // redirecting requests to the callee argument.
8099 Argument *Arg = getAssociatedArgument();
8100 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8101 auto *ArgAA =
8102 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8103 if (!ArgAA)
8104 return indicatePessimisticFixpoint();
8105 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8106 }
8107
8108 /// See AbstractAttribute::trackStatistics()
8109 void trackStatistics() const override {
8110 if (isAssumedReadNone())
8112 else if (isAssumedReadOnly())
8114 else if (isAssumedWriteOnly())
8116 }
8117};
8118
8119/// Memory behavior attribute for a call site return position.
8120struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8121 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8122 : AAMemoryBehaviorFloating(IRP, A) {}
8123
8124 /// See AbstractAttribute::initialize(...).
8125 void initialize(Attributor &A) override {
8126 AAMemoryBehaviorImpl::initialize(A);
8127 }
8128 /// See AbstractAttribute::manifest(...).
8129 ChangeStatus manifest(Attributor &A) override {
8130 // We do not annotate returned values.
8131 return ChangeStatus::UNCHANGED;
8132 }
8133
8134 /// See AbstractAttribute::trackStatistics()
8135 void trackStatistics() const override {}
8136};
8137
8138/// An AA to represent the memory behavior function attributes.
8139struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8140 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8141 : AAMemoryBehaviorImpl(IRP, A) {}
8142
8143 /// See AbstractAttribute::updateImpl(Attributor &A).
8144 ChangeStatus updateImpl(Attributor &A) override;
8145
8146 /// See AbstractAttribute::manifest(...).
8147 ChangeStatus manifest(Attributor &A) override {
8148 // TODO: It would be better to merge this with AAMemoryLocation, so that
8149 // we could determine read/write per location. This would also have the
8150 // benefit of only one place trying to manifest the memory attribute.
8151 Function &F = cast<Function>(getAnchorValue());
8153 if (isAssumedReadNone())
8154 ME = MemoryEffects::none();
8155 else if (isAssumedReadOnly())
8157 else if (isAssumedWriteOnly())
8159
8160 A.removeAttrs(getIRPosition(), AttrKinds);
8161 // Clear conflicting writable attribute.
8162 if (ME.onlyReadsMemory())
8163 for (Argument &Arg : F.args())
8164 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8165 return A.manifestAttrs(getIRPosition(),
8166 Attribute::getWithMemoryEffects(F.getContext(), ME));
8167 }
8168
8169 /// See AbstractAttribute::trackStatistics()
8170 void trackStatistics() const override {
8171 if (isAssumedReadNone())
8172 STATS_DECLTRACK_FN_ATTR(readnone)
8173 else if (isAssumedReadOnly())
8174 STATS_DECLTRACK_FN_ATTR(readonly)
8175 else if (isAssumedWriteOnly())
8176 STATS_DECLTRACK_FN_ATTR(writeonly)
8177 }
8178};
8179
8180/// AAMemoryBehavior attribute for call sites.
8181struct AAMemoryBehaviorCallSite final
8182 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8183 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8184 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8185
8186 /// See AbstractAttribute::manifest(...).
8187 ChangeStatus manifest(Attributor &A) override {
8188 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8189 CallBase &CB = cast<CallBase>(getAnchorValue());
8191 if (isAssumedReadNone())
8192 ME = MemoryEffects::none();
8193 else if (isAssumedReadOnly())
8195 else if (isAssumedWriteOnly())
8197
8198 A.removeAttrs(getIRPosition(), AttrKinds);
8199 // Clear conflicting writable attribute.
8200 if (ME.onlyReadsMemory())
8201 for (Use &U : CB.args())
8202 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8203 Attribute::Writable);
8204 return A.manifestAttrs(
8205 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8206 }
8207
8208 /// See AbstractAttribute::trackStatistics()
8209 void trackStatistics() const override {
8210 if (isAssumedReadNone())
8211 STATS_DECLTRACK_CS_ATTR(readnone)
8212 else if (isAssumedReadOnly())
8213 STATS_DECLTRACK_CS_ATTR(readonly)
8214 else if (isAssumedWriteOnly())
8215 STATS_DECLTRACK_CS_ATTR(writeonly)
8216 }
8217};
8218
8219ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8220
8221 // The current assumed state used to determine a change.
8222 auto AssumedState = getAssumed();
8223
8224 auto CheckRWInst = [&](Instruction &I) {
8225 // If the instruction has an own memory behavior state, use it to restrict
8226 // the local state. No further analysis is required as the other memory
8227 // state is as optimistic as it gets.
8228 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8229 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8231 if (MemBehaviorAA) {
8232 intersectAssumedBits(MemBehaviorAA->getAssumed());
8233 return !isAtFixpoint();
8234 }
8235 }
8236
8237 // Remove access kind modifiers if necessary.
8238 if (I.mayReadFromMemory())
8239 removeAssumedBits(NO_READS);
8240 if (I.mayWriteToMemory())
8241 removeAssumedBits(NO_WRITES);
8242 return !isAtFixpoint();
8243 };
8244
8245 bool UsedAssumedInformation = false;
8246 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8247 UsedAssumedInformation))
8248 return indicatePessimisticFixpoint();
8249
8250 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8252}
8253
8254ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8255
8256 const IRPosition &IRP = getIRPosition();
8257 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8258 AAMemoryBehavior::StateType &S = getState();
8259
8260 // First, check the function scope. We take the known information and we avoid
8261 // work if the assumed information implies the current assumed information for
8262 // this attribute. This is a valid for all but byval arguments.
8263 Argument *Arg = IRP.getAssociatedArgument();
8264 AAMemoryBehavior::base_t FnMemAssumedState =
8266 if (!Arg || !Arg->hasByValAttr()) {
8267 const auto *FnMemAA =
8268 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8269 if (FnMemAA) {
8270 FnMemAssumedState = FnMemAA->getAssumed();
8271 S.addKnownBits(FnMemAA->getKnown());
8272 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8274 }
8275 }
8276
8277 // The current assumed state used to determine a change.
8278 auto AssumedState = S.getAssumed();
8279
8280 // Make sure the value is not captured (except through "return"), if
8281 // it is, any information derived would be irrelevant anyway as we cannot
8282 // check the potential aliases introduced by the capture. However, no need
8283 // to fall back to anythign less optimistic than the function state.
8284 bool IsKnownNoCapture;
8285 const AANoCapture *ArgNoCaptureAA = nullptr;
8286 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8287 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8288 &ArgNoCaptureAA);
8289
8290 if (!IsAssumedNoCapture &&
8291 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8292 S.intersectAssumedBits(FnMemAssumedState);
8293 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8295 }
8296
8297 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8298 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8299 Instruction *UserI = cast<Instruction>(U.getUser());
8300 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8301 << " \n");
8302
8303 // Droppable users, e.g., llvm::assume does not actually perform any action.
8304 if (UserI->isDroppable())
8305 return true;
8306
8307 // Check if the users of UserI should also be visited.
8308 Follow = followUsersOfUseIn(A, U, UserI);
8309
8310 // If UserI might touch memory we analyze the use in detail.
8311 if (UserI->mayReadOrWriteMemory())
8312 analyzeUseIn(A, U, UserI);
8313
8314 return !isAtFixpoint();
8315 };
8316
8317 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8318 return indicatePessimisticFixpoint();
8319
8320 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8322}
8323
8324bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8325 const Instruction *UserI) {
8326 // The loaded value is unrelated to the pointer argument, no need to
8327 // follow the users of the load.
8328 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8329 return false;
8330
8331 // By default we follow all uses assuming UserI might leak information on U,
8332 // we have special handling for call sites operands though.
8333 const auto *CB = dyn_cast<CallBase>(UserI);
8334 if (!CB || !CB->isArgOperand(&U))
8335 return true;
8336
8337 // If the use is a call argument known not to be captured, the users of
8338 // the call do not need to be visited because they have to be unrelated to
8339 // the input. Note that this check is not trivial even though we disallow
8340 // general capturing of the underlying argument. The reason is that the
8341 // call might the argument "through return", which we allow and for which we
8342 // need to check call users.
8343 if (U.get()->getType()->isPointerTy()) {
8344 unsigned ArgNo = CB->getArgOperandNo(&U);
8345 bool IsKnownNoCapture;
8347 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8348 DepClassTy::OPTIONAL, IsKnownNoCapture);
8349 }
8350
8351 return true;
8352}
8353
8354void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8355 const Instruction *UserI) {
8356 assert(UserI->mayReadOrWriteMemory());
8357
8358 switch (UserI->getOpcode()) {
8359 default:
8360 // TODO: Handle all atomics and other side-effect operations we know of.
8361 break;
8362 case Instruction::Load:
8363 // Loads cause the NO_READS property to disappear.
8364 removeAssumedBits(NO_READS);
8365 return;
8366
8367 case Instruction::Store:
8368 // Stores cause the NO_WRITES property to disappear if the use is the
8369 // pointer operand. Note that while capturing was taken care of somewhere
8370 // else we need to deal with stores of the value that is not looked through.
8371 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8372 removeAssumedBits(NO_WRITES);
8373 else
8374 indicatePessimisticFixpoint();
8375 return;
8376
8377 case Instruction::Call:
8378 case Instruction::CallBr:
8379 case Instruction::Invoke: {
8380 // For call sites we look at the argument memory behavior attribute (this
8381 // could be recursive!) in order to restrict our own state.
8382 const auto *CB = cast<CallBase>(UserI);
8383
8384 // Give up on operand bundles.
8385 if (CB->isBundleOperand(&U)) {
8386 indicatePessimisticFixpoint();
8387 return;
8388 }
8389
8390 // Calling a function does read the function pointer, maybe write it if the
8391 // function is self-modifying.
8392 if (CB->isCallee(&U)) {
8393 removeAssumedBits(NO_READS);
8394 break;
8395 }
8396
8397 // Adjust the possible access behavior based on the information on the
8398 // argument.
8399 IRPosition Pos;
8400 if (U.get()->getType()->isPointerTy())
8402 else
8404 const auto *MemBehaviorAA =
8405 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8406 if (!MemBehaviorAA)
8407 break;
8408 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8409 // and at least "known".
8410 intersectAssumedBits(MemBehaviorAA->getAssumed());
8411 return;
8412 }
8413 };
8414
8415 // Generally, look at the "may-properties" and adjust the assumed state if we
8416 // did not trigger special handling before.
8417 if (UserI->mayReadFromMemory())
8418 removeAssumedBits(NO_READS);
8419 if (UserI->mayWriteToMemory())
8420 removeAssumedBits(NO_WRITES);
8421}
8422} // namespace
8423
8424/// -------------------- Memory Locations Attributes ---------------------------
8425/// Includes read-none, argmemonly, inaccessiblememonly,
8426/// inaccessiblememorargmemonly
8427/// ----------------------------------------------------------------------------
8428
8431 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8432 return "all memory";
8434 return "no memory";
8435 std::string S = "memory:";
8436 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8437 S += "stack,";
8438 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8439 S += "constant,";
8441 S += "internal global,";
8443 S += "external global,";
8444 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8445 S += "argument,";
8447 S += "inaccessible,";
8448 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8449 S += "malloced,";
8450 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8451 S += "unknown,";
8452 S.pop_back();
8453 return S;
8454}
8455
8456namespace {
8457struct AAMemoryLocationImpl : public AAMemoryLocation {
8458
8459 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8460 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8461 AccessKind2Accesses.fill(nullptr);
8462 }
8463
8464 ~AAMemoryLocationImpl() override {
8465 // The AccessSets are allocated via a BumpPtrAllocator, we call
8466 // the destructor manually.
8467 for (AccessSet *AS : AccessKind2Accesses)
8468 if (AS)
8469 AS->~AccessSet();
8470 }
8471
8472 /// See AbstractAttribute::initialize(...).
8473 void initialize(Attributor &A) override {
8474 intersectAssumedBits(BEST_STATE);
8475 getKnownStateFromValue(A, getIRPosition(), getState());
8476 AAMemoryLocation::initialize(A);
8477 }
8478
8479 /// Return the memory behavior information encoded in the IR for \p IRP.
8480 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8481 BitIntegerState &State,
8482 bool IgnoreSubsumingPositions = false) {
8483 // For internal functions we ignore `argmemonly` and
8484 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8485 // constant propagation. It is unclear if this is the best way but it is
8486 // unlikely this will cause real performance problems. If we are deriving
8487 // attributes for the anchor function we even remove the attribute in
8488 // addition to ignoring it.
8489 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8490 // MemoryEffects::Other as a possible location.
8491 bool UseArgMemOnly = true;
8492 Function *AnchorFn = IRP.getAnchorScope();
8493 if (AnchorFn && A.isRunOn(*AnchorFn))
8494 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8495
8497 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8498 for (const Attribute &Attr : Attrs) {
8499 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8500 MemoryEffects ME = Attr.getMemoryEffects();
8501 if (ME.doesNotAccessMemory()) {
8502 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8503 continue;
8504 }
8505 if (ME.onlyAccessesInaccessibleMem()) {
8506 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8507 continue;
8508 }
8509 if (ME.onlyAccessesArgPointees()) {
8510 if (UseArgMemOnly)
8511 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8512 else {
8513 // Remove location information, only keep read/write info.
8514 ME = MemoryEffects(ME.getModRef());
8515 A.manifestAttrs(IRP,
8516 Attribute::getWithMemoryEffects(
8517 IRP.getAnchorValue().getContext(), ME),
8518 /*ForceReplace*/ true);
8519 }
8520 continue;
8521 }
8523 if (UseArgMemOnly)
8524 State.addKnownBits(inverseLocation(
8525 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8526 else {
8527 // Remove location information, only keep read/write info.
8528 ME = MemoryEffects(ME.getModRef());
8529 A.manifestAttrs(IRP,
8530 Attribute::getWithMemoryEffects(
8531 IRP.getAnchorValue().getContext(), ME),
8532 /*ForceReplace*/ true);
8533 }
8534 continue;
8535 }
8536 }
8537 }
8538
8539 /// See AbstractAttribute::getDeducedAttributes(...).
8540 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8541 SmallVectorImpl<Attribute> &Attrs) const override {
8542 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8543 assert(Attrs.size() == 0);
8544 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8545 if (isAssumedReadNone())
8546 Attrs.push_back(
8547 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8548 else if (isAssumedInaccessibleMemOnly())
8549 Attrs.push_back(Attribute::getWithMemoryEffects(
8551 else if (isAssumedArgMemOnly())
8552 Attrs.push_back(
8553 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8554 else if (isAssumedInaccessibleOrArgMemOnly())
8555 Attrs.push_back(Attribute::getWithMemoryEffects(
8557 }
8558 assert(Attrs.size() <= 1);
8559 }
8560
8561 /// See AbstractAttribute::manifest(...).
8562 ChangeStatus manifest(Attributor &A) override {
8563 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8564 // provide per-location modref information here.
8565 const IRPosition &IRP = getIRPosition();
8566
8567 SmallVector<Attribute, 1> DeducedAttrs;
8568 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8569 if (DeducedAttrs.size() != 1)
8570 return ChangeStatus::UNCHANGED;
8571 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8572
8573 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8574 IRP.getAnchorValue().getContext(), ME));
8575 }
8576
8577 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8578 bool checkForAllAccessesToMemoryKind(
8579 function_ref<bool(const Instruction *, const Value *, AccessKind,
8580 MemoryLocationsKind)>
8581 Pred,
8582 MemoryLocationsKind RequestedMLK) const override {
8583 if (!isValidState())
8584 return false;
8585
8586 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8587 if (AssumedMLK == NO_LOCATIONS)
8588 return true;
8589
8590 unsigned Idx = 0;
8591 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8592 CurMLK *= 2, ++Idx) {
8593 if (CurMLK & RequestedMLK)
8594 continue;
8595
8596 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8597 for (const AccessInfo &AI : *Accesses)
8598 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8599 return false;
8600 }
8601
8602 return true;
8603 }
8604
8605 ChangeStatus indicatePessimisticFixpoint() override {
8606 // If we give up and indicate a pessimistic fixpoint this instruction will
8607 // become an access for all potential access kinds:
8608 // TODO: Add pointers for argmemonly and globals to improve the results of
8609 // checkForAllAccessesToMemoryKind.
8610 bool Changed = false;
8611 MemoryLocationsKind KnownMLK = getKnown();
8612 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8613 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8614 if (!(CurMLK & KnownMLK))
8615 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8616 getAccessKindFromInst(I));
8617 return AAMemoryLocation::indicatePessimisticFixpoint();
8618 }
8619
8620protected:
8621 /// Helper struct to tie together an instruction that has a read or write
8622 /// effect with the pointer it accesses (if any).
8623 struct AccessInfo {
8624
8625 /// The instruction that caused the access.
8626 const Instruction *I;
8627
8628 /// The base pointer that is accessed, or null if unknown.
8629 const Value *Ptr;
8630
8631 /// The kind of access (read/write/read+write).
8633
8634 bool operator==(const AccessInfo &RHS) const {
8635 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8636 }
8637 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8638 if (LHS.I != RHS.I)
8639 return LHS.I < RHS.I;
8640 if (LHS.Ptr != RHS.Ptr)
8641 return LHS.Ptr < RHS.Ptr;
8642 if (LHS.Kind != RHS.Kind)
8643 return LHS.Kind < RHS.Kind;
8644 return false;
8645 }
8646 };
8647
8648 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8649 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8650 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8651 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8652 AccessKind2Accesses;
8653
8654 /// Categorize the pointer arguments of CB that might access memory in
8655 /// AccessedLoc and update the state and access map accordingly.
8656 void
8657 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8658 AAMemoryLocation::StateType &AccessedLocs,
8659 bool &Changed);
8660
8661 /// Return the kind(s) of location that may be accessed by \p V.
8663 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8664
8665 /// Return the access kind as determined by \p I.
8666 AccessKind getAccessKindFromInst(const Instruction *I) {
8667 AccessKind AK = READ_WRITE;
8668 if (I) {
8669 AK = I->mayReadFromMemory() ? READ : NONE;
8670 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8671 }
8672 return AK;
8673 }
8674
8675 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8676 /// an access of kind \p AK to a \p MLK memory location with the access
8677 /// pointer \p Ptr.
8678 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8679 MemoryLocationsKind MLK, const Instruction *I,
8680 const Value *Ptr, bool &Changed,
8681 AccessKind AK = READ_WRITE) {
8682
8683 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8684 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8685 if (!Accesses)
8686 Accesses = new (Allocator) AccessSet();
8687 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8688 if (MLK == NO_UNKOWN_MEM)
8689 MLK = NO_LOCATIONS;
8690 State.removeAssumedBits(MLK);
8691 }
8692
8693 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8694 /// arguments, and update the state and access map accordingly.
8695 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8696 AAMemoryLocation::StateType &State, bool &Changed,
8697 unsigned AccessAS = 0);
8698
8699 /// Used to allocate access sets.
8701};
8702
8703void AAMemoryLocationImpl::categorizePtrValue(
8704 Attributor &A, const Instruction &I, const Value &Ptr,
8705 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8706 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8707 << Ptr << " ["
8708 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8709
8710 auto Pred = [&](Value &Obj) {
8711 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8712 // TODO: recognize the TBAA used for constant accesses.
8713 MemoryLocationsKind MLK = NO_LOCATIONS;
8714
8715 // Filter accesses to constant (GPU) memory if we have an AS at the access
8716 // site or the object is known to actually have the associated AS.
8717 if (AA::isGPU(A.getModule())) {
8718 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8719 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8720 isIdentifiedObject(&Obj)))
8721 return true;
8722 }
8723
8724 if (isa<UndefValue>(&Obj))
8725 return true;
8726 if (isa<Argument>(&Obj)) {
8727 // TODO: For now we do not treat byval arguments as local copies performed
8728 // on the call edge, though, we should. To make that happen we need to
8729 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8730 // would also allow us to mark functions only accessing byval arguments as
8731 // readnone again, arguably their accesses have no effect outside of the
8732 // function, like accesses to allocas.
8733 MLK = NO_ARGUMENT_MEM;
8734 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8735 // Reading constant memory is not treated as a read "effect" by the
8736 // function attr pass so we won't neither. Constants defined by TBAA are
8737 // similar. (We know we do not write it because it is constant.)
8738 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8739 if (GVar->isConstant())
8740 return true;
8741
8742 if (GV->hasLocalLinkage())
8743 MLK = NO_GLOBAL_INTERNAL_MEM;
8744 else
8745 MLK = NO_GLOBAL_EXTERNAL_MEM;
8746 } else if (isa<ConstantPointerNull>(&Obj) &&
8747 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8748 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8749 return true;
8750 } else if (isa<AllocaInst>(&Obj)) {
8751 MLK = NO_LOCAL_MEM;
8752 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8753 bool IsKnownNoAlias;
8756 IsKnownNoAlias))
8757 MLK = NO_MALLOCED_MEM;
8758 else
8759 MLK = NO_UNKOWN_MEM;
8760 } else {
8761 MLK = NO_UNKOWN_MEM;
8762 }
8763
8764 assert(MLK != NO_LOCATIONS && "No location specified!");
8765 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8766 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8767 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8768 getAccessKindFromInst(&I));
8769
8770 return true;
8771 };
8772
8773 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8775 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8776 LLVM_DEBUG(
8777 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8778 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8779 getAccessKindFromInst(&I));
8780 return;
8781 }
8782
8783 LLVM_DEBUG(
8784 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8785 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8786}
8787
8788void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8789 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8790 bool &Changed) {
8791 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8792
8793 // Skip non-pointer arguments.
8794 const Value *ArgOp = CB.getArgOperand(ArgNo);
8795 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8796 continue;
8797
8798 // Skip readnone arguments.
8799 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8800 const auto *ArgOpMemLocationAA =
8801 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8802
8803 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8804 continue;
8805
8806 // Categorize potentially accessed pointer arguments as if there was an
8807 // access instruction with them as pointer.
8808 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8809 }
8810}
8811
8813AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8814 bool &Changed) {
8815 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8816 << I << "\n");
8817
8818 AAMemoryLocation::StateType AccessedLocs;
8819 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8820
8821 if (auto *CB = dyn_cast<CallBase>(&I)) {
8822
8823 // First check if we assume any memory is access is visible.
8824 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8826 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8827 << " [" << CBMemLocationAA << "]\n");
8828 if (!CBMemLocationAA) {
8829 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8830 Changed, getAccessKindFromInst(&I));
8831 return NO_UNKOWN_MEM;
8832 }
8833
8834 if (CBMemLocationAA->isAssumedReadNone())
8835 return NO_LOCATIONS;
8836
8837 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8838 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8839 Changed, getAccessKindFromInst(&I));
8840 return AccessedLocs.getAssumed();
8841 }
8842
8843 uint32_t CBAssumedNotAccessedLocs =
8844 CBMemLocationAA->getAssumedNotAccessedLocation();
8845
8846 // Set the argmemonly and global bit as we handle them separately below.
8847 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8848 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8849
8850 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8851 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8852 continue;
8853 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8854 getAccessKindFromInst(&I));
8855 }
8856
8857 // Now handle global memory if it might be accessed. This is slightly tricky
8858 // as NO_GLOBAL_MEM has multiple bits set.
8859 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8860 if (HasGlobalAccesses) {
8861 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8862 AccessKind Kind, MemoryLocationsKind MLK) {
8863 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8864 getAccessKindFromInst(&I));
8865 return true;
8866 };
8867 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8868 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8869 return AccessedLocs.getWorstState();
8870 }
8871
8872 LLVM_DEBUG(
8873 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8874 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8875
8876 // Now handle argument memory if it might be accessed.
8877 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8878 if (HasArgAccesses)
8879 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8880
8881 LLVM_DEBUG(
8882 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8883 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8884
8885 return AccessedLocs.getAssumed();
8886 }
8887
8888 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8889 LLVM_DEBUG(
8890 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8891 << I << " [" << *Ptr << "]\n");
8892 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8893 Ptr->getType()->getPointerAddressSpace());
8894 return AccessedLocs.getAssumed();
8895 }
8896
8897 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8898 << I << "\n");
8899 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8900 getAccessKindFromInst(&I));
8901 return AccessedLocs.getAssumed();
8902}
8903
8904/// An AA to represent the memory behavior function attributes.
8905struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8906 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8907 : AAMemoryLocationImpl(IRP, A) {}
8908
8909 /// See AbstractAttribute::updateImpl(Attributor &A).
8910 ChangeStatus updateImpl(Attributor &A) override {
8911
8912 const auto *MemBehaviorAA =
8913 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8914 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8915 if (MemBehaviorAA->isKnownReadNone())
8916 return indicateOptimisticFixpoint();
8918 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8919 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8920 return ChangeStatus::UNCHANGED;
8921 }
8922
8923 // The current assumed state used to determine a change.
8924 auto AssumedState = getAssumed();
8925 bool Changed = false;
8926
8927 auto CheckRWInst = [&](Instruction &I) {
8928 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8929 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8930 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8931 removeAssumedBits(inverseLocation(MLK, false, false));
8932 // Stop once only the valid bit set in the *not assumed location*, thus
8933 // once we don't actually exclude any memory locations in the state.
8934 return getAssumedNotAccessedLocation() != VALID_STATE;
8935 };
8936
8937 bool UsedAssumedInformation = false;
8938 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8939 UsedAssumedInformation))
8940 return indicatePessimisticFixpoint();
8941
8942 Changed |= AssumedState != getAssumed();
8943 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8944 }
8945
8946 /// See AbstractAttribute::trackStatistics()
8947 void trackStatistics() const override {
8948 if (isAssumedReadNone())
8949 STATS_DECLTRACK_FN_ATTR(readnone)
8950 else if (isAssumedArgMemOnly())
8951 STATS_DECLTRACK_FN_ATTR(argmemonly)
8952 else if (isAssumedInaccessibleMemOnly())
8953 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8954 else if (isAssumedInaccessibleOrArgMemOnly())
8955 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8956 }
8957};
8958
8959/// AAMemoryLocation attribute for call sites.
8960struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8961 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8962 : AAMemoryLocationImpl(IRP, A) {}
8963
8964 /// See AbstractAttribute::updateImpl(...).
8965 ChangeStatus updateImpl(Attributor &A) override {
8966 // TODO: Once we have call site specific value information we can provide
8967 // call site specific liveness liveness information and then it makes
8968 // sense to specialize attributes for call sites arguments instead of
8969 // redirecting requests to the callee argument.
8970 Function *F = getAssociatedFunction();
8971 const IRPosition &FnPos = IRPosition::function(*F);
8972 auto *FnAA =
8973 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8974 if (!FnAA)
8975 return indicatePessimisticFixpoint();
8976 bool Changed = false;
8977 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8978 AccessKind Kind, MemoryLocationsKind MLK) {
8979 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8980 getAccessKindFromInst(I));
8981 return true;
8982 };
8983 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8984 return indicatePessimisticFixpoint();
8985 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8986 }
8987
8988 /// See AbstractAttribute::trackStatistics()
8989 void trackStatistics() const override {
8990 if (isAssumedReadNone())
8991 STATS_DECLTRACK_CS_ATTR(readnone)
8992 }
8993};
8994} // namespace
8995
8996/// ------------------ denormal-fp-math Attribute -------------------------
8997
8998namespace {
8999struct AADenormalFPMathImpl : public AADenormalFPMath {
9000 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9001 : AADenormalFPMath(IRP, A) {}
9002
9003 const std::string getAsStr(Attributor *A) const override {
9004 std::string Str("AADenormalFPMath[");
9005 raw_string_ostream OS(Str);
9006
9007 DenormalState Known = getKnown();
9008 if (Known.Mode.isValid())
9009 OS << "denormal-fp-math=" << Known.Mode;
9010 else
9011 OS << "invalid";
9012
9013 if (Known.ModeF32.isValid())
9014 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9015 OS << ']';
9016 return Str;
9017 }
9018};
9019
9020struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9021 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9022 : AADenormalFPMathImpl(IRP, A) {}
9023
9024 void initialize(Attributor &A) override {
9025 const Function *F = getAnchorScope();
9026 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9027
9028 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9029 if (isModeFixed())
9030 indicateFixpoint();
9031 }
9032
9033 ChangeStatus updateImpl(Attributor &A) override {
9034 ChangeStatus Change = ChangeStatus::UNCHANGED;
9035
9036 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9037 Function *Caller = CS.getInstruction()->getFunction();
9038 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9039 << "->" << getAssociatedFunction()->getName() << '\n');
9040
9041 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9042 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9043 if (!CallerInfo)
9044 return false;
9045
9046 Change = Change | clampStateAndIndicateChange(this->getState(),
9047 CallerInfo->getState());
9048 return true;
9049 };
9050
9051 bool AllCallSitesKnown = true;
9052 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9053 return indicatePessimisticFixpoint();
9054
9055 if (Change == ChangeStatus::CHANGED && isModeFixed())
9056 indicateFixpoint();
9057 return Change;
9058 }
9059
9060 ChangeStatus manifest(Attributor &A) override {
9061 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9062
9063 SmallVector<Attribute, 2> AttrToAdd;
9065
9066 // TODO: Change to use DenormalFPEnv everywhere.
9067 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9068
9069 if (KnownEnv == DenormalFPEnv::getDefault()) {
9070 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9071 } else {
9072 AttrToAdd.push_back(Attribute::get(
9073 Ctx, Attribute::DenormalFPEnv,
9074 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9075 }
9076
9077 auto &IRP = getIRPosition();
9078
9079 // TODO: There should be a combined add and remove API.
9080 return A.removeAttrs(IRP, AttrToRemove) |
9081 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9082 }
9083
9084 void trackStatistics() const override {
9085 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9086 }
9087};
9088} // namespace
9089
9090/// ------------------ Value Constant Range Attribute -------------------------
9091
9092namespace {
9093struct AAValueConstantRangeImpl : AAValueConstantRange {
9094 using StateType = IntegerRangeState;
9095 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9096 : AAValueConstantRange(IRP, A) {}
9097
9098 /// See AbstractAttribute::initialize(..).
9099 void initialize(Attributor &A) override {
9100 if (A.hasSimplificationCallback(getIRPosition())) {
9101 indicatePessimisticFixpoint();
9102 return;
9103 }
9104
9105 // Intersect a range given by SCEV.
9106 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9107
9108 // Intersect a range given by LVI.
9109 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9110 }
9111
9112 /// See AbstractAttribute::getAsStr().
9113 const std::string getAsStr(Attributor *A) const override {
9114 std::string Str;
9115 llvm::raw_string_ostream OS(Str);
9116 OS << "range(" << getBitWidth() << ")<";
9117 getKnown().print(OS);
9118 OS << " / ";
9119 getAssumed().print(OS);
9120 OS << ">";
9121 return Str;
9122 }
9123
9124 /// Helper function to get a SCEV expr for the associated value at program
9125 /// point \p I.
9126 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9127 if (!getAnchorScope())
9128 return nullptr;
9129
9130 ScalarEvolution *SE =
9131 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9132 *getAnchorScope());
9133
9134 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9135 *getAnchorScope());
9136
9137 if (!SE || !LI)
9138 return nullptr;
9139
9140 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9141 if (!I)
9142 return S;
9143
9144 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9145 }
9146
9147 /// Helper function to get a range from SCEV for the associated value at
9148 /// program point \p I.
9149 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9150 const Instruction *I = nullptr) const {
9151 if (!getAnchorScope())
9152 return getWorstState(getBitWidth());
9153
9154 ScalarEvolution *SE =
9155 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9156 *getAnchorScope());
9157
9158 const SCEV *S = getSCEV(A, I);
9159 if (!SE || !S)
9160 return getWorstState(getBitWidth());
9161
9162 return SE->getUnsignedRange(S);
9163 }
9164
9165 /// Helper function to get a range from LVI for the associated value at
9166 /// program point \p I.
9167 ConstantRange
9168 getConstantRangeFromLVI(Attributor &A,
9169 const Instruction *CtxI = nullptr) const {
9170 if (!getAnchorScope())
9171 return getWorstState(getBitWidth());
9172
9173 LazyValueInfo *LVI =
9174 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9175 *getAnchorScope());
9176
9177 if (!LVI || !CtxI)
9178 return getWorstState(getBitWidth());
9179 return LVI->getConstantRange(&getAssociatedValue(),
9180 const_cast<Instruction *>(CtxI),
9181 /*UndefAllowed*/ false);
9182 }
9183
9184 /// Return true if \p CtxI is valid for querying outside analyses.
9185 /// This basically makes sure we do not ask intra-procedural analysis
9186 /// about a context in the wrong function or a context that violates
9187 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9188 /// if the original context of this AA is OK or should be considered invalid.
9189 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9190 const Instruction *CtxI,
9191 bool AllowAACtxI) const {
9192 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9193 return false;
9194
9195 // Our context might be in a different function, neither intra-procedural
9196 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9197 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9198 return false;
9199
9200 // If the context is not dominated by the value there are paths to the
9201 // context that do not define the value. This cannot be handled by
9202 // LazyValueInfo so we need to bail.
9203 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9204 InformationCache &InfoCache = A.getInfoCache();
9205 const DominatorTree *DT =
9206 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9207 *I->getFunction());
9208 return DT && DT->dominates(I, CtxI);
9209 }
9210
9211 return true;
9212 }
9213
9214 /// See AAValueConstantRange::getKnownConstantRange(..).
9215 ConstantRange
9216 getKnownConstantRange(Attributor &A,
9217 const Instruction *CtxI = nullptr) const override {
9218 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9219 /* AllowAACtxI */ false))
9220 return getKnown();
9221
9222 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9223 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9224 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9225 }
9226
9227 /// See AAValueConstantRange::getAssumedConstantRange(..).
9228 ConstantRange
9229 getAssumedConstantRange(Attributor &A,
9230 const Instruction *CtxI = nullptr) const override {
9231 // TODO: Make SCEV use Attributor assumption.
9232 // We may be able to bound a variable range via assumptions in
9233 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9234 // evolve to x^2 + x, then we can say that y is in [2, 12].
9235 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9236 /* AllowAACtxI */ false))
9237 return getAssumed();
9238
9239 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9240 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9241 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9242 }
9243
9244 /// Helper function to create MDNode for range metadata.
9245 static MDNode *
9246 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9247 const ConstantRange &AssumedConstantRange) {
9248 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9249 Ty, AssumedConstantRange.getLower())),
9250 ConstantAsMetadata::get(ConstantInt::get(
9251 Ty, AssumedConstantRange.getUpper()))};
9252 return MDNode::get(Ctx, LowAndHigh);
9253 }
9254
9255 /// Return true if \p Assumed is included in ranges from instruction \p I.
9256 static bool isBetterRange(const ConstantRange &Assumed,
9257 const Instruction &I) {
9258 if (Assumed.isFullSet())
9259 return false;
9260
9261 std::optional<ConstantRange> Known;
9262
9263 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9264 Known = CB->getRange();
9265 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9266 // If multiple ranges are annotated in IR, we give up to annotate assumed
9267 // range for now.
9268
9269 // TODO: If there exists a known range which containts assumed range, we
9270 // can say assumed range is better.
9271 if (KnownRanges->getNumOperands() > 2)
9272 return false;
9273
9274 ConstantInt *Lower =
9275 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9276 ConstantInt *Upper =
9277 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9278
9279 Known.emplace(Lower->getValue(), Upper->getValue());
9280 }
9281 return !Known || (*Known != Assumed && Known->contains(Assumed));
9282 }
9283
9284 /// Helper function to set range metadata.
9285 static bool
9286 setRangeMetadataIfisBetterRange(Instruction *I,
9287 const ConstantRange &AssumedConstantRange) {
9288 if (isBetterRange(AssumedConstantRange, *I)) {
9289 I->setMetadata(LLVMContext::MD_range,
9290 getMDNodeForConstantRange(I->getType(), I->getContext(),
9291 AssumedConstantRange));
9292 return true;
9293 }
9294 return false;
9295 }
9296 /// Helper function to set range return attribute.
9297 static bool
9298 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9299 Instruction *I,
9300 const ConstantRange &AssumedConstantRange) {
9301 if (isBetterRange(AssumedConstantRange, *I)) {
9302 A.manifestAttrs(IRP,
9303 Attribute::get(I->getContext(), Attribute::Range,
9304 AssumedConstantRange),
9305 /*ForceReplace*/ true);
9306 return true;
9307 }
9308 return false;
9309 }
9310
9311 /// See AbstractAttribute::manifest()
9312 ChangeStatus manifest(Attributor &A) override {
9313 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9314 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9315 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9316
9317 auto &V = getAssociatedValue();
9318 if (!AssumedConstantRange.isEmptySet() &&
9319 !AssumedConstantRange.isSingleElement()) {
9320 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9321 assert(I == getCtxI() && "Should not annotate an instruction which is "
9322 "not the context instruction");
9323 if (isa<LoadInst>(I))
9324 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9325 Changed = ChangeStatus::CHANGED;
9326 if (isa<CallInst>(I))
9327 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9328 AssumedConstantRange))
9329 Changed = ChangeStatus::CHANGED;
9330 }
9331 }
9332
9333 return Changed;
9334 }
9335};
9336
9337struct AAValueConstantRangeArgument final
9338 : AAArgumentFromCallSiteArguments<
9339 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9340 true /* BridgeCallBaseContext */> {
9341 using Base = AAArgumentFromCallSiteArguments<
9342 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9343 true /* BridgeCallBaseContext */>;
9344 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9345 : Base(IRP, A) {}
9346
9347 /// See AbstractAttribute::trackStatistics()
9348 void trackStatistics() const override {
9349 STATS_DECLTRACK_ARG_ATTR(value_range)
9350 }
9351};
9352
9353struct AAValueConstantRangeReturned
9354 : AAReturnedFromReturnedValues<AAValueConstantRange,
9355 AAValueConstantRangeImpl,
9356 AAValueConstantRangeImpl::StateType,
9357 /* PropagateCallBaseContext */ true> {
9358 using Base =
9359 AAReturnedFromReturnedValues<AAValueConstantRange,
9360 AAValueConstantRangeImpl,
9361 AAValueConstantRangeImpl::StateType,
9362 /* PropagateCallBaseContext */ true>;
9363 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9364 : Base(IRP, A) {}
9365
9366 /// See AbstractAttribute::initialize(...).
9367 void initialize(Attributor &A) override {
9368 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9369 indicatePessimisticFixpoint();
9370 }
9371
9372 /// See AbstractAttribute::trackStatistics()
9373 void trackStatistics() const override {
9374 STATS_DECLTRACK_FNRET_ATTR(value_range)
9375 }
9376};
9377
9378struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9379 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9380 : AAValueConstantRangeImpl(IRP, A) {}
9381
9382 /// See AbstractAttribute::initialize(...).
9383 void initialize(Attributor &A) override {
9384 AAValueConstantRangeImpl::initialize(A);
9385 if (isAtFixpoint())
9386 return;
9387
9388 Value &V = getAssociatedValue();
9389
9390 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9391 unionAssumed(ConstantRange(C->getValue()));
9392 indicateOptimisticFixpoint();
9393 return;
9394 }
9395
9396 if (isa<UndefValue>(&V)) {
9397 // Collapse the undef state to 0.
9398 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9399 indicateOptimisticFixpoint();
9400 return;
9401 }
9402
9403 if (isa<CallBase>(&V))
9404 return;
9405
9406 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9407 return;
9408
9409 // If it is a load instruction with range metadata, use it.
9410 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9411 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9412 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9413 return;
9414 }
9415
9416 // We can work with PHI and select instruction as we traverse their operands
9417 // during update.
9418 if (isa<SelectInst>(V) || isa<PHINode>(V))
9419 return;
9420
9421 // Otherwise we give up.
9422 indicatePessimisticFixpoint();
9423
9424 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9425 << getAssociatedValue() << "\n");
9426 }
9427
9428 bool calculateBinaryOperator(
9429 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9430 const Instruction *CtxI,
9431 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9432 Value *LHS = BinOp->getOperand(0);
9433 Value *RHS = BinOp->getOperand(1);
9434
9435 // Simplify the operands first.
9436 bool UsedAssumedInformation = false;
9437 const auto &SimplifiedLHS = A.getAssumedSimplified(
9438 IRPosition::value(*LHS, getCallBaseContext()), *this,
9439 UsedAssumedInformation, AA::Interprocedural);
9440 if (!SimplifiedLHS.has_value())
9441 return true;
9442 if (!*SimplifiedLHS)
9443 return false;
9444 LHS = *SimplifiedLHS;
9445
9446 const auto &SimplifiedRHS = A.getAssumedSimplified(
9447 IRPosition::value(*RHS, getCallBaseContext()), *this,
9448 UsedAssumedInformation, AA::Interprocedural);
9449 if (!SimplifiedRHS.has_value())
9450 return true;
9451 if (!*SimplifiedRHS)
9452 return false;
9453 RHS = *SimplifiedRHS;
9454
9455 // TODO: Allow non integers as well.
9456 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9457 return false;
9458
9459 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9460 *this, IRPosition::value(*LHS, getCallBaseContext()),
9461 DepClassTy::REQUIRED);
9462 if (!LHSAA)
9463 return false;
9464 QuerriedAAs.push_back(LHSAA);
9465 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9466
9467 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9468 *this, IRPosition::value(*RHS, getCallBaseContext()),
9469 DepClassTy::REQUIRED);
9470 if (!RHSAA)
9471 return false;
9472 QuerriedAAs.push_back(RHSAA);
9473 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9474
9475 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9476
9477 T.unionAssumed(AssumedRange);
9478
9479 // TODO: Track a known state too.
9480
9481 return T.isValidState();
9482 }
9483
9484 bool calculateCastInst(
9485 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9486 const Instruction *CtxI,
9487 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9488 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9489 // TODO: Allow non integers as well.
9490 Value *OpV = CastI->getOperand(0);
9491
9492 // Simplify the operand first.
9493 bool UsedAssumedInformation = false;
9494 const auto &SimplifiedOpV = A.getAssumedSimplified(
9495 IRPosition::value(*OpV, getCallBaseContext()), *this,
9496 UsedAssumedInformation, AA::Interprocedural);
9497 if (!SimplifiedOpV.has_value())
9498 return true;
9499 if (!*SimplifiedOpV)
9500 return false;
9501 OpV = *SimplifiedOpV;
9502
9503 if (!OpV->getType()->isIntegerTy())
9504 return false;
9505
9506 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9507 *this, IRPosition::value(*OpV, getCallBaseContext()),
9508 DepClassTy::REQUIRED);
9509 if (!OpAA)
9510 return false;
9511 QuerriedAAs.push_back(OpAA);
9512 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9513 getState().getBitWidth()));
9514 return T.isValidState();
9515 }
9516
9517 bool
9518 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9519 const Instruction *CtxI,
9520 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9521 Value *LHS = CmpI->getOperand(0);
9522 Value *RHS = CmpI->getOperand(1);
9523
9524 // Simplify the operands first.
9525 bool UsedAssumedInformation = false;
9526 const auto &SimplifiedLHS = A.getAssumedSimplified(
9527 IRPosition::value(*LHS, getCallBaseContext()), *this,
9528 UsedAssumedInformation, AA::Interprocedural);
9529 if (!SimplifiedLHS.has_value())
9530 return true;
9531 if (!*SimplifiedLHS)
9532 return false;
9533 LHS = *SimplifiedLHS;
9534
9535 const auto &SimplifiedRHS = A.getAssumedSimplified(
9536 IRPosition::value(*RHS, getCallBaseContext()), *this,
9537 UsedAssumedInformation, AA::Interprocedural);
9538 if (!SimplifiedRHS.has_value())
9539 return true;
9540 if (!*SimplifiedRHS)
9541 return false;
9542 RHS = *SimplifiedRHS;
9543
9544 // TODO: Allow non integers as well.
9545 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9546 return false;
9547
9548 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9549 *this, IRPosition::value(*LHS, getCallBaseContext()),
9550 DepClassTy::REQUIRED);
9551 if (!LHSAA)
9552 return false;
9553 QuerriedAAs.push_back(LHSAA);
9554 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9555 *this, IRPosition::value(*RHS, getCallBaseContext()),
9556 DepClassTy::REQUIRED);
9557 if (!RHSAA)
9558 return false;
9559 QuerriedAAs.push_back(RHSAA);
9560 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9561 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9562
9563 // If one of them is empty set, we can't decide.
9564 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9565 return true;
9566
9567 bool MustTrue = false, MustFalse = false;
9568
9569 auto AllowedRegion =
9571
9572 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9573 MustFalse = true;
9574
9575 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9576 MustTrue = true;
9577
9578 assert((!MustTrue || !MustFalse) &&
9579 "Either MustTrue or MustFalse should be false!");
9580
9581 if (MustTrue)
9582 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9583 else if (MustFalse)
9584 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9585 else
9586 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9587
9588 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9589 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9590 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9591 << *RHSAA);
9592
9593 // TODO: Track a known state too.
9594 return T.isValidState();
9595 }
9596
9597 /// See AbstractAttribute::updateImpl(...).
9598 ChangeStatus updateImpl(Attributor &A) override {
9599
9600 IntegerRangeState T(getBitWidth());
9601 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9603 if (!I || isa<CallBase>(I)) {
9604
9605 // Simplify the operand first.
9606 bool UsedAssumedInformation = false;
9607 const auto &SimplifiedOpV = A.getAssumedSimplified(
9608 IRPosition::value(V, getCallBaseContext()), *this,
9609 UsedAssumedInformation, AA::Interprocedural);
9610 if (!SimplifiedOpV.has_value())
9611 return true;
9612 if (!*SimplifiedOpV)
9613 return false;
9614 Value *VPtr = *SimplifiedOpV;
9615
9616 // If the value is not instruction, we query AA to Attributor.
9617 const auto *AA = A.getAAFor<AAValueConstantRange>(
9618 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9619 DepClassTy::REQUIRED);
9620
9621 // Clamp operator is not used to utilize a program point CtxI.
9622 if (AA)
9623 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9624 else
9625 return false;
9626
9627 return T.isValidState();
9628 }
9629
9631 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9632 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9633 return false;
9634 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9635 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9636 return false;
9637 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9638 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9639 return false;
9640 } else {
9641 // Give up with other instructions.
9642 // TODO: Add other instructions
9643
9644 T.indicatePessimisticFixpoint();
9645 return false;
9646 }
9647
9648 // Catch circular reasoning in a pessimistic way for now.
9649 // TODO: Check how the range evolves and if we stripped anything, see also
9650 // AADereferenceable or AAAlign for similar situations.
9651 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9652 if (QueriedAA != this)
9653 continue;
9654 // If we are in a stady state we do not need to worry.
9655 if (T.getAssumed() == getState().getAssumed())
9656 continue;
9657 T.indicatePessimisticFixpoint();
9658 }
9659
9660 return T.isValidState();
9661 };
9662
9663 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9664 return indicatePessimisticFixpoint();
9665
9666 // Ensure that long def-use chains can't cause circular reasoning either by
9667 // introducing a cutoff below.
9668 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9669 return ChangeStatus::UNCHANGED;
9670 if (++NumChanges > MaxNumChanges) {
9671 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9672 << " but only " << MaxNumChanges
9673 << " are allowed to avoid cyclic reasoning.");
9674 return indicatePessimisticFixpoint();
9675 }
9676 return ChangeStatus::CHANGED;
9677 }
9678
9679 /// See AbstractAttribute::trackStatistics()
9680 void trackStatistics() const override {
9682 }
9683
9684 /// Tracker to bail after too many widening steps of the constant range.
9685 int NumChanges = 0;
9686
9687 /// Upper bound for the number of allowed changes (=widening steps) for the
9688 /// constant range before we give up.
9689 static constexpr int MaxNumChanges = 5;
9690};
9691
9692struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9693 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9694 : AAValueConstantRangeImpl(IRP, A) {}
9695
9696 /// See AbstractAttribute::initialize(...).
9697 ChangeStatus updateImpl(Attributor &A) override {
9698 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9699 "not be called");
9700 }
9701
9702 /// See AbstractAttribute::trackStatistics()
9703 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9704};
9705
9706struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9707 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9708 : AAValueConstantRangeFunction(IRP, A) {}
9709
9710 /// See AbstractAttribute::trackStatistics()
9711 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9712};
9713
9714struct AAValueConstantRangeCallSiteReturned
9715 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9716 AAValueConstantRangeImpl::StateType,
9717 /* IntroduceCallBaseContext */ true> {
9718 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9719 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9720 AAValueConstantRangeImpl::StateType,
9721 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9722
9723 /// See AbstractAttribute::initialize(...).
9724 void initialize(Attributor &A) override {
9725 // If it is a call instruction with range attribute, use the range.
9726 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9727 if (std::optional<ConstantRange> Range = CI->getRange())
9728 intersectKnown(*Range);
9729 }
9730
9731 AAValueConstantRangeImpl::initialize(A);
9732 }
9733
9734 /// See AbstractAttribute::trackStatistics()
9735 void trackStatistics() const override {
9736 STATS_DECLTRACK_CSRET_ATTR(value_range)
9737 }
9738};
9739struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9740 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9741 : AAValueConstantRangeFloating(IRP, A) {}
9742
9743 /// See AbstractAttribute::manifest()
9744 ChangeStatus manifest(Attributor &A) override {
9745 return ChangeStatus::UNCHANGED;
9746 }
9747
9748 /// See AbstractAttribute::trackStatistics()
9749 void trackStatistics() const override {
9750 STATS_DECLTRACK_CSARG_ATTR(value_range)
9751 }
9752};
9753} // namespace
9754
9755/// ------------------ Potential Values Attribute -------------------------
9756
9757namespace {
9758struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9759 using StateType = PotentialConstantIntValuesState;
9760
9761 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9762 : AAPotentialConstantValues(IRP, A) {}
9763
9764 /// See AbstractAttribute::initialize(..).
9765 void initialize(Attributor &A) override {
9766 if (A.hasSimplificationCallback(getIRPosition()))
9767 indicatePessimisticFixpoint();
9768 else
9769 AAPotentialConstantValues::initialize(A);
9770 }
9771
9772 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9773 bool &ContainsUndef, bool ForSelf) {
9775 bool UsedAssumedInformation = false;
9776 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9777 UsedAssumedInformation)) {
9778 // Avoid recursion when the caller is computing constant values for this
9779 // IRP itself.
9780 if (ForSelf)
9781 return false;
9782 if (!IRP.getAssociatedType()->isIntegerTy())
9783 return false;
9784 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9785 *this, IRP, DepClassTy::REQUIRED);
9786 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9787 return false;
9788 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9789 S = PotentialValuesAA->getState().getAssumedSet();
9790 return true;
9791 }
9792
9793 // Copy all the constant values, except UndefValue. ContainsUndef is true
9794 // iff Values contains only UndefValue instances. If there are other known
9795 // constants, then UndefValue is dropped.
9796 ContainsUndef = false;
9797 for (auto &It : Values) {
9798 if (isa<UndefValue>(It.getValue())) {
9799 ContainsUndef = true;
9800 continue;
9801 }
9802 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9803 if (!CI)
9804 return false;
9805 S.insert(CI->getValue());
9806 }
9807 ContainsUndef &= S.empty();
9808
9809 return true;
9810 }
9811
9812 /// See AbstractAttribute::getAsStr().
9813 const std::string getAsStr(Attributor *A) const override {
9814 std::string Str;
9815 llvm::raw_string_ostream OS(Str);
9816 OS << getState();
9817 return Str;
9818 }
9819
9820 /// See AbstractAttribute::updateImpl(...).
9821 ChangeStatus updateImpl(Attributor &A) override {
9822 return indicatePessimisticFixpoint();
9823 }
9824};
9825
9826struct AAPotentialConstantValuesArgument final
9827 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9828 AAPotentialConstantValuesImpl,
9829 PotentialConstantIntValuesState> {
9830 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9831 AAPotentialConstantValuesImpl,
9833 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9834 : Base(IRP, A) {}
9835
9836 /// See AbstractAttribute::trackStatistics()
9837 void trackStatistics() const override {
9838 STATS_DECLTRACK_ARG_ATTR(potential_values)
9839 }
9840};
9841
9842struct AAPotentialConstantValuesReturned
9843 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9844 AAPotentialConstantValuesImpl> {
9845 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9846 AAPotentialConstantValuesImpl>;
9847 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9848 : Base(IRP, A) {}
9849
9850 void initialize(Attributor &A) override {
9851 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9852 indicatePessimisticFixpoint();
9853 Base::initialize(A);
9854 }
9855
9856 /// See AbstractAttribute::trackStatistics()
9857 void trackStatistics() const override {
9858 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9859 }
9860};
9861
9862struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9863 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9864 : AAPotentialConstantValuesImpl(IRP, A) {}
9865
9866 /// See AbstractAttribute::initialize(..).
9867 void initialize(Attributor &A) override {
9868 AAPotentialConstantValuesImpl::initialize(A);
9869 if (isAtFixpoint())
9870 return;
9871
9872 Value &V = getAssociatedValue();
9873
9874 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9875 unionAssumed(C->getValue());
9876 indicateOptimisticFixpoint();
9877 return;
9878 }
9879
9880 if (isa<UndefValue>(&V)) {
9881 unionAssumedWithUndef();
9882 indicateOptimisticFixpoint();
9883 return;
9884 }
9885
9886 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9887 return;
9888
9889 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9890 return;
9891
9892 indicatePessimisticFixpoint();
9893
9894 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9895 << getAssociatedValue() << "\n");
9896 }
9897
9898 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9899 const APInt &RHS) {
9900 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9901 }
9902
9903 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9904 uint32_t ResultBitWidth) {
9905 Instruction::CastOps CastOp = CI->getOpcode();
9906 switch (CastOp) {
9907 default:
9908 llvm_unreachable("unsupported or not integer cast");
9909 case Instruction::Trunc:
9910 return Src.trunc(ResultBitWidth);
9911 case Instruction::SExt:
9912 return Src.sext(ResultBitWidth);
9913 case Instruction::ZExt:
9914 return Src.zext(ResultBitWidth);
9915 case Instruction::BitCast:
9916 return Src;
9917 }
9918 }
9919
9920 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9921 const APInt &LHS, const APInt &RHS,
9922 bool &SkipOperation, bool &Unsupported) {
9923 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9924 // Unsupported is set to true when the binary operator is not supported.
9925 // SkipOperation is set to true when UB occur with the given operand pair
9926 // (LHS, RHS).
9927 // TODO: we should look at nsw and nuw keywords to handle operations
9928 // that create poison or undef value.
9929 switch (BinOpcode) {
9930 default:
9931 Unsupported = true;
9932 return LHS;
9933 case Instruction::Add:
9934 return LHS + RHS;
9935 case Instruction::Sub:
9936 return LHS - RHS;
9937 case Instruction::Mul:
9938 return LHS * RHS;
9939 case Instruction::UDiv:
9940 if (RHS.isZero()) {
9941 SkipOperation = true;
9942 return LHS;
9943 }
9944 return LHS.udiv(RHS);
9945 case Instruction::SDiv:
9946 if (RHS.isZero()) {
9947 SkipOperation = true;
9948 return LHS;
9949 }
9950 return LHS.sdiv(RHS);
9951 case Instruction::URem:
9952 if (RHS.isZero()) {
9953 SkipOperation = true;
9954 return LHS;
9955 }
9956 return LHS.urem(RHS);
9957 case Instruction::SRem:
9958 if (RHS.isZero()) {
9959 SkipOperation = true;
9960 return LHS;
9961 }
9962 return LHS.srem(RHS);
9963 case Instruction::Shl:
9964 return LHS.shl(RHS);
9965 case Instruction::LShr:
9966 return LHS.lshr(RHS);
9967 case Instruction::AShr:
9968 return LHS.ashr(RHS);
9969 case Instruction::And:
9970 return LHS & RHS;
9971 case Instruction::Or:
9972 return LHS | RHS;
9973 case Instruction::Xor:
9974 return LHS ^ RHS;
9975 }
9976 }
9977
9978 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9979 const APInt &LHS, const APInt &RHS) {
9980 bool SkipOperation = false;
9981 bool Unsupported = false;
9982 APInt Result =
9983 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9984 if (Unsupported)
9985 return false;
9986 // If SkipOperation is true, we can ignore this operand pair (L, R).
9987 if (!SkipOperation)
9988 unionAssumed(Result);
9989 return isValidState();
9990 }
9991
9992 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9993 auto AssumedBefore = getAssumed();
9994 Value *LHS = ICI->getOperand(0);
9995 Value *RHS = ICI->getOperand(1);
9996
9997 bool LHSContainsUndef = false, RHSContainsUndef = false;
9998 SetTy LHSAAPVS, RHSAAPVS;
9999 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10000 LHSContainsUndef, /* ForSelf */ false) ||
10001 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10002 RHSContainsUndef, /* ForSelf */ false))
10003 return indicatePessimisticFixpoint();
10004
10005 // TODO: make use of undef flag to limit potential values aggressively.
10006 bool MaybeTrue = false, MaybeFalse = false;
10007 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10008 if (LHSContainsUndef && RHSContainsUndef) {
10009 // The result of any comparison between undefs can be soundly replaced
10010 // with undef.
10011 unionAssumedWithUndef();
10012 } else if (LHSContainsUndef) {
10013 for (const APInt &R : RHSAAPVS) {
10014 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10015 MaybeTrue |= CmpResult;
10016 MaybeFalse |= !CmpResult;
10017 if (MaybeTrue & MaybeFalse)
10018 return indicatePessimisticFixpoint();
10019 }
10020 } else if (RHSContainsUndef) {
10021 for (const APInt &L : LHSAAPVS) {
10022 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10023 MaybeTrue |= CmpResult;
10024 MaybeFalse |= !CmpResult;
10025 if (MaybeTrue & MaybeFalse)
10026 return indicatePessimisticFixpoint();
10027 }
10028 } else {
10029 for (const APInt &L : LHSAAPVS) {
10030 for (const APInt &R : RHSAAPVS) {
10031 bool CmpResult = calculateICmpInst(ICI, L, R);
10032 MaybeTrue |= CmpResult;
10033 MaybeFalse |= !CmpResult;
10034 if (MaybeTrue & MaybeFalse)
10035 return indicatePessimisticFixpoint();
10036 }
10037 }
10038 }
10039 if (MaybeTrue)
10040 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10041 if (MaybeFalse)
10042 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10043 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10044 : ChangeStatus::CHANGED;
10045 }
10046
10047 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10048 auto AssumedBefore = getAssumed();
10049 Value *LHS = SI->getTrueValue();
10050 Value *RHS = SI->getFalseValue();
10051
10052 bool UsedAssumedInformation = false;
10053 std::optional<Constant *> C = A.getAssumedConstant(
10054 *SI->getCondition(), *this, UsedAssumedInformation);
10055
10056 // Check if we only need one operand.
10057 bool OnlyLeft = false, OnlyRight = false;
10058 if (C && *C && (*C)->isOneValue())
10059 OnlyLeft = true;
10060 else if (C && *C && (*C)->isNullValue())
10061 OnlyRight = true;
10062
10063 bool LHSContainsUndef = false, RHSContainsUndef = false;
10064 SetTy LHSAAPVS, RHSAAPVS;
10065 if (!OnlyRight &&
10066 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10067 LHSContainsUndef, /* ForSelf */ false))
10068 return indicatePessimisticFixpoint();
10069
10070 if (!OnlyLeft &&
10071 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10072 RHSContainsUndef, /* ForSelf */ false))
10073 return indicatePessimisticFixpoint();
10074
10075 if (OnlyLeft || OnlyRight) {
10076 // select (true/false), lhs, rhs
10077 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10078 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10079
10080 if (Undef)
10081 unionAssumedWithUndef();
10082 else {
10083 for (const auto &It : *OpAA)
10084 unionAssumed(It);
10085 }
10086
10087 } else if (LHSContainsUndef && RHSContainsUndef) {
10088 // select i1 *, undef , undef => undef
10089 unionAssumedWithUndef();
10090 } else {
10091 for (const auto &It : LHSAAPVS)
10092 unionAssumed(It);
10093 for (const auto &It : RHSAAPVS)
10094 unionAssumed(It);
10095 }
10096 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10097 : ChangeStatus::CHANGED;
10098 }
10099
10100 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10101 auto AssumedBefore = getAssumed();
10102 if (!CI->isIntegerCast())
10103 return indicatePessimisticFixpoint();
10104 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10105 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10106 Value *Src = CI->getOperand(0);
10107
10108 bool SrcContainsUndef = false;
10109 SetTy SrcPVS;
10110 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10111 SrcContainsUndef, /* ForSelf */ false))
10112 return indicatePessimisticFixpoint();
10113
10114 if (SrcContainsUndef)
10115 unionAssumedWithUndef();
10116 else {
10117 for (const APInt &S : SrcPVS) {
10118 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10119 unionAssumed(T);
10120 }
10121 }
10122 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10123 : ChangeStatus::CHANGED;
10124 }
10125
10126 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10127 auto AssumedBefore = getAssumed();
10128 Value *LHS = BinOp->getOperand(0);
10129 Value *RHS = BinOp->getOperand(1);
10130
10131 bool LHSContainsUndef = false, RHSContainsUndef = false;
10132 SetTy LHSAAPVS, RHSAAPVS;
10133 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10134 LHSContainsUndef, /* ForSelf */ false) ||
10135 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10136 RHSContainsUndef, /* ForSelf */ false))
10137 return indicatePessimisticFixpoint();
10138
10139 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10140
10141 // TODO: make use of undef flag to limit potential values aggressively.
10142 if (LHSContainsUndef && RHSContainsUndef) {
10143 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10144 return indicatePessimisticFixpoint();
10145 } else if (LHSContainsUndef) {
10146 for (const APInt &R : RHSAAPVS) {
10147 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10148 return indicatePessimisticFixpoint();
10149 }
10150 } else if (RHSContainsUndef) {
10151 for (const APInt &L : LHSAAPVS) {
10152 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10153 return indicatePessimisticFixpoint();
10154 }
10155 } else {
10156 for (const APInt &L : LHSAAPVS) {
10157 for (const APInt &R : RHSAAPVS) {
10158 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10159 return indicatePessimisticFixpoint();
10160 }
10161 }
10162 }
10163 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10164 : ChangeStatus::CHANGED;
10165 }
10166
10167 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10168 auto AssumedBefore = getAssumed();
10169 SetTy Incoming;
10170 bool ContainsUndef;
10171 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10172 ContainsUndef, /* ForSelf */ true))
10173 return indicatePessimisticFixpoint();
10174 if (ContainsUndef) {
10175 unionAssumedWithUndef();
10176 } else {
10177 for (const auto &It : Incoming)
10178 unionAssumed(It);
10179 }
10180 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10181 : ChangeStatus::CHANGED;
10182 }
10183
10184 /// See AbstractAttribute::updateImpl(...).
10185 ChangeStatus updateImpl(Attributor &A) override {
10186 Value &V = getAssociatedValue();
10188
10189 if (auto *ICI = dyn_cast<ICmpInst>(I))
10190 return updateWithICmpInst(A, ICI);
10191
10192 if (auto *SI = dyn_cast<SelectInst>(I))
10193 return updateWithSelectInst(A, SI);
10194
10195 if (auto *CI = dyn_cast<CastInst>(I))
10196 return updateWithCastInst(A, CI);
10197
10198 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10199 return updateWithBinaryOperator(A, BinOp);
10200
10201 if (isa<PHINode>(I) || isa<LoadInst>(I))
10202 return updateWithInstruction(A, I);
10203
10204 return indicatePessimisticFixpoint();
10205 }
10206
10207 /// See AbstractAttribute::trackStatistics()
10208 void trackStatistics() const override {
10209 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10210 }
10211};
10212
10213struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10214 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10215 : AAPotentialConstantValuesImpl(IRP, A) {}
10216
10217 /// See AbstractAttribute::initialize(...).
10218 ChangeStatus updateImpl(Attributor &A) override {
10220 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10221 "not be called");
10222 }
10223
10224 /// See AbstractAttribute::trackStatistics()
10225 void trackStatistics() const override {
10226 STATS_DECLTRACK_FN_ATTR(potential_values)
10227 }
10228};
10229
10230struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10231 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10232 : AAPotentialConstantValuesFunction(IRP, A) {}
10233
10234 /// See AbstractAttribute::trackStatistics()
10235 void trackStatistics() const override {
10236 STATS_DECLTRACK_CS_ATTR(potential_values)
10237 }
10238};
10239
10240struct AAPotentialConstantValuesCallSiteReturned
10241 : AACalleeToCallSite<AAPotentialConstantValues,
10242 AAPotentialConstantValuesImpl> {
10243 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10244 Attributor &A)
10245 : AACalleeToCallSite<AAPotentialConstantValues,
10246 AAPotentialConstantValuesImpl>(IRP, A) {}
10247
10248 /// See AbstractAttribute::trackStatistics()
10249 void trackStatistics() const override {
10250 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10251 }
10252};
10253
10254struct AAPotentialConstantValuesCallSiteArgument
10255 : AAPotentialConstantValuesFloating {
10256 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10257 Attributor &A)
10258 : AAPotentialConstantValuesFloating(IRP, A) {}
10259
10260 /// See AbstractAttribute::initialize(..).
10261 void initialize(Attributor &A) override {
10262 AAPotentialConstantValuesImpl::initialize(A);
10263 if (isAtFixpoint())
10264 return;
10265
10266 Value &V = getAssociatedValue();
10267
10268 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10269 unionAssumed(C->getValue());
10270 indicateOptimisticFixpoint();
10271 return;
10272 }
10273
10274 if (isa<UndefValue>(&V)) {
10275 unionAssumedWithUndef();
10276 indicateOptimisticFixpoint();
10277 return;
10278 }
10279 }
10280
10281 /// See AbstractAttribute::updateImpl(...).
10282 ChangeStatus updateImpl(Attributor &A) override {
10283 Value &V = getAssociatedValue();
10284 auto AssumedBefore = getAssumed();
10285 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10286 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10287 if (!AA)
10288 return indicatePessimisticFixpoint();
10289 const auto &S = AA->getAssumed();
10290 unionAssumed(S);
10291 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10292 : ChangeStatus::CHANGED;
10293 }
10294
10295 /// See AbstractAttribute::trackStatistics()
10296 void trackStatistics() const override {
10297 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10298 }
10299};
10300} // namespace
10301
10302/// ------------------------ NoUndef Attribute ---------------------------------
10304 Attribute::AttrKind ImpliedAttributeKind,
10305 bool IgnoreSubsumingPositions) {
10306 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10307 "Unexpected attribute kind");
10308 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10309 Attribute::NoUndef))
10310 return true;
10311
10312 Value &Val = IRP.getAssociatedValue();
10315 LLVMContext &Ctx = Val.getContext();
10316 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10317 return true;
10318 }
10319
10320 return false;
10321}
10322
10323namespace {
10324struct AANoUndefImpl : AANoUndef {
10325 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10326
10327 /// See AbstractAttribute::initialize(...).
10328 void initialize(Attributor &A) override {
10329 Value &V = getAssociatedValue();
10330 if (isa<UndefValue>(V))
10331 indicatePessimisticFixpoint();
10332 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10333 }
10334
10335 /// See followUsesInMBEC
10336 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10337 AANoUndef::StateType &State) {
10338 const Value *UseV = U->get();
10339 const DominatorTree *DT = nullptr;
10340 AssumptionCache *AC = nullptr;
10341 InformationCache &InfoCache = A.getInfoCache();
10342 if (Function *F = getAnchorScope()) {
10343 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10344 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10345 }
10346 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10347 bool TrackUse = false;
10348 // Track use for instructions which must produce undef or poison bits when
10349 // at least one operand contains such bits.
10351 TrackUse = true;
10352 return TrackUse;
10353 }
10354
10355 /// See AbstractAttribute::getAsStr().
10356 const std::string getAsStr(Attributor *A) const override {
10357 return getAssumed() ? "noundef" : "may-undef-or-poison";
10358 }
10359
10360 ChangeStatus manifest(Attributor &A) override {
10361 // We don't manifest noundef attribute for dead positions because the
10362 // associated values with dead positions would be replaced with undef
10363 // values.
10364 bool UsedAssumedInformation = false;
10365 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10366 UsedAssumedInformation))
10367 return ChangeStatus::UNCHANGED;
10368 // A position whose simplified value does not have any value is
10369 // considered to be dead. We don't manifest noundef in such positions for
10370 // the same reason above.
10371 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10373 .has_value())
10374 return ChangeStatus::UNCHANGED;
10375 return AANoUndef::manifest(A);
10376 }
10377};
10378
10379struct AANoUndefFloating : public AANoUndefImpl {
10380 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10381 : AANoUndefImpl(IRP, A) {}
10382
10383 /// See AbstractAttribute::initialize(...).
10384 void initialize(Attributor &A) override {
10385 AANoUndefImpl::initialize(A);
10386 if (!getState().isAtFixpoint() && getAnchorScope() &&
10387 !getAnchorScope()->isDeclaration())
10388 if (Instruction *CtxI = getCtxI())
10389 followUsesInMBEC(*this, A, getState(), *CtxI);
10390 }
10391
10392 /// See AbstractAttribute::updateImpl(...).
10393 ChangeStatus updateImpl(Attributor &A) override {
10394 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10395 bool IsKnownNoUndef;
10397 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10398 };
10399
10400 bool Stripped;
10401 bool UsedAssumedInformation = false;
10402 Value *AssociatedValue = &getAssociatedValue();
10404 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10405 AA::AnyScope, UsedAssumedInformation))
10406 Stripped = false;
10407 else
10408 Stripped =
10409 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10410
10411 if (!Stripped) {
10412 // If we haven't stripped anything we might still be able to use a
10413 // different AA, but only if the IRP changes. Effectively when we
10414 // interpret this not as a call site value but as a floating/argument
10415 // value.
10416 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10417 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10418 return indicatePessimisticFixpoint();
10419 return ChangeStatus::UNCHANGED;
10420 }
10421
10422 for (const auto &VAC : Values)
10423 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10424 return indicatePessimisticFixpoint();
10425
10426 return ChangeStatus::UNCHANGED;
10427 }
10428
10429 /// See AbstractAttribute::trackStatistics()
10430 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10431};
10432
10433struct AANoUndefReturned final
10434 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10435 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10436 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10437
10438 /// See AbstractAttribute::trackStatistics()
10439 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10440};
10441
10442struct AANoUndefArgument final
10443 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10444 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10445 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10446
10447 /// See AbstractAttribute::trackStatistics()
10448 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10449};
10450
10451struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10452 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10453 : AANoUndefFloating(IRP, A) {}
10454
10455 /// See AbstractAttribute::trackStatistics()
10456 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10457};
10458
10459struct AANoUndefCallSiteReturned final
10460 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10461 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10462 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10463
10464 /// See AbstractAttribute::trackStatistics()
10465 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10466};
10467
10468/// ------------------------ NoFPClass Attribute -------------------------------
10469
10470struct AANoFPClassImpl : AANoFPClass {
10471 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10472
10473 void initialize(Attributor &A) override {
10474 const IRPosition &IRP = getIRPosition();
10475
10476 Value &V = IRP.getAssociatedValue();
10477 if (isa<UndefValue>(V)) {
10478 indicateOptimisticFixpoint();
10479 return;
10480 }
10481
10483 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10484 for (const auto &Attr : Attrs) {
10485 addKnownBits(Attr.getNoFPClass());
10486 }
10487
10488 Instruction *CtxI = getCtxI();
10489
10490 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10491 const DataLayout &DL = A.getDataLayout();
10492 InformationCache &InfoCache = A.getInfoCache();
10493
10494 const DominatorTree *DT = nullptr;
10495 AssumptionCache *AC = nullptr;
10496 const TargetLibraryInfo *TLI = nullptr;
10497 Function *F = getAnchorScope();
10498 if (F) {
10499 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10500 if (!F->isDeclaration()) {
10501 DT =
10502 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10503 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10504 }
10505 }
10506
10507 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10508
10509 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10510 addKnownBits(~KnownFPClass.KnownFPClasses);
10511 }
10512
10513 if (CtxI)
10514 followUsesInMBEC(*this, A, getState(), *CtxI);
10515 }
10516
10517 /// See followUsesInMBEC
10518 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10519 AANoFPClass::StateType &State) {
10520 // TODO: Determine what instructions can be looked through.
10521 auto *CB = dyn_cast<CallBase>(I);
10522 if (!CB)
10523 return false;
10524
10525 if (!CB->isArgOperand(U))
10526 return false;
10527
10528 unsigned ArgNo = CB->getArgOperandNo(U);
10529 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10530 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10531 State.addKnownBits(NoFPAA->getState().getKnown());
10532 return false;
10533 }
10534
10535 const std::string getAsStr(Attributor *A) const override {
10536 std::string Result = "nofpclass";
10537 raw_string_ostream OS(Result);
10538 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10539 return Result;
10540 }
10541
10542 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10543 SmallVectorImpl<Attribute> &Attrs) const override {
10544 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10545 }
10546};
10547
10548struct AANoFPClassFloating : public AANoFPClassImpl {
10549 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10550 : AANoFPClassImpl(IRP, A) {}
10551
10552 /// See AbstractAttribute::updateImpl(...).
10553 ChangeStatus updateImpl(Attributor &A) override {
10555 bool UsedAssumedInformation = false;
10556 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10557 AA::AnyScope, UsedAssumedInformation)) {
10558 Values.push_back({getAssociatedValue(), getCtxI()});
10559 }
10560
10561 StateType T;
10562 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10563 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10564 DepClassTy::REQUIRED);
10565 if (!AA || this == AA) {
10566 T.indicatePessimisticFixpoint();
10567 } else {
10568 const AANoFPClass::StateType &S =
10569 static_cast<const AANoFPClass::StateType &>(AA->getState());
10570 T ^= S;
10571 }
10572 return T.isValidState();
10573 };
10574
10575 for (const auto &VAC : Values)
10576 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10577 return indicatePessimisticFixpoint();
10578
10579 return clampStateAndIndicateChange(getState(), T);
10580 }
10581
10582 /// See AbstractAttribute::trackStatistics()
10583 void trackStatistics() const override {
10585 }
10586};
10587
10588struct AANoFPClassReturned final
10589 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10590 AANoFPClassImpl::StateType, false,
10591 Attribute::None, false> {
10592 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10593 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10594 AANoFPClassImpl::StateType, false,
10595 Attribute::None, false>(IRP, A) {}
10596
10597 /// See AbstractAttribute::trackStatistics()
10598 void trackStatistics() const override {
10600 }
10601};
10602
10603struct AANoFPClassArgument final
10604 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10605 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10606 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10607
10608 /// See AbstractAttribute::trackStatistics()
10609 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10610};
10611
10612struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10613 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10614 : AANoFPClassFloating(IRP, A) {}
10615
10616 /// See AbstractAttribute::trackStatistics()
10617 void trackStatistics() const override {
10619 }
10620};
10621
10622struct AANoFPClassCallSiteReturned final
10623 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10624 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10625 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10626
10627 /// See AbstractAttribute::trackStatistics()
10628 void trackStatistics() const override {
10630 }
10631};
10632
10633struct AACallEdgesImpl : public AACallEdges {
10634 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10635
10636 const SetVector<Function *> &getOptimisticEdges() const override {
10637 return CalledFunctions;
10638 }
10639
10640 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10641
10642 bool hasNonAsmUnknownCallee() const override {
10643 return HasUnknownCalleeNonAsm;
10644 }
10645
10646 const std::string getAsStr(Attributor *A) const override {
10647 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10648 std::to_string(CalledFunctions.size()) + "]";
10649 }
10650
10651 void trackStatistics() const override {}
10652
10653protected:
10654 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10655 if (CalledFunctions.insert(Fn)) {
10656 Change = ChangeStatus::CHANGED;
10657 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10658 << "\n");
10659 }
10660 }
10661
10662 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10663 if (!HasUnknownCallee)
10664 Change = ChangeStatus::CHANGED;
10665 if (NonAsm && !HasUnknownCalleeNonAsm)
10666 Change = ChangeStatus::CHANGED;
10667 HasUnknownCalleeNonAsm |= NonAsm;
10668 HasUnknownCallee = true;
10669 }
10670
10671private:
10672 /// Optimistic set of functions that might be called by this position.
10673 SetVector<Function *> CalledFunctions;
10674
10675 /// Is there any call with a unknown callee.
10676 bool HasUnknownCallee = false;
10677
10678 /// Is there any call with a unknown callee, excluding any inline asm.
10679 bool HasUnknownCalleeNonAsm = false;
10680};
10681
10682struct AACallEdgesCallSite : public AACallEdgesImpl {
10683 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10684 : AACallEdgesImpl(IRP, A) {}
10685 /// See AbstractAttribute::updateImpl(...).
10686 ChangeStatus updateImpl(Attributor &A) override {
10687 ChangeStatus Change = ChangeStatus::UNCHANGED;
10688
10689 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10690 if (Function *Fn = dyn_cast<Function>(&V)) {
10691 addCalledFunction(Fn, Change);
10692 } else {
10693 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10694 setHasUnknownCallee(true, Change);
10695 }
10696
10697 // Explore all values.
10698 return true;
10699 };
10700
10702 // Process any value that we might call.
10703 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10704 if (isa<Constant>(V)) {
10705 VisitValue(*V, CtxI);
10706 return;
10707 }
10708
10709 bool UsedAssumedInformation = false;
10710 Values.clear();
10711 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10712 AA::AnyScope, UsedAssumedInformation)) {
10713 Values.push_back({*V, CtxI});
10714 }
10715 for (auto &VAC : Values)
10716 VisitValue(*VAC.getValue(), VAC.getCtxI());
10717 };
10718
10719 CallBase *CB = cast<CallBase>(getCtxI());
10720
10721 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10722 if (IA->hasSideEffects() &&
10723 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10724 !hasAssumption(*CB, "ompx_no_call_asm")) {
10725 setHasUnknownCallee(false, Change);
10726 }
10727 return Change;
10728 }
10729
10730 if (CB->isIndirectCall())
10731 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10732 *this, getIRPosition(), DepClassTy::OPTIONAL))
10733 if (IndirectCallAA->foreachCallee(
10734 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10735 return Change;
10736
10737 // The most simple case.
10738 ProcessCalledOperand(CB->getCalledOperand(), CB);
10739
10740 // Process callback functions.
10741 SmallVector<const Use *, 4u> CallbackUses;
10742 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10743 for (const Use *U : CallbackUses)
10744 ProcessCalledOperand(U->get(), CB);
10745
10746 return Change;
10747 }
10748};
10749
10750struct AACallEdgesFunction : public AACallEdgesImpl {
10751 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10752 : AACallEdgesImpl(IRP, A) {}
10753
10754 /// See AbstractAttribute::updateImpl(...).
10755 ChangeStatus updateImpl(Attributor &A) override {
10756 ChangeStatus Change = ChangeStatus::UNCHANGED;
10757
10758 auto ProcessCallInst = [&](Instruction &Inst) {
10759 CallBase &CB = cast<CallBase>(Inst);
10760
10761 auto *CBEdges = A.getAAFor<AACallEdges>(
10762 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10763 if (!CBEdges)
10764 return false;
10765 if (CBEdges->hasNonAsmUnknownCallee())
10766 setHasUnknownCallee(true, Change);
10767 if (CBEdges->hasUnknownCallee())
10768 setHasUnknownCallee(false, Change);
10769
10770 for (Function *F : CBEdges->getOptimisticEdges())
10771 addCalledFunction(F, Change);
10772
10773 return true;
10774 };
10775
10776 // Visit all callable instructions.
10777 bool UsedAssumedInformation = false;
10778 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10779 UsedAssumedInformation,
10780 /* CheckBBLivenessOnly */ true)) {
10781 // If we haven't looked at all call like instructions, assume that there
10782 // are unknown callees.
10783 setHasUnknownCallee(true, Change);
10784 }
10785
10786 return Change;
10787 }
10788};
10789
10790/// -------------------AAInterFnReachability Attribute--------------------------
10791
10792struct AAInterFnReachabilityFunction
10793 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10794 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10795 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10796 : Base(IRP, A) {}
10797
10798 bool instructionCanReach(
10799 Attributor &A, const Instruction &From, const Function &To,
10800 const AA::InstExclusionSetTy *ExclusionSet) const override {
10801 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10802 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10803
10804 RQITy StackRQI(A, From, To, ExclusionSet, false);
10805 RQITy::Reachable Result;
10806 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10807 return NonConstThis->isReachableImpl(A, StackRQI,
10808 /*IsTemporaryRQI=*/true);
10809 return Result == RQITy::Reachable::Yes;
10810 }
10811
10812 bool isReachableImpl(Attributor &A, RQITy &RQI,
10813 bool IsTemporaryRQI) override {
10814 const Instruction *EntryI =
10815 &RQI.From->getFunction()->getEntryBlock().front();
10816 if (EntryI != RQI.From &&
10817 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10818 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10819 IsTemporaryRQI);
10820
10821 auto CheckReachableCallBase = [&](CallBase *CB) {
10822 auto *CBEdges = A.getAAFor<AACallEdges>(
10823 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10824 if (!CBEdges || !CBEdges->getState().isValidState())
10825 return false;
10826 // TODO Check To backwards in this case.
10827 if (CBEdges->hasUnknownCallee())
10828 return false;
10829
10830 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10831 if (Fn == RQI.To)
10832 return false;
10833
10834 if (Fn->isDeclaration()) {
10835 if (Fn->hasFnAttribute(Attribute::NoCallback))
10836 continue;
10837 // TODO Check To backwards in this case.
10838 return false;
10839 }
10840
10841 if (Fn == getAnchorScope()) {
10842 if (EntryI == RQI.From)
10843 continue;
10844 return false;
10845 }
10846
10847 const AAInterFnReachability *InterFnReachability =
10848 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10849 DepClassTy::OPTIONAL);
10850
10851 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10852 if (!InterFnReachability ||
10853 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10854 RQI.ExclusionSet))
10855 return false;
10856 }
10857 return true;
10858 };
10859
10860 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10861 *this, IRPosition::function(*RQI.From->getFunction()),
10862 DepClassTy::OPTIONAL);
10863
10864 // Determine call like instructions that we can reach from the inst.
10865 auto CheckCallBase = [&](Instruction &CBInst) {
10866 // There are usually less nodes in the call graph, check inter function
10867 // reachability first.
10868 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10869 return true;
10870 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10871 A, *RQI.From, CBInst, RQI.ExclusionSet);
10872 };
10873
10874 bool UsedExclusionSet = /* conservative */ true;
10875 bool UsedAssumedInformation = false;
10876 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10877 UsedAssumedInformation,
10878 /* CheckBBLivenessOnly */ true))
10879 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10880 IsTemporaryRQI);
10881
10882 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10883 IsTemporaryRQI);
10884 }
10885
10886 void trackStatistics() const override {}
10887};
10888} // namespace
10889
10890template <typename AAType>
10891static std::optional<Constant *>
10893 const IRPosition &IRP, Type &Ty) {
10894 if (!Ty.isIntegerTy())
10895 return nullptr;
10896
10897 // This will also pass the call base context.
10898 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10899 if (!AA)
10900 return nullptr;
10901
10902 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10903
10904 if (!COpt.has_value()) {
10905 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10906 return std::nullopt;
10907 }
10908 if (auto *C = *COpt) {
10909 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10910 return C;
10911 }
10912 return nullptr;
10913}
10914
10916 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10918 Type &Ty = *IRP.getAssociatedType();
10919 std::optional<Value *> V;
10920 for (auto &It : Values) {
10921 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10922 if (V.has_value() && !*V)
10923 break;
10924 }
10925 if (!V.has_value())
10926 return UndefValue::get(&Ty);
10927 return *V;
10928}
10929
10930namespace {
10931struct AAPotentialValuesImpl : AAPotentialValues {
10932 using StateType = PotentialLLVMValuesState;
10933
10934 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10935 : AAPotentialValues(IRP, A) {}
10936
10937 /// See AbstractAttribute::initialize(..).
10938 void initialize(Attributor &A) override {
10939 if (A.hasSimplificationCallback(getIRPosition())) {
10940 indicatePessimisticFixpoint();
10941 return;
10942 }
10943 Value *Stripped = getAssociatedValue().stripPointerCasts();
10944 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10945 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10946 getAnchorScope());
10947 indicateOptimisticFixpoint();
10948 return;
10949 }
10950 AAPotentialValues::initialize(A);
10951 }
10952
10953 /// See AbstractAttribute::getAsStr().
10954 const std::string getAsStr(Attributor *A) const override {
10955 std::string Str;
10956 llvm::raw_string_ostream OS(Str);
10957 OS << getState();
10958 return Str;
10959 }
10960
10961 template <typename AAType>
10962 static std::optional<Value *> askOtherAA(Attributor &A,
10963 const AbstractAttribute &AA,
10964 const IRPosition &IRP, Type &Ty) {
10966 return &IRP.getAssociatedValue();
10967 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10968 if (!C)
10969 return std::nullopt;
10970 if (*C)
10971 if (auto *CC = AA::getWithType(**C, Ty))
10972 return CC;
10973 return nullptr;
10974 }
10975
10976 virtual void addValue(Attributor &A, StateType &State, Value &V,
10977 const Instruction *CtxI, AA::ValueScope S,
10978 Function *AnchorScope) const {
10979
10980 IRPosition ValIRP = IRPosition::value(V);
10981 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10982 for (const auto &U : CB->args()) {
10983 if (U.get() != &V)
10984 continue;
10985 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10986 break;
10987 }
10988 }
10989
10990 Value *VPtr = &V;
10991 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10992 Type &Ty = *getAssociatedType();
10993 std::optional<Value *> SimpleV =
10994 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10995 if (SimpleV.has_value() && !*SimpleV) {
10996 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10997 *this, ValIRP, DepClassTy::OPTIONAL);
10998 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10999 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11000 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11001 if (PotentialConstantsAA->undefIsContained())
11002 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11003 return;
11004 }
11005 }
11006 if (!SimpleV.has_value())
11007 return;
11008
11009 if (*SimpleV)
11010 VPtr = *SimpleV;
11011 }
11012
11013 if (isa<ConstantInt>(VPtr))
11014 CtxI = nullptr;
11015 if (!AA::isValidInScope(*VPtr, AnchorScope))
11017
11018 State.unionAssumed({{*VPtr, CtxI}, S});
11019 }
11020
11021 /// Helper struct to tie a value+context pair together with the scope for
11022 /// which this is the simplified version.
11023 struct ItemInfo {
11024 AA::ValueAndContext I;
11026
11027 bool operator==(const ItemInfo &II) const {
11028 return II.I == I && II.S == S;
11029 };
11030 bool operator<(const ItemInfo &II) const {
11031 return std::tie(I, S) < std::tie(II.I, II.S);
11032 };
11033 };
11034
11035 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11036 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11037 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11038 if (!(CS & S))
11039 continue;
11040
11041 bool UsedAssumedInformation = false;
11043 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11044 UsedAssumedInformation))
11045 return false;
11046
11047 for (auto &It : Values)
11048 ValueScopeMap[It] += CS;
11049 }
11050 for (auto &It : ValueScopeMap)
11051 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11052 AA::ValueScope(It.second), getAnchorScope());
11053
11054 return true;
11055 }
11056
11057 void giveUpOnIntraprocedural(Attributor &A) {
11058 auto NewS = StateType::getBestState(getState());
11059 for (const auto &It : getAssumedSet()) {
11060 if (It.second == AA::Intraprocedural)
11061 continue;
11062 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11063 AA::Interprocedural, getAnchorScope());
11064 }
11065 assert(!undefIsContained() && "Undef should be an explicit value!");
11066 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11067 getAnchorScope());
11068 getState() = NewS;
11069 }
11070
11071 /// See AbstractState::indicatePessimisticFixpoint(...).
11072 ChangeStatus indicatePessimisticFixpoint() override {
11073 getState() = StateType::getBestState(getState());
11074 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11075 AAPotentialValues::indicateOptimisticFixpoint();
11076 return ChangeStatus::CHANGED;
11077 }
11078
11079 /// See AbstractAttribute::updateImpl(...).
11080 ChangeStatus updateImpl(Attributor &A) override {
11081 return indicatePessimisticFixpoint();
11082 }
11083
11084 /// See AbstractAttribute::manifest(...).
11085 ChangeStatus manifest(Attributor &A) override {
11088 Values.clear();
11089 if (!getAssumedSimplifiedValues(A, Values, S))
11090 continue;
11091 Value &OldV = getAssociatedValue();
11092 if (isa<UndefValue>(OldV))
11093 continue;
11094 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11095 if (!NewV || NewV == &OldV)
11096 continue;
11097 if (getCtxI() &&
11098 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11099 continue;
11100 if (A.changeAfterManifest(getIRPosition(), *NewV))
11101 return ChangeStatus::CHANGED;
11102 }
11103 return ChangeStatus::UNCHANGED;
11104 }
11105
11106 bool getAssumedSimplifiedValues(
11107 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11108 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11109 if (!isValidState())
11110 return false;
11111 bool UsedAssumedInformation = false;
11112 for (const auto &It : getAssumedSet())
11113 if (It.second & S) {
11114 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11115 isa<SelectInst>(It.first.getValue()))) {
11116 if (A.getAssumedSimplifiedValues(
11117 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11118 this, Values, S, UsedAssumedInformation))
11119 continue;
11120 }
11121 Values.push_back(It.first);
11122 }
11123 assert(!undefIsContained() && "Undef should be an explicit value!");
11124 return true;
11125 }
11126};
11127
11128struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11129 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11130 : AAPotentialValuesImpl(IRP, A) {}
11131
11132 /// See AbstractAttribute::updateImpl(...).
11133 ChangeStatus updateImpl(Attributor &A) override {
11134 auto AssumedBefore = getAssumed();
11135
11136 genericValueTraversal(A, &getAssociatedValue());
11137
11138 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11139 : ChangeStatus::CHANGED;
11140 }
11141
11142 /// Helper struct to remember which AAIsDead instances we actually used.
11143 struct LivenessInfo {
11144 const AAIsDead *LivenessAA = nullptr;
11145 bool AnyDead = false;
11146 };
11147
11148 /// Check if \p Cmp is a comparison we can simplify.
11149 ///
11150 /// We handle multiple cases, one in which at least one operand is an
11151 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11152 /// operand. Return true if successful, in that case Worklist will be updated.
11153 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11154 CmpInst::Predicate Pred, ItemInfo II,
11155 SmallVectorImpl<ItemInfo> &Worklist) {
11156
11157 // Simplify the operands first.
11158 bool UsedAssumedInformation = false;
11159 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11160 auto GetSimplifiedValues = [&](Value &V,
11162 if (!A.getAssumedSimplifiedValues(
11163 IRPosition::value(V, getCallBaseContext()), this, Values,
11164 AA::Intraprocedural, UsedAssumedInformation)) {
11165 Values.clear();
11166 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11167 }
11168 return Values.empty();
11169 };
11170 if (GetSimplifiedValues(*LHS, LHSValues))
11171 return true;
11172 if (GetSimplifiedValues(*RHS, RHSValues))
11173 return true;
11174
11175 LLVMContext &Ctx = LHS->getContext();
11176
11177 InformationCache &InfoCache = A.getInfoCache();
11178 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11179 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11180 const auto *DT =
11181 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11182 : nullptr;
11183 const auto *TLI =
11184 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11185 auto *AC =
11186 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11187 : nullptr;
11188
11189 const DataLayout &DL = A.getDataLayout();
11190 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11191
11192 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11193 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11194 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11195 /* CtxI */ nullptr, II.S, getAnchorScope());
11196 return true;
11197 }
11198
11199 // Handle the trivial case first in which we don't even need to think
11200 // about null or non-null.
11201 if (&LHSV == &RHSV &&
11203 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11205 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11206 getAnchorScope());
11207 return true;
11208 }
11209
11210 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11211 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11212 if (TypedLHS && TypedRHS) {
11213 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11214 if (NewV && NewV != &Cmp) {
11215 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11216 getAnchorScope());
11217 return true;
11218 }
11219 }
11220
11221 // From now on we only handle equalities (==, !=).
11222 if (!CmpInst::isEquality(Pred))
11223 return false;
11224
11225 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11226 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11227 if (!LHSIsNull && !RHSIsNull)
11228 return false;
11229
11230 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11231 // non-nullptr operand and if we assume it's non-null we can conclude the
11232 // result of the comparison.
11233 assert((LHSIsNull || RHSIsNull) &&
11234 "Expected nullptr versus non-nullptr comparison at this point");
11235
11236 // The index is the operand that we assume is not null.
11237 unsigned PtrIdx = LHSIsNull;
11238 bool IsKnownNonNull;
11239 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11240 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11241 DepClassTy::REQUIRED, IsKnownNonNull);
11242 if (!IsAssumedNonNull)
11243 return false;
11244
11245 // The new value depends on the predicate, true for != and false for ==.
11246 Constant *NewV =
11247 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11248 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11249 getAnchorScope());
11250 return true;
11251 };
11252
11253 for (auto &LHSValue : LHSValues)
11254 for (auto &RHSValue : RHSValues)
11255 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11256 return false;
11257 return true;
11258 }
11259
11260 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11261 SmallVectorImpl<ItemInfo> &Worklist) {
11262 const Instruction *CtxI = II.I.getCtxI();
11263 bool UsedAssumedInformation = false;
11264
11265 std::optional<Constant *> C =
11266 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11267 bool NoValueYet = !C.has_value();
11268 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11269 return true;
11270 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11271 if (CI->isZero())
11272 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11273 else
11274 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11275 } else if (&SI == &getAssociatedValue()) {
11276 // We could not simplify the condition, assume both values.
11277 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11278 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11279 } else {
11280 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11281 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11282 if (!SimpleV.has_value())
11283 return true;
11284 if (*SimpleV) {
11285 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11286 return true;
11287 }
11288 return false;
11289 }
11290 return true;
11291 }
11292
11293 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11294 SmallVectorImpl<ItemInfo> &Worklist) {
11295 SmallSetVector<Value *, 4> PotentialCopies;
11296 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11297 bool UsedAssumedInformation = false;
11298 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11299 PotentialValueOrigins, *this,
11300 UsedAssumedInformation,
11301 /* OnlyExact */ true)) {
11302 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11303 "loaded values for load instruction "
11304 << LI << "\n");
11305 return false;
11306 }
11307
11308 // Do not simplify loads that are only used in llvm.assume if we cannot also
11309 // remove all stores that may feed into the load. The reason is that the
11310 // assume is probably worth something as long as the stores are around.
11311 InformationCache &InfoCache = A.getInfoCache();
11312 if (InfoCache.isOnlyUsedByAssume(LI)) {
11313 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11314 if (!I || isa<AssumeInst>(I))
11315 return true;
11316 if (auto *SI = dyn_cast<StoreInst>(I))
11317 return A.isAssumedDead(SI->getOperandUse(0), this,
11318 /* LivenessAA */ nullptr,
11319 UsedAssumedInformation,
11320 /* CheckBBLivenessOnly */ false);
11321 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11322 UsedAssumedInformation,
11323 /* CheckBBLivenessOnly */ false);
11324 })) {
11325 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11326 "and we cannot delete all the stores: "
11327 << LI << "\n");
11328 return false;
11329 }
11330 }
11331
11332 // Values have to be dynamically unique or we loose the fact that a
11333 // single llvm::Value might represent two runtime values (e.g.,
11334 // stack locations in different recursive calls).
11335 const Instruction *CtxI = II.I.getCtxI();
11336 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11337 bool AllLocal = ScopeIsLocal;
11338 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11339 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11340 return AA::isDynamicallyUnique(A, *this, *PC);
11341 });
11342 if (!DynamicallyUnique) {
11343 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11344 "values are dynamically unique: "
11345 << LI << "\n");
11346 return false;
11347 }
11348
11349 for (auto *PotentialCopy : PotentialCopies) {
11350 if (AllLocal) {
11351 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11352 } else {
11353 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11354 }
11355 }
11356 if (!AllLocal && ScopeIsLocal)
11357 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11358 return true;
11359 }
11360
11361 bool handlePHINode(
11362 Attributor &A, PHINode &PHI, ItemInfo II,
11363 SmallVectorImpl<ItemInfo> &Worklist,
11364 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11365 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11366 LivenessInfo &LI = LivenessAAs[&F];
11367 if (!LI.LivenessAA)
11368 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11369 DepClassTy::NONE);
11370 return LI;
11371 };
11372
11373 if (&PHI == &getAssociatedValue()) {
11374 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11375 const auto *CI =
11376 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11377 *PHI.getFunction());
11378
11379 Cycle *C = nullptr;
11380 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11381 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11382 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11383 if (LI.LivenessAA &&
11384 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11385 LI.AnyDead = true;
11386 continue;
11387 }
11388 Value *V = PHI.getIncomingValue(u);
11389 if (V == &PHI)
11390 continue;
11391
11392 // If the incoming value is not the PHI but an instruction in the same
11393 // cycle we might have multiple versions of it flying around.
11394 if (CyclePHI && isa<Instruction>(V) &&
11395 (!C || C->contains(cast<Instruction>(V)->getParent())))
11396 return false;
11397
11398 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11399 }
11400 return true;
11401 }
11402
11403 bool UsedAssumedInformation = false;
11404 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11405 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11406 if (!SimpleV.has_value())
11407 return true;
11408 if (!(*SimpleV))
11409 return false;
11410 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11411 return true;
11412 }
11413
11414 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11415 /// simplify any operand of the instruction \p I. Return true if successful,
11416 /// in that case Worklist will be updated.
11417 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11418 SmallVectorImpl<ItemInfo> &Worklist) {
11419 bool SomeSimplified = false;
11420 bool UsedAssumedInformation = false;
11421
11422 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11423 int Idx = 0;
11424 for (Value *Op : I.operands()) {
11425 const auto &SimplifiedOp = A.getAssumedSimplified(
11426 IRPosition::value(*Op, getCallBaseContext()), *this,
11427 UsedAssumedInformation, AA::Intraprocedural);
11428 // If we are not sure about any operand we are not sure about the entire
11429 // instruction, we'll wait.
11430 if (!SimplifiedOp.has_value())
11431 return true;
11432
11433 if (*SimplifiedOp)
11434 NewOps[Idx] = *SimplifiedOp;
11435 else
11436 NewOps[Idx] = Op;
11437
11438 SomeSimplified |= (NewOps[Idx] != Op);
11439 ++Idx;
11440 }
11441
11442 // We won't bother with the InstSimplify interface if we didn't simplify any
11443 // operand ourselves.
11444 if (!SomeSimplified)
11445 return false;
11446
11447 InformationCache &InfoCache = A.getInfoCache();
11448 Function *F = I.getFunction();
11449 const auto *DT =
11450 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11451 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11452 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11453
11454 const DataLayout &DL = I.getDataLayout();
11455 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11456 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11457 if (!NewV || NewV == &I)
11458 return false;
11459
11460 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11461 << *NewV << "\n");
11462 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11463 return true;
11464 }
11465
11467 Attributor &A, Instruction &I, ItemInfo II,
11468 SmallVectorImpl<ItemInfo> &Worklist,
11469 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11470 if (auto *CI = dyn_cast<CmpInst>(&I))
11471 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11472 CI->getPredicate(), II, Worklist);
11473
11474 switch (I.getOpcode()) {
11475 case Instruction::Select:
11476 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11477 case Instruction::PHI:
11478 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11479 case Instruction::Load:
11480 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11481 default:
11482 return handleGenericInst(A, I, II, Worklist);
11483 };
11484 return false;
11485 }
11486
11487 void genericValueTraversal(Attributor &A, Value *InitialV) {
11488 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11489
11490 SmallSet<ItemInfo, 16> Visited;
11492 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11493
11494 int Iteration = 0;
11495 do {
11496 ItemInfo II = Worklist.pop_back_val();
11497 Value *V = II.I.getValue();
11498 assert(V);
11499 const Instruction *CtxI = II.I.getCtxI();
11500 AA::ValueScope S = II.S;
11501
11502 // Check if we should process the current value. To prevent endless
11503 // recursion keep a record of the values we followed!
11504 if (!Visited.insert(II).second)
11505 continue;
11506
11507 // Make sure we limit the compile time for complex expressions.
11508 if (Iteration++ >= MaxPotentialValuesIterations) {
11509 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11510 << Iteration << "!\n");
11511 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11512 continue;
11513 }
11514
11515 // Explicitly look through calls with a "returned" attribute if we do
11516 // not have a pointer as stripPointerCasts only works on them.
11517 Value *NewV = nullptr;
11518 if (V->getType()->isPointerTy()) {
11519 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11520 } else {
11521 if (auto *CB = dyn_cast<CallBase>(V))
11522 if (auto *Callee =
11524 for (Argument &Arg : Callee->args())
11525 if (Arg.hasReturnedAttr()) {
11526 NewV = CB->getArgOperand(Arg.getArgNo());
11527 break;
11528 }
11529 }
11530 }
11531 if (NewV && NewV != V) {
11532 Worklist.push_back({{*NewV, CtxI}, S});
11533 continue;
11534 }
11535
11536 if (auto *I = dyn_cast<Instruction>(V)) {
11537 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11538 continue;
11539 }
11540
11541 if (V != InitialV || isa<Argument>(V))
11542 if (recurseForValue(A, IRPosition::value(*V), II.S))
11543 continue;
11544
11545 // If we haven't stripped anything we give up.
11546 if (V == InitialV && CtxI == getCtxI()) {
11547 indicatePessimisticFixpoint();
11548 return;
11549 }
11550
11551 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11552 } while (!Worklist.empty());
11553
11554 // If we actually used liveness information so we have to record a
11555 // dependence.
11556 for (auto &It : LivenessAAs)
11557 if (It.second.AnyDead)
11558 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11559 }
11560
11561 /// See AbstractAttribute::trackStatistics()
11562 void trackStatistics() const override {
11563 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11564 }
11565};
11566
11567struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11568 using Base = AAPotentialValuesImpl;
11569 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11570 : Base(IRP, A) {}
11571
11572 /// See AbstractAttribute::initialize(..).
11573 void initialize(Attributor &A) override {
11574 auto &Arg = cast<Argument>(getAssociatedValue());
11576 indicatePessimisticFixpoint();
11577 }
11578
11579 /// See AbstractAttribute::updateImpl(...).
11580 ChangeStatus updateImpl(Attributor &A) override {
11581 auto AssumedBefore = getAssumed();
11582
11583 unsigned ArgNo = getCalleeArgNo();
11584
11585 bool UsedAssumedInformation = false;
11587 auto CallSitePred = [&](AbstractCallSite ACS) {
11588 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11589 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11590 return false;
11591
11592 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11594 UsedAssumedInformation))
11595 return false;
11596
11597 return isValidState();
11598 };
11599
11600 if (!A.checkForAllCallSites(CallSitePred, *this,
11601 /* RequireAllCallSites */ true,
11602 UsedAssumedInformation))
11603 return indicatePessimisticFixpoint();
11604
11605 Function *Fn = getAssociatedFunction();
11606 bool AnyNonLocal = false;
11607 for (auto &It : Values) {
11608 if (isa<Constant>(It.getValue())) {
11609 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11610 getAnchorScope());
11611 continue;
11612 }
11613 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11614 return indicatePessimisticFixpoint();
11615
11616 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11617 if (Arg->getParent() == Fn) {
11618 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11619 getAnchorScope());
11620 continue;
11621 }
11622 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11623 getAnchorScope());
11624 AnyNonLocal = true;
11625 }
11626 assert(!undefIsContained() && "Undef should be an explicit value!");
11627 if (AnyNonLocal)
11628 giveUpOnIntraprocedural(A);
11629
11630 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11631 : ChangeStatus::CHANGED;
11632 }
11633
11634 /// See AbstractAttribute::trackStatistics()
11635 void trackStatistics() const override {
11636 STATS_DECLTRACK_ARG_ATTR(potential_values)
11637 }
11638};
11639
11640struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11641 using Base = AAPotentialValuesFloating;
11642 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11643 : Base(IRP, A) {}
11644
11645 /// See AbstractAttribute::initialize(..).
11646 void initialize(Attributor &A) override {
11647 Function *F = getAssociatedFunction();
11648 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11649 indicatePessimisticFixpoint();
11650 return;
11651 }
11652
11653 for (Argument &Arg : F->args())
11654 if (Arg.hasReturnedAttr()) {
11655 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11656 ReturnedArg = &Arg;
11657 break;
11658 }
11659 if (!A.isFunctionIPOAmendable(*F) ||
11660 A.hasSimplificationCallback(getIRPosition())) {
11661 if (!ReturnedArg)
11662 indicatePessimisticFixpoint();
11663 else
11664 indicateOptimisticFixpoint();
11665 }
11666 }
11667
11668 /// See AbstractAttribute::updateImpl(...).
11669 ChangeStatus updateImpl(Attributor &A) override {
11670 auto AssumedBefore = getAssumed();
11671 bool UsedAssumedInformation = false;
11672
11674 Function *AnchorScope = getAnchorScope();
11675 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11676 bool AddValues) {
11678 Values.clear();
11679 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11680 UsedAssumedInformation,
11681 /* RecurseForSelectAndPHI */ true))
11682 return false;
11683 if (!AddValues)
11684 continue;
11685
11686 bool AllInterAreIntra = false;
11687 if (S == AA::Interprocedural)
11688 AllInterAreIntra =
11689 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11690 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11691 });
11692
11693 for (const AA::ValueAndContext &VAC : Values) {
11694 addValue(A, getState(), *VAC.getValue(),
11695 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11696 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11697 }
11698 if (AllInterAreIntra)
11699 break;
11700 }
11701 return true;
11702 };
11703
11704 if (ReturnedArg) {
11705 HandleReturnedValue(*ReturnedArg, nullptr, true);
11706 } else {
11707 auto RetInstPred = [&](Instruction &RetI) {
11708 bool AddValues = true;
11709 if (isa<PHINode>(RetI.getOperand(0)) ||
11710 isa<SelectInst>(RetI.getOperand(0))) {
11711 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11712 AnchorScope);
11713 AddValues = false;
11714 }
11715 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11716 };
11717
11718 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11719 UsedAssumedInformation,
11720 /* CheckBBLivenessOnly */ true))
11721 return indicatePessimisticFixpoint();
11722 }
11723
11724 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11725 : ChangeStatus::CHANGED;
11726 }
11727
11728 ChangeStatus manifest(Attributor &A) override {
11729 if (ReturnedArg)
11730 return ChangeStatus::UNCHANGED;
11732 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11733 /* RecurseForSelectAndPHI */ true))
11734 return ChangeStatus::UNCHANGED;
11735 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11736 if (!NewVal)
11737 return ChangeStatus::UNCHANGED;
11738
11739 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11740 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11741 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11742 "Number of function with unique return");
11743 Changed |= A.manifestAttrs(
11745 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11746 STATS_DECLTRACK_ARG_ATTR(returned);
11747 }
11748
11749 auto RetInstPred = [&](Instruction &RetI) {
11750 Value *RetOp = RetI.getOperand(0);
11751 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11752 return true;
11753 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11754 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11755 Changed = ChangeStatus::CHANGED;
11756 return true;
11757 };
11758 bool UsedAssumedInformation = false;
11759 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11760 UsedAssumedInformation,
11761 /* CheckBBLivenessOnly */ true);
11762 return Changed;
11763 }
11764
11765 ChangeStatus indicatePessimisticFixpoint() override {
11766 return AAPotentialValues::indicatePessimisticFixpoint();
11767 }
11768
11769 /// See AbstractAttribute::trackStatistics()
11770 void trackStatistics() const override{
11771 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11772
11773 /// The argumented with an existing `returned` attribute.
11774 Argument *ReturnedArg = nullptr;
11775};
11776
11777struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11778 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11779 : AAPotentialValuesImpl(IRP, A) {}
11780
11781 /// See AbstractAttribute::updateImpl(...).
11782 ChangeStatus updateImpl(Attributor &A) override {
11783 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11784 "not be called");
11785 }
11786
11787 /// See AbstractAttribute::trackStatistics()
11788 void trackStatistics() const override {
11789 STATS_DECLTRACK_FN_ATTR(potential_values)
11790 }
11791};
11792
11793struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11794 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11795 : AAPotentialValuesFunction(IRP, A) {}
11796
11797 /// See AbstractAttribute::trackStatistics()
11798 void trackStatistics() const override {
11799 STATS_DECLTRACK_CS_ATTR(potential_values)
11800 }
11801};
11802
11803struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11804 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11805 : AAPotentialValuesImpl(IRP, A) {}
11806
11807 /// See AbstractAttribute::updateImpl(...).
11808 ChangeStatus updateImpl(Attributor &A) override {
11809 auto AssumedBefore = getAssumed();
11810
11811 Function *Callee = getAssociatedFunction();
11812 if (!Callee)
11813 return indicatePessimisticFixpoint();
11814
11815 bool UsedAssumedInformation = false;
11816 auto *CB = cast<CallBase>(getCtxI());
11817 if (CB->isMustTailCall() &&
11818 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11819 UsedAssumedInformation))
11820 return indicatePessimisticFixpoint();
11821
11822 Function *Caller = CB->getCaller();
11823
11824 auto AddScope = [&](AA::ValueScope S) {
11826 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11827 Values, S, UsedAssumedInformation))
11828 return false;
11829
11830 for (auto &It : Values) {
11831 Value *V = It.getValue();
11832 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11833 V, *CB, *this, UsedAssumedInformation);
11834 if (!CallerV.has_value()) {
11835 // Nothing to do as long as no value was determined.
11836 continue;
11837 }
11838 V = *CallerV ? *CallerV : V;
11839 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11840 if (recurseForValue(A, IRPosition::value(*V), S))
11841 continue;
11842 }
11843 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11844 giveUpOnIntraprocedural(A);
11845 return true;
11846 }
11847 addValue(A, getState(), *V, CB, S, getAnchorScope());
11848 }
11849 return true;
11850 };
11851 if (!AddScope(AA::Intraprocedural))
11852 return indicatePessimisticFixpoint();
11853 if (!AddScope(AA::Interprocedural))
11854 return indicatePessimisticFixpoint();
11855 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11856 : ChangeStatus::CHANGED;
11857 }
11858
11859 ChangeStatus indicatePessimisticFixpoint() override {
11860 return AAPotentialValues::indicatePessimisticFixpoint();
11861 }
11862
11863 /// See AbstractAttribute::trackStatistics()
11864 void trackStatistics() const override {
11865 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11866 }
11867};
11868
11869struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11870 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11871 : AAPotentialValuesFloating(IRP, A) {}
11872
11873 /// See AbstractAttribute::trackStatistics()
11874 void trackStatistics() const override {
11875 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11876 }
11877};
11878} // namespace
11879
11880/// ---------------------- Assumption Propagation ------------------------------
11881namespace {
11882struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11883 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11884 const DenseSet<StringRef> &Known)
11885 : AAAssumptionInfo(IRP, A, Known) {}
11886
11887 /// See AbstractAttribute::manifest(...).
11888 ChangeStatus manifest(Attributor &A) override {
11889 // Don't manifest a universal set if it somehow made it here.
11890 if (getKnown().isUniversal())
11891 return ChangeStatus::UNCHANGED;
11892
11893 const IRPosition &IRP = getIRPosition();
11894 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11895 getAssumed().getSet().end());
11896 llvm::sort(Set);
11897 return A.manifestAttrs(IRP,
11898 Attribute::get(IRP.getAnchorValue().getContext(),
11900 llvm::join(Set, ",")),
11901 /*ForceReplace=*/true);
11902 }
11903
11904 bool hasAssumption(const StringRef Assumption) const override {
11905 return isValidState() && setContains(Assumption);
11906 }
11907
11908 /// See AbstractAttribute::getAsStr()
11909 const std::string getAsStr(Attributor *A) const override {
11910 const SetContents &Known = getKnown();
11911 const SetContents &Assumed = getAssumed();
11912
11913 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11914 llvm::sort(Set);
11915 const std::string KnownStr = llvm::join(Set, ",");
11916
11917 std::string AssumedStr = "Universal";
11918 if (!Assumed.isUniversal()) {
11919 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11920 AssumedStr = llvm::join(Set, ",");
11921 }
11922 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11923 }
11924};
11925
11926/// Propagates assumption information from parent functions to all of their
11927/// successors. An assumption can be propagated if the containing function
11928/// dominates the called function.
11929///
11930/// We start with a "known" set of assumptions already valid for the associated
11931/// function and an "assumed" set that initially contains all possible
11932/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11933/// contents as concrete values are known. The concrete values are seeded by the
11934/// first nodes that are either entries into the call graph, or contains no
11935/// assumptions. Each node is updated as the intersection of the assumed state
11936/// with all of its predecessors.
11937struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11938 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11939 : AAAssumptionInfoImpl(IRP, A,
11940 getAssumptions(*IRP.getAssociatedFunction())) {}
11941
11942 /// See AbstractAttribute::updateImpl(...).
11943 ChangeStatus updateImpl(Attributor &A) override {
11944 bool Changed = false;
11945
11946 auto CallSitePred = [&](AbstractCallSite ACS) {
11947 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11948 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11949 DepClassTy::REQUIRED);
11950 if (!AssumptionAA)
11951 return false;
11952 // Get the set of assumptions shared by all of this function's callers.
11953 Changed |= getIntersection(AssumptionAA->getAssumed());
11954 return !getAssumed().empty() || !getKnown().empty();
11955 };
11956
11957 bool UsedAssumedInformation = false;
11958 // Get the intersection of all assumptions held by this node's predecessors.
11959 // If we don't know all the call sites then this is either an entry into the
11960 // call graph or an empty node. This node is known to only contain its own
11961 // assumptions and can be propagated to its successors.
11962 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11963 UsedAssumedInformation))
11964 return indicatePessimisticFixpoint();
11965
11966 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11967 }
11968
11969 void trackStatistics() const override {}
11970};
11971
11972/// Assumption Info defined for call sites.
11973struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11974
11975 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11976 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11977
11978 /// See AbstractAttribute::initialize(...).
11979 void initialize(Attributor &A) override {
11980 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11981 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11982 }
11983
11984 /// See AbstractAttribute::updateImpl(...).
11985 ChangeStatus updateImpl(Attributor &A) override {
11986 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11987 auto *AssumptionAA =
11988 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11989 if (!AssumptionAA)
11990 return indicatePessimisticFixpoint();
11991 bool Changed = getIntersection(AssumptionAA->getAssumed());
11992 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11993 }
11994
11995 /// See AbstractAttribute::trackStatistics()
11996 void trackStatistics() const override {}
11997
11998private:
11999 /// Helper to initialized the known set as all the assumptions this call and
12000 /// the callee contain.
12001 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12002 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12003 auto Assumptions = getAssumptions(CB);
12004 if (const Function *F = CB.getCaller())
12005 set_union(Assumptions, getAssumptions(*F));
12006 if (Function *F = IRP.getAssociatedFunction())
12007 set_union(Assumptions, getAssumptions(*F));
12008 return Assumptions;
12009 }
12010};
12011} // namespace
12012
12014 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12015 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12016}
12017
12019
12020/// ------------------------ UnderlyingObjects ---------------------------------
12021
12022namespace {
12023struct AAUnderlyingObjectsImpl
12024 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12026 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12027
12028 /// See AbstractAttribute::getAsStr().
12029 const std::string getAsStr(Attributor *A) const override {
12030 if (!isValidState())
12031 return "<invalid>";
12032 std::string Str;
12034 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12035 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12036 << " objects.\n";
12037 if (!InterAssumedUnderlyingObjects.empty()) {
12038 OS << "inter objects:\n";
12039 for (auto *Obj : InterAssumedUnderlyingObjects)
12040 OS << *Obj << '\n';
12041 }
12042 if (!IntraAssumedUnderlyingObjects.empty()) {
12043 OS << "intra objects:\n";
12044 for (auto *Obj : IntraAssumedUnderlyingObjects)
12045 OS << *Obj << '\n';
12046 }
12047 return Str;
12048 }
12049
12050 /// See AbstractAttribute::trackStatistics()
12051 void trackStatistics() const override {}
12052
12053 /// See AbstractAttribute::updateImpl(...).
12054 ChangeStatus updateImpl(Attributor &A) override {
12055 auto &Ptr = getAssociatedValue();
12056
12057 bool UsedAssumedInformation = false;
12058 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12060 SmallPtrSet<Value *, 8> SeenObjects;
12062
12063 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12064 Scope, UsedAssumedInformation))
12065 return UnderlyingObjects.insert(&Ptr);
12066
12067 bool Changed = false;
12068
12069 for (unsigned I = 0; I < Values.size(); ++I) {
12070 auto &VAC = Values[I];
12071 auto *Obj = VAC.getValue();
12072 Value *UO = getUnderlyingObject(Obj);
12073 if (!SeenObjects.insert(UO ? UO : Obj).second)
12074 continue;
12075 if (UO && UO != Obj) {
12076 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12077 Changed |= UnderlyingObjects.insert(UO);
12078 continue;
12079 }
12080
12081 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12082 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12083 auto Pred = [&](Value &V) {
12084 if (&V == UO)
12085 Changed |= UnderlyingObjects.insert(UO);
12086 else
12087 Values.emplace_back(V, nullptr);
12088 return true;
12089 };
12090
12091 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12093 "The forall call should not return false at this position");
12094 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12095 continue;
12096 }
12097
12098 if (isa<SelectInst>(Obj)) {
12099 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12100 UsedAssumedInformation);
12101 continue;
12102 }
12103 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12104 // Explicitly look through PHIs as we do not care about dynamically
12105 // uniqueness.
12106 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12107 Changed |=
12108 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12109 Scope, UsedAssumedInformation);
12110 }
12111 continue;
12112 }
12113
12114 Changed |= UnderlyingObjects.insert(Obj);
12115 }
12116
12117 return Changed;
12118 };
12119
12120 bool Changed = false;
12121 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12122 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12123 if (!UsedAssumedInformation)
12124 indicateOptimisticFixpoint();
12125 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12126 }
12127
12128 bool forallUnderlyingObjects(
12129 function_ref<bool(Value &)> Pred,
12130 AA::ValueScope Scope = AA::Interprocedural) const override {
12131 if (!isValidState())
12132 return Pred(getAssociatedValue());
12133
12134 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12135 ? IntraAssumedUnderlyingObjects
12136 : InterAssumedUnderlyingObjects;
12137 for (Value *Obj : AssumedUnderlyingObjects)
12138 if (!Pred(*Obj))
12139 return false;
12140
12141 return true;
12142 }
12143
12144private:
12145 /// Handle the case where the value is not the actual underlying value, such
12146 /// as a phi node or a select instruction.
12147 bool handleIndirect(Attributor &A, Value &V,
12148 SmallSetVector<Value *, 8> &UnderlyingObjects,
12149 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12150 bool Changed = false;
12151 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12152 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12153 auto Pred = [&](Value &V) {
12154 Changed |= UnderlyingObjects.insert(&V);
12155 return true;
12156 };
12157 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12159 "The forall call should not return false at this position");
12160 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12161 return Changed;
12162 }
12163
12164 /// All the underlying objects collected so far via intra procedural scope.
12165 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12166 /// All the underlying objects collected so far via inter procedural scope.
12167 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12168};
12169
12170struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12171 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12172 : AAUnderlyingObjectsImpl(IRP, A) {}
12173};
12174
12175struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12176 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12177 : AAUnderlyingObjectsImpl(IRP, A) {}
12178};
12179
12180struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12181 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12182 : AAUnderlyingObjectsImpl(IRP, A) {}
12183};
12184
12185struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12186 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12187 : AAUnderlyingObjectsImpl(IRP, A) {}
12188};
12189
12190struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12191 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12192 : AAUnderlyingObjectsImpl(IRP, A) {}
12193};
12194
12195struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12196 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12197 : AAUnderlyingObjectsImpl(IRP, A) {}
12198};
12199
12200struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12201 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12202 : AAUnderlyingObjectsImpl(IRP, A) {}
12203};
12204} // namespace
12205
12206/// ------------------------ Global Value Info -------------------------------
12207namespace {
12208struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12209 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12210 : AAGlobalValueInfo(IRP, A) {}
12211
12212 /// See AbstractAttribute::initialize(...).
12213 void initialize(Attributor &A) override {}
12214
12215 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12216 SmallVectorImpl<const Value *> &Worklist) {
12217 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12218 if (!UInst) {
12219 Follow = true;
12220 return true;
12221 }
12222
12223 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12224 << *UInst << "\n");
12225
12226 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12227 int Idx = &Cmp->getOperandUse(0) == &U;
12228 if (isa<Constant>(Cmp->getOperand(Idx)))
12229 return true;
12230 return U == &getAnchorValue();
12231 }
12232
12233 // Explicitly catch return instructions.
12234 if (isa<ReturnInst>(UInst)) {
12235 auto CallSitePred = [&](AbstractCallSite ACS) {
12236 Worklist.push_back(ACS.getInstruction());
12237 return true;
12238 };
12239 bool UsedAssumedInformation = false;
12240 // TODO: We should traverse the uses or add a "non-call-site" CB.
12241 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12242 /*RequireAllCallSites=*/true, this,
12243 UsedAssumedInformation))
12244 return false;
12245 return true;
12246 }
12247
12248 // For now we only use special logic for call sites. However, the tracker
12249 // itself knows about a lot of other non-capturing cases already.
12250 auto *CB = dyn_cast<CallBase>(UInst);
12251 if (!CB)
12252 return false;
12253 // Direct calls are OK uses.
12254 if (CB->isCallee(&U))
12255 return true;
12256 // Non-argument uses are scary.
12257 if (!CB->isArgOperand(&U))
12258 return false;
12259 // TODO: Iterate callees.
12260 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12261 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12262 return false;
12263
12264 unsigned ArgNo = CB->getArgOperandNo(&U);
12265 Worklist.push_back(Fn->getArg(ArgNo));
12266 return true;
12267 }
12268
12269 ChangeStatus updateImpl(Attributor &A) override {
12270 unsigned NumUsesBefore = Uses.size();
12271
12272 SmallPtrSet<const Value *, 8> Visited;
12274 Worklist.push_back(&getAnchorValue());
12275
12276 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12277 Uses.insert(&U);
12278 // TODO(captures): Make this more precise.
12279 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12280 if (CI.isPassthrough()) {
12281 Follow = true;
12282 return true;
12283 }
12284 return checkUse(A, U, Follow, Worklist);
12285 };
12286 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12287 Uses.insert(&OldU);
12288 return true;
12289 };
12290
12291 while (!Worklist.empty()) {
12292 const Value *V = Worklist.pop_back_val();
12293 if (!Visited.insert(V).second)
12294 continue;
12295 if (!A.checkForAllUses(UsePred, *this, *V,
12296 /* CheckBBLivenessOnly */ true,
12297 DepClassTy::OPTIONAL,
12298 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12299 return indicatePessimisticFixpoint();
12300 }
12301 }
12302
12303 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12304 : ChangeStatus::CHANGED;
12305 }
12306
12307 bool isPotentialUse(const Use &U) const override {
12308 return !isValidState() || Uses.contains(&U);
12309 }
12310
12311 /// See AbstractAttribute::manifest(...).
12312 ChangeStatus manifest(Attributor &A) override {
12313 return ChangeStatus::UNCHANGED;
12314 }
12315
12316 /// See AbstractAttribute::getAsStr().
12317 const std::string getAsStr(Attributor *A) const override {
12318 return "[" + std::to_string(Uses.size()) + " uses]";
12319 }
12320
12321 void trackStatistics() const override {
12322 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12323 }
12324
12325private:
12326 /// Set of (transitive) uses of this GlobalValue.
12327 SmallPtrSet<const Use *, 8> Uses;
12328};
12329} // namespace
12330
12331/// ------------------------ Indirect Call Info -------------------------------
12332namespace {
12333struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12334 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12335 : AAIndirectCallInfo(IRP, A) {}
12336
12337 /// See AbstractAttribute::initialize(...).
12338 void initialize(Attributor &A) override {
12339 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12340 if (!MD && !A.isClosedWorldModule())
12341 return;
12342
12343 if (MD) {
12344 for (const auto &Op : MD->operands())
12345 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12346 PotentialCallees.insert(Callee);
12347 } else if (A.isClosedWorldModule()) {
12348 ArrayRef<Function *> IndirectlyCallableFunctions =
12349 A.getInfoCache().getIndirectlyCallableFunctions(A);
12350 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12351 }
12352
12353 if (PotentialCallees.empty())
12354 indicateOptimisticFixpoint();
12355 }
12356
12357 ChangeStatus updateImpl(Attributor &A) override {
12358 CallBase *CB = cast<CallBase>(getCtxI());
12359 const Use &CalleeUse = CB->getCalledOperandUse();
12360 Value *FP = CB->getCalledOperand();
12361
12362 SmallSetVector<Function *, 4> AssumedCalleesNow;
12363 bool AllCalleesKnownNow = AllCalleesKnown;
12364
12365 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12366 bool &UsedAssumedInformation) {
12367 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12368 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12369 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12370 return true;
12371 UsedAssumedInformation = !GIAA->isAtFixpoint();
12372 return false;
12373 };
12374
12375 auto AddPotentialCallees = [&]() {
12376 for (auto *PotentialCallee : PotentialCallees) {
12377 bool UsedAssumedInformation = false;
12378 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12379 AssumedCalleesNow.insert(PotentialCallee);
12380 }
12381 };
12382
12383 // Use simplification to find potential callees, if !callees was present,
12384 // fallback to that set if necessary.
12385 bool UsedAssumedInformation = false;
12387 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12388 AA::ValueScope::AnyScope,
12389 UsedAssumedInformation)) {
12390 if (PotentialCallees.empty())
12391 return indicatePessimisticFixpoint();
12392 AddPotentialCallees();
12393 }
12394
12395 // Try to find a reason for \p Fn not to be a potential callee. If none was
12396 // found, add it to the assumed callees set.
12397 auto CheckPotentialCallee = [&](Function &Fn) {
12398 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12399 return false;
12400
12401 auto &CachedResult = FilterResults[&Fn];
12402 if (CachedResult.has_value())
12403 return CachedResult.value();
12404
12405 bool UsedAssumedInformation = false;
12406 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12407 if (!UsedAssumedInformation)
12408 CachedResult = false;
12409 return false;
12410 }
12411
12412 int NumFnArgs = Fn.arg_size();
12413 int NumCBArgs = CB->arg_size();
12414
12415 // Check if any excess argument (which we fill up with poison) is known to
12416 // be UB on undef.
12417 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12418 bool IsKnown = false;
12420 A, this, IRPosition::argument(*Fn.getArg(I)),
12421 DepClassTy::OPTIONAL, IsKnown)) {
12422 if (IsKnown)
12423 CachedResult = false;
12424 return false;
12425 }
12426 }
12427
12428 CachedResult = true;
12429 return true;
12430 };
12431
12432 // Check simplification result, prune known UB callees, also restrict it to
12433 // the !callees set, if present.
12434 for (auto &VAC : Values) {
12435 if (isa<UndefValue>(VAC.getValue()))
12436 continue;
12438 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12439 continue;
12440 // TODO: Check for known UB, e.g., poison + noundef.
12441 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12442 if (CheckPotentialCallee(*VACFn))
12443 AssumedCalleesNow.insert(VACFn);
12444 continue;
12445 }
12446 if (!PotentialCallees.empty()) {
12447 AddPotentialCallees();
12448 break;
12449 }
12450 AllCalleesKnownNow = false;
12451 }
12452
12453 if (AssumedCalleesNow == AssumedCallees &&
12454 AllCalleesKnown == AllCalleesKnownNow)
12455 return ChangeStatus::UNCHANGED;
12456
12457 std::swap(AssumedCallees, AssumedCalleesNow);
12458 AllCalleesKnown = AllCalleesKnownNow;
12459 return ChangeStatus::CHANGED;
12460 }
12461
12462 /// See AbstractAttribute::manifest(...).
12463 ChangeStatus manifest(Attributor &A) override {
12464 // If we can't specialize at all, give up now.
12465 if (!AllCalleesKnown && AssumedCallees.empty())
12466 return ChangeStatus::UNCHANGED;
12467
12468 CallBase *CB = cast<CallBase>(getCtxI());
12469 bool UsedAssumedInformation = false;
12470 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12471 UsedAssumedInformation))
12472 return ChangeStatus::UNCHANGED;
12473
12474 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12475 Value *FP = CB->getCalledOperand();
12476 if (FP->getType()->getPointerAddressSpace())
12477 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12478 FP->getName() + ".as0", CB->getIterator());
12479
12480 bool CBIsVoid = CB->getType()->isVoidTy();
12482 FunctionType *CSFT = CB->getFunctionType();
12483 SmallVector<Value *> CSArgs(CB->args());
12484
12485 // If we know all callees and there are none, the call site is (effectively)
12486 // dead (or UB).
12487 if (AssumedCallees.empty()) {
12488 assert(AllCalleesKnown &&
12489 "Expected all callees to be known if there are none.");
12490 A.changeToUnreachableAfterManifest(CB);
12491 return ChangeStatus::CHANGED;
12492 }
12493
12494 // Special handling for the single callee case.
12495 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12496 auto *NewCallee = AssumedCallees.front();
12497 if (isLegalToPromote(*CB, NewCallee)) {
12498 promoteCall(*CB, NewCallee, nullptr);
12499 NumIndirectCallsPromoted++;
12500 return ChangeStatus::CHANGED;
12501 }
12502 Instruction *NewCall =
12503 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12504 CB->getName(), CB->getIterator());
12505 if (!CBIsVoid)
12506 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12507 A.deleteAfterManifest(*CB);
12508 return ChangeStatus::CHANGED;
12509 }
12510
12511 // For each potential value we create a conditional
12512 //
12513 // ```
12514 // if (ptr == value) value(args);
12515 // else ...
12516 // ```
12517 //
12518 bool SpecializedForAnyCallees = false;
12519 bool SpecializedForAllCallees = AllCalleesKnown;
12520 ICmpInst *LastCmp = nullptr;
12521 SmallVector<Function *, 8> SkippedAssumedCallees;
12523 for (Function *NewCallee : AssumedCallees) {
12524 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12525 AssumedCallees.size())) {
12526 SkippedAssumedCallees.push_back(NewCallee);
12527 SpecializedForAllCallees = false;
12528 continue;
12529 }
12530 SpecializedForAnyCallees = true;
12531
12532 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12533 Instruction *ThenTI =
12534 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12535 BasicBlock *CBBB = CB->getParent();
12536 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12537 A.registerManifestAddedBasicBlock(*IP->getParent());
12538 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12539 BasicBlock *ElseBB;
12540 if (&*IP == CB) {
12541 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12542 ThenTI->getFunction(), CBBB);
12543 A.registerManifestAddedBasicBlock(*ElseBB);
12544 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12545 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12546 } else {
12547 ElseBB = IP->getParent();
12548 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12549 }
12550 CastInst *RetBC = nullptr;
12551 CallInst *NewCall = nullptr;
12552 if (isLegalToPromote(*CB, NewCallee)) {
12553 auto *CBClone = cast<CallBase>(CB->clone());
12554 CBClone->insertBefore(ThenTI->getIterator());
12555 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12556 NumIndirectCallsPromoted++;
12557 } else {
12558 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12559 CB->getName(), ThenTI->getIterator());
12560 }
12561 NewCalls.push_back({NewCall, RetBC});
12562 }
12563
12564 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12565 if (!AllCalleesKnown)
12566 return ChangeStatus::UNCHANGED;
12567 MDBuilder MDB(IndirectCB.getContext());
12568 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12569 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12570 return ChangeStatus::CHANGED;
12571 };
12572
12573 if (!SpecializedForAnyCallees)
12574 return AttachCalleeMetadata(*CB);
12575
12576 // Check if we need the fallback indirect call still.
12577 if (SpecializedForAllCallees) {
12579 LastCmp->eraseFromParent();
12580 new UnreachableInst(IP->getContext(), IP);
12581 IP->eraseFromParent();
12582 } else {
12583 auto *CBClone = cast<CallInst>(CB->clone());
12584 CBClone->setName(CB->getName());
12585 CBClone->insertBefore(*IP->getParent(), IP);
12586 NewCalls.push_back({CBClone, nullptr});
12587 AttachCalleeMetadata(*CBClone);
12588 }
12589
12590 // Check if we need a PHI to merge the results.
12591 if (!CBIsVoid) {
12592 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12593 CB->getName() + ".phi",
12594 CB->getParent()->getFirstInsertionPt());
12595 for (auto &It : NewCalls) {
12596 CallBase *NewCall = It.first;
12597 Instruction *CallRet = It.second ? It.second : It.first;
12598 if (CallRet->getType() == CB->getType())
12599 PHI->addIncoming(CallRet, CallRet->getParent());
12600 else if (NewCall->getType()->isVoidTy())
12601 PHI->addIncoming(PoisonValue::get(CB->getType()),
12602 NewCall->getParent());
12603 else
12604 llvm_unreachable("Call return should match or be void!");
12605 }
12606 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12607 }
12608
12609 A.deleteAfterManifest(*CB);
12610 Changed = ChangeStatus::CHANGED;
12611
12612 return Changed;
12613 }
12614
12615 /// See AbstractAttribute::getAsStr().
12616 const std::string getAsStr(Attributor *A) const override {
12617 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12618 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12619 " functions";
12620 }
12621
12622 void trackStatistics() const override {
12623 if (AllCalleesKnown) {
12625 Eliminated, CallSites,
12626 "Number of indirect call sites eliminated via specialization")
12627 } else {
12628 STATS_DECLTRACK(Specialized, CallSites,
12629 "Number of indirect call sites specialized")
12630 }
12631 }
12632
12633 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12634 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12635 }
12636
12637private:
12638 /// Map to remember filter results.
12639 DenseMap<Function *, std::optional<bool>> FilterResults;
12640
12641 /// If the !callee metadata was present, this set will contain all potential
12642 /// callees (superset).
12643 SmallSetVector<Function *, 4> PotentialCallees;
12644
12645 /// This set contains all currently assumed calllees, which might grow over
12646 /// time.
12647 SmallSetVector<Function *, 4> AssumedCallees;
12648
12649 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12650 /// if there could be others.
12651 bool AllCalleesKnown = true;
12652};
12653} // namespace
12654
12655/// --------------------- Invariant Load Pointer -------------------------------
12656namespace {
12657
12658struct AAInvariantLoadPointerImpl
12659 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12660 AAInvariantLoadPointer> {
12661
12662 enum {
12663 // pointer does not alias within the bounds of the function
12664 IS_NOALIAS = 1 << 0,
12665 // pointer is not involved in any effectful instructions within the bounds
12666 // of the function
12667 IS_NOEFFECT = 1 << 1,
12668 // loads are invariant within the bounds of the function
12669 IS_LOCALLY_INVARIANT = 1 << 2,
12670 // memory lifetime is constrained within the bounds of the function
12671 IS_LOCALLY_CONSTRAINED = 1 << 3,
12672
12673 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12674 IS_LOCALLY_CONSTRAINED,
12675 };
12676 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12677
12678 using Base =
12679 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12680
12681 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12682 // pessimistic about IS_KNOWN_INVARIANT
12683 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12684 : Base(IRP) {}
12685
12686 bool isKnownInvariant() const final {
12687 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12688 }
12689
12690 bool isKnownLocallyInvariant() const final {
12691 if (isKnown(IS_LOCALLY_INVARIANT))
12692 return true;
12693 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12694 }
12695
12696 bool isAssumedInvariant() const final {
12697 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12698 }
12699
12700 bool isAssumedLocallyInvariant() const final {
12701 if (isAssumed(IS_LOCALLY_INVARIANT))
12702 return true;
12703 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12704 }
12705
12706 ChangeStatus updateImpl(Attributor &A) override {
12707 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12708
12709 Changed |= updateNoAlias(A);
12710 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12711 return indicatePessimisticFixpoint();
12712
12713 Changed |= updateNoEffect(A);
12714
12715 Changed |= updateLocalInvariance(A);
12716
12717 return Changed;
12718 }
12719
12720 ChangeStatus manifest(Attributor &A) override {
12721 if (!isKnownInvariant())
12722 return ChangeStatus::UNCHANGED;
12723
12724 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12725 const Value *Ptr = &getAssociatedValue();
12726 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12727 if (U.get() != Ptr)
12728 return true;
12729 auto *I = dyn_cast<Instruction>(U.getUser());
12730 if (!I)
12731 return true;
12732
12733 // Ensure that we are only changing uses from the corresponding callgraph
12734 // SSC in the case that the AA isn't run on the entire module
12735 if (!A.isRunOn(I->getFunction()))
12736 return true;
12737
12738 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12739 return true;
12740
12741 if (auto *LI = dyn_cast<LoadInst>(I)) {
12742 LI->setMetadata(LLVMContext::MD_invariant_load,
12743 MDNode::get(LI->getContext(), {}));
12744 Changed = ChangeStatus::CHANGED;
12745 }
12746 return true;
12747 };
12748
12749 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12750 return Changed;
12751 }
12752
12753 /// See AbstractAttribute::getAsStr().
12754 const std::string getAsStr(Attributor *) const override {
12755 if (isKnownInvariant())
12756 return "load-invariant pointer";
12757 return "non-invariant pointer";
12758 }
12759
12760 /// See AbstractAttribute::trackStatistics().
12761 void trackStatistics() const override {}
12762
12763private:
12764 /// Indicate that noalias is required for the pointer to be invariant.
12765 bool requiresNoAlias() const {
12766 switch (getPositionKind()) {
12767 default:
12768 // Conservatively default to require noalias.
12769 return true;
12770 case IRP_FLOAT:
12771 case IRP_RETURNED:
12772 case IRP_CALL_SITE:
12773 return false;
12774 case IRP_CALL_SITE_RETURNED: {
12775 const auto &CB = cast<CallBase>(getAnchorValue());
12777 &CB, /*MustPreserveNullness=*/false);
12778 }
12779 case IRP_ARGUMENT: {
12780 const Function *F = getAssociatedFunction();
12781 assert(F && "no associated function for argument");
12782 return !isCallableCC(F->getCallingConv());
12783 }
12784 }
12785 }
12786
12787 bool isExternal() const {
12788 const Function *F = getAssociatedFunction();
12789 if (!F)
12790 return true;
12791 return isCallableCC(F->getCallingConv()) &&
12792 getPositionKind() != IRP_CALL_SITE_RETURNED;
12793 }
12794
12795 ChangeStatus updateNoAlias(Attributor &A) {
12796 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12797 return ChangeStatus::UNCHANGED;
12798
12799 // Try to use AANoAlias.
12800 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12801 getIRPosition(), this, DepClassTy::REQUIRED)) {
12802 if (ANoAlias->isKnownNoAlias()) {
12803 addKnownBits(IS_NOALIAS);
12804 return ChangeStatus::CHANGED;
12805 }
12806
12807 if (!ANoAlias->isAssumedNoAlias()) {
12808 removeAssumedBits(IS_NOALIAS);
12809 return ChangeStatus::CHANGED;
12810 }
12811
12812 return ChangeStatus::UNCHANGED;
12813 }
12814
12815 // Try to infer noalias from argument attribute, since it is applicable for
12816 // the duration of the function.
12817 if (const Argument *Arg = getAssociatedArgument()) {
12818 if (Arg->hasNoAliasAttr()) {
12819 addKnownBits(IS_NOALIAS);
12820 return ChangeStatus::UNCHANGED;
12821 }
12822
12823 // Noalias information is not provided, and cannot be inferred,
12824 // so we conservatively assume the pointer aliases.
12825 removeAssumedBits(IS_NOALIAS);
12826 return ChangeStatus::CHANGED;
12827 }
12828
12829 return ChangeStatus::UNCHANGED;
12830 }
12831
12832 ChangeStatus updateNoEffect(Attributor &A) {
12833 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12834 return ChangeStatus::UNCHANGED;
12835
12836 if (!getAssociatedFunction())
12837 return indicatePessimisticFixpoint();
12838
12839 if (isa<AllocaInst>(&getAssociatedValue()))
12840 return indicatePessimisticFixpoint();
12841
12842 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12843 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12844 return !LI || !LI->mayHaveSideEffects();
12845 };
12846 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12847 return indicatePessimisticFixpoint();
12848
12849 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12850 getIRPosition(), this, DepClassTy::REQUIRED)) {
12851 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12852 // attribute
12853 if (!AMemoryBehavior->isAssumedReadOnly())
12854 return indicatePessimisticFixpoint();
12855
12856 if (AMemoryBehavior->isKnownReadOnly()) {
12857 addKnownBits(IS_NOEFFECT);
12858 return ChangeStatus::UNCHANGED;
12859 }
12860
12861 return ChangeStatus::UNCHANGED;
12862 }
12863
12864 if (const Argument *Arg = getAssociatedArgument()) {
12865 if (Arg->onlyReadsMemory()) {
12866 addKnownBits(IS_NOEFFECT);
12867 return ChangeStatus::UNCHANGED;
12868 }
12869
12870 // Readonly information is not provided, and cannot be inferred from
12871 // AAMemoryBehavior.
12872 return indicatePessimisticFixpoint();
12873 }
12874
12875 return ChangeStatus::UNCHANGED;
12876 }
12877
12878 ChangeStatus updateLocalInvariance(Attributor &A) {
12879 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12880 return ChangeStatus::UNCHANGED;
12881
12882 // try to infer invariance from underlying objects
12883 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12884 getIRPosition(), this, DepClassTy::REQUIRED);
12885 if (!AUO)
12886 return ChangeStatus::UNCHANGED;
12887
12888 bool UsedAssumedInformation = false;
12889 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12890 if (!V.getType()->isPointerTy())
12891 return true;
12892 const auto *IsInvariantLoadPointer =
12893 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12894 DepClassTy::REQUIRED);
12895 // Conservatively fail if invariance cannot be inferred.
12896 if (!IsInvariantLoadPointer)
12897 return false;
12898
12899 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12900 return true;
12901 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12902 return false;
12903
12904 UsedAssumedInformation = true;
12905 return true;
12906 };
12907 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12908 return indicatePessimisticFixpoint();
12909
12910 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12912 CB, /*MustPreserveNullness=*/false)) {
12913 for (const Value *Arg : CB->args()) {
12914 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12915 return indicatePessimisticFixpoint();
12916 }
12917 }
12918 }
12919
12920 if (!UsedAssumedInformation) {
12921 // Pointer is known and not just assumed to be locally invariant.
12922 addKnownBits(IS_LOCALLY_INVARIANT);
12923 return ChangeStatus::CHANGED;
12924 }
12925
12926 return ChangeStatus::UNCHANGED;
12927 }
12928};
12929
12930struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12931 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12932 : AAInvariantLoadPointerImpl(IRP, A) {}
12933};
12934
12935struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12936 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12937 : AAInvariantLoadPointerImpl(IRP, A) {}
12938
12939 void initialize(Attributor &) override {
12940 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12941 }
12942};
12943
12944struct AAInvariantLoadPointerCallSiteReturned final
12945 : AAInvariantLoadPointerImpl {
12946 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12947 : AAInvariantLoadPointerImpl(IRP, A) {}
12948
12949 void initialize(Attributor &A) override {
12950 const Function *F = getAssociatedFunction();
12951 assert(F && "no associated function for return from call");
12952
12953 if (!F->isDeclaration() && !F->isIntrinsic())
12954 return AAInvariantLoadPointerImpl::initialize(A);
12955
12956 const auto &CB = cast<CallBase>(getAnchorValue());
12958 &CB, /*MustPreserveNullness=*/false))
12959 return AAInvariantLoadPointerImpl::initialize(A);
12960
12961 if (F->onlyReadsMemory() && F->hasNoSync())
12962 return AAInvariantLoadPointerImpl::initialize(A);
12963
12964 // At this point, the function is opaque, so we conservatively assume
12965 // non-invariance.
12966 indicatePessimisticFixpoint();
12967 }
12968};
12969
12970struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12971 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12972 : AAInvariantLoadPointerImpl(IRP, A) {}
12973
12974 void initialize(Attributor &) override {
12975 const Function *F = getAssociatedFunction();
12976 assert(F && "no associated function for argument");
12977
12978 if (!isCallableCC(F->getCallingConv())) {
12979 addKnownBits(IS_LOCALLY_CONSTRAINED);
12980 return;
12981 }
12982
12983 if (!F->hasLocalLinkage())
12984 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12985 }
12986};
12987
12988struct AAInvariantLoadPointerCallSiteArgument final
12989 : AAInvariantLoadPointerImpl {
12990 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12991 : AAInvariantLoadPointerImpl(IRP, A) {}
12992};
12993} // namespace
12994
12995/// ------------------------ Address Space ------------------------------------
12996namespace {
12997
12998template <typename InstType>
12999static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13000 Value *OriginalValue, PointerType *NewPtrTy,
13001 bool UseOriginalValue) {
13002 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13003 return false;
13004
13005 if (MemInst->isVolatile()) {
13006 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13007 *MemInst->getFunction());
13008 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13009 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13010 return false;
13011 }
13012
13013 if (UseOriginalValue) {
13014 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13015 return true;
13016 }
13017
13018 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13019 CastInst->insertBefore(MemInst->getIterator());
13020 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13021 return true;
13022}
13023
13024struct AAAddressSpaceImpl : public AAAddressSpace {
13025 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13026 : AAAddressSpace(IRP, A) {}
13027
13028 uint32_t getAddressSpace() const override {
13029 assert(isValidState() && "the AA is invalid");
13030 return AssumedAddressSpace;
13031 }
13032
13033 /// See AbstractAttribute::initialize(...).
13034 void initialize(Attributor &A) override {
13035 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13036 "Associated value is not a pointer");
13037
13038 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13039 indicatePessimisticFixpoint();
13040 return;
13041 }
13042
13043 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13044 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13045 if (AS != FlatAS) {
13046 [[maybe_unused]] bool R = takeAddressSpace(AS);
13047 assert(R && "The take should happen");
13048 indicateOptimisticFixpoint();
13049 }
13050 }
13051
13052 ChangeStatus updateImpl(Attributor &A) override {
13053 uint32_t OldAddressSpace = AssumedAddressSpace;
13054 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13055
13056 auto CheckAddressSpace = [&](Value &Obj) {
13057 // Ignore undef.
13058 if (isa<UndefValue>(&Obj))
13059 return true;
13060
13061 // If the object already has a non-flat address space, we simply take it.
13062 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13063 if (ObjAS != FlatAS)
13064 return takeAddressSpace(ObjAS);
13065
13066 // At this point, we know Obj is in the flat address space. For a final
13067 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13068 // associated function, if possible.
13069 Function *F = nullptr;
13070 if (auto *Arg = dyn_cast<Argument>(&Obj))
13071 F = Arg->getParent();
13072 else if (auto *I = dyn_cast<Instruction>(&Obj))
13073 F = I->getFunction();
13074
13075 // Use getAssumedAddrSpace if the associated function exists.
13076 if (F) {
13077 auto *TTI =
13078 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13079 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13080 if (AssumedAS != ~0U)
13081 return takeAddressSpace(AssumedAS);
13082 }
13083
13084 // Now we can't do anything else but to take the flat AS.
13085 return takeAddressSpace(FlatAS);
13086 };
13087
13088 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13089 DepClassTy::REQUIRED);
13090 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13091 return indicatePessimisticFixpoint();
13092
13093 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13094 : ChangeStatus::CHANGED;
13095 }
13096
13097 /// See AbstractAttribute::manifest(...).
13098 ChangeStatus manifest(Attributor &A) override {
13099 unsigned NewAS = getAddressSpace();
13100
13101 if (NewAS == InvalidAddressSpace ||
13102 NewAS == getAssociatedType()->getPointerAddressSpace())
13103 return ChangeStatus::UNCHANGED;
13104
13105 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13106
13107 Value *AssociatedValue = &getAssociatedValue();
13108 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13109
13110 PointerType *NewPtrTy =
13111 PointerType::get(getAssociatedType()->getContext(), NewAS);
13112 bool UseOriginalValue =
13113 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13114
13115 bool Changed = false;
13116
13117 auto Pred = [&](const Use &U, bool &) {
13118 if (U.get() != AssociatedValue)
13119 return true;
13120 auto *Inst = dyn_cast<Instruction>(U.getUser());
13121 if (!Inst)
13122 return true;
13123 // This is a WA to make sure we only change uses from the corresponding
13124 // CGSCC if the AA is run on CGSCC instead of the entire module.
13125 if (!A.isRunOn(Inst->getFunction()))
13126 return true;
13127 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13128 Changed |=
13129 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13130 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13131 Changed |=
13132 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13133 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13134 Changed |=
13135 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13136 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13137 Changed |=
13138 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13139 }
13140 return true;
13141 };
13142
13143 // It doesn't matter if we can't check all uses as we can simply
13144 // conservatively ignore those that can not be visited.
13145 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13146 /* CheckBBLivenessOnly */ true);
13147
13148 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13149 }
13150
13151 /// See AbstractAttribute::getAsStr().
13152 const std::string getAsStr(Attributor *A) const override {
13153 if (!isValidState())
13154 return "addrspace(<invalid>)";
13155 return "addrspace(" +
13156 (AssumedAddressSpace == InvalidAddressSpace
13157 ? "none"
13158 : std::to_string(AssumedAddressSpace)) +
13159 ")";
13160 }
13161
13162private:
13163 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13164
13165 bool takeAddressSpace(uint32_t AS) {
13166 if (AssumedAddressSpace == InvalidAddressSpace) {
13167 AssumedAddressSpace = AS;
13168 return true;
13169 }
13170 return AssumedAddressSpace == AS;
13171 }
13172
13173 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13174 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13175 assert(I->getSrcAddressSpace() != FlatAS &&
13176 "there should not be flat AS -> non-flat AS");
13177 return I->getPointerOperand();
13178 }
13179 if (auto *C = dyn_cast<ConstantExpr>(V))
13180 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13181 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13182 FlatAS &&
13183 "there should not be flat AS -> non-flat AS X");
13184 return C->getOperand(0);
13185 }
13186 return V;
13187 }
13188};
13189
13190struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13191 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13192 : AAAddressSpaceImpl(IRP, A) {}
13193
13194 void trackStatistics() const override {
13196 }
13197};
13198
13199struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13200 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13201 : AAAddressSpaceImpl(IRP, A) {}
13202
13203 /// See AbstractAttribute::initialize(...).
13204 void initialize(Attributor &A) override {
13205 // TODO: we don't rewrite function argument for now because it will need to
13206 // rewrite the function signature and all call sites.
13207 (void)indicatePessimisticFixpoint();
13208 }
13209
13210 void trackStatistics() const override {
13211 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13212 }
13213};
13214
13215struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13216 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13217 : AAAddressSpaceImpl(IRP, A) {}
13218
13219 void trackStatistics() const override {
13220 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13221 }
13222};
13223
13224struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13225 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13226 : AAAddressSpaceImpl(IRP, A) {}
13227
13228 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13229};
13230
13231struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13232 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13233 : AAAddressSpaceImpl(IRP, A) {}
13234
13235 /// See AbstractAttribute::initialize(...).
13236 void initialize(Attributor &A) override {
13237 // TODO: we don't rewrite call site argument for now because it will need to
13238 // rewrite the function signature of the callee.
13239 (void)indicatePessimisticFixpoint();
13240 }
13241
13242 void trackStatistics() const override {
13243 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13244 }
13245};
13246} // namespace
13247
13248/// ------------------------ No Alias Address Space ---------------------------
13249// This attribute assumes flat address space can alias all other address space
13250
13251// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13252// But merging it created failing cased on gateway test that cannot be
13253// reproduced locally. So should open a separated PR to handle the merge of
13254// AANoAliasAddrSpace and AAAddressSpace attribute
13255
13256namespace {
13257struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13258 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13259 : AANoAliasAddrSpace(IRP, A) {}
13260
13261 void initialize(Attributor &A) override {
13262 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13263 "Associated value is not a pointer");
13264
13265 resetASRanges(A);
13266
13267 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13268 if (!FlatAS.has_value()) {
13269 indicatePessimisticFixpoint();
13270 return;
13271 }
13272
13273 removeAS(*FlatAS);
13274
13275 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13276 if (AS != *FlatAS) {
13277 removeAS(AS);
13278 indicateOptimisticFixpoint();
13279 }
13280 }
13281
13282 ChangeStatus updateImpl(Attributor &A) override {
13283 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13284 uint32_t OldAssumed = getAssumed();
13285
13286 auto CheckAddressSpace = [&](Value &Obj) {
13287 if (isa<PoisonValue>(&Obj))
13288 return true;
13289
13290 unsigned AS = Obj.getType()->getPointerAddressSpace();
13291 if (AS == FlatAS)
13292 return false;
13293
13294 removeAS(Obj.getType()->getPointerAddressSpace());
13295 return true;
13296 };
13297
13298 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13299 getIRPosition(), this, DepClassTy::REQUIRED);
13300 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13301 return indicatePessimisticFixpoint();
13302
13303 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13304 : ChangeStatus::CHANGED;
13305 }
13306
13307 /// See AbstractAttribute::manifest(...).
13308 ChangeStatus manifest(Attributor &A) override {
13309 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13310
13311 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13312 if (AS != FlatAS || Map.empty())
13313 return ChangeStatus::UNCHANGED;
13314
13315 LLVMContext &Ctx = getAssociatedValue().getContext();
13316 MDNode *NoAliasASNode = nullptr;
13317 MDBuilder MDB(Ctx);
13318 // Has to use iterator to get the range info.
13319 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13320 if (!I.value())
13321 continue;
13322 unsigned Upper = I.stop();
13323 unsigned Lower = I.start();
13324 if (!NoAliasASNode) {
13325 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13326 continue;
13327 }
13328 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13329 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13330 }
13331
13332 Value *AssociatedValue = &getAssociatedValue();
13333 bool Changed = false;
13334
13335 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13336 if (U.get() != AssociatedValue)
13337 return true;
13338 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13339 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13340 return true;
13341 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13343 return true;
13344 if (!A.isRunOn(Inst->getFunction()))
13345 return true;
13346 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13347 Changed = true;
13348 return true;
13349 };
13350 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13351 /*CheckBBLivenessOnly=*/true);
13352 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13353 }
13354
13355 /// See AbstractAttribute::getAsStr().
13356 const std::string getAsStr(Attributor *A) const override {
13357 if (!isValidState())
13358 return "<invalid>";
13359 std::string Str;
13360 raw_string_ostream OS(Str);
13361 OS << "CanNotBeAddrSpace(";
13362 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13363 unsigned Upper = I.stop();
13364 unsigned Lower = I.start();
13365 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13366 }
13367 OS << " )";
13368 return OS.str();
13369 }
13370
13371private:
13372 void removeAS(unsigned AS) {
13373 RangeMap::iterator I = Map.find(AS);
13374
13375 if (I != Map.end()) {
13376 unsigned Upper = I.stop();
13377 unsigned Lower = I.start();
13378 I.erase();
13379 if (Upper == Lower)
13380 return;
13381 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13382 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13383 if (AS != 0 && Lower <= AS - 1)
13384 Map.insert(Lower, AS - 1, true);
13385 }
13386 }
13387
13388 void resetASRanges(Attributor &A) {
13389 Map.clear();
13390 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13391 }
13392};
13393
13394struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13395 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13396 : AANoAliasAddrSpaceImpl(IRP, A) {}
13397
13398 void trackStatistics() const override {
13399 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13400 }
13401};
13402
13403struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13404 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13405 : AANoAliasAddrSpaceImpl(IRP, A) {}
13406
13407 void trackStatistics() const override {
13408 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13409 }
13410};
13411
13412struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13413 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13414 : AANoAliasAddrSpaceImpl(IRP, A) {}
13415
13416 void trackStatistics() const override {
13417 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13418 }
13419};
13420
13421struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13422 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13423 : AANoAliasAddrSpaceImpl(IRP, A) {}
13424
13425 void trackStatistics() const override {
13426 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13427 }
13428};
13429
13430struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13431 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13432 : AANoAliasAddrSpaceImpl(IRP, A) {}
13433
13434 void trackStatistics() const override {
13435 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13436 }
13437};
13438} // namespace
13439/// ----------- Allocation Info ----------
13440namespace {
13441struct AAAllocationInfoImpl : public AAAllocationInfo {
13442 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13443 : AAAllocationInfo(IRP, A) {}
13444
13445 std::optional<TypeSize> getAllocatedSize() const override {
13446 assert(isValidState() && "the AA is invalid");
13447 return AssumedAllocatedSize;
13448 }
13449
13450 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13451 const DataLayout &DL) {
13452
13453 // TODO: implement case for malloc like instructions
13454 switch (I->getOpcode()) {
13455 case Instruction::Alloca: {
13456 AllocaInst *AI = cast<AllocaInst>(I);
13457 return AI->getAllocationSize(DL);
13458 }
13459 default:
13460 return std::nullopt;
13461 }
13462 }
13463
13464 ChangeStatus updateImpl(Attributor &A) override {
13465
13466 const IRPosition &IRP = getIRPosition();
13467 Instruction *I = IRP.getCtxI();
13468
13469 // TODO: update check for malloc like calls
13470 if (!isa<AllocaInst>(I))
13471 return indicatePessimisticFixpoint();
13472
13473 bool IsKnownNoCapture;
13475 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13476 return indicatePessimisticFixpoint();
13477
13478 const AAPointerInfo *PI =
13479 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13480
13481 if (!PI)
13482 return indicatePessimisticFixpoint();
13483
13484 if (!PI->getState().isValidState() || PI->reachesReturn())
13485 return indicatePessimisticFixpoint();
13486
13487 const DataLayout &DL = A.getDataLayout();
13488 const auto AllocationSize = findInitialAllocationSize(I, DL);
13489
13490 // If allocation size is nullopt, we give up.
13491 if (!AllocationSize)
13492 return indicatePessimisticFixpoint();
13493
13494 // For zero sized allocations, we give up.
13495 // Since we can't reduce further
13496 if (*AllocationSize == 0)
13497 return indicatePessimisticFixpoint();
13498
13499 int64_t BinSize = PI->numOffsetBins();
13500
13501 // TODO: implement for multiple bins
13502 if (BinSize > 1)
13503 return indicatePessimisticFixpoint();
13504
13505 if (BinSize == 0) {
13506 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13507 if (!changeAllocationSize(NewAllocationSize))
13508 return ChangeStatus::UNCHANGED;
13509 return ChangeStatus::CHANGED;
13510 }
13511
13512 // TODO: refactor this to be part of multiple bin case
13513 const auto &It = PI->begin();
13514
13515 // TODO: handle if Offset is not zero
13516 if (It->first.Offset != 0)
13517 return indicatePessimisticFixpoint();
13518
13519 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13520
13521 if (SizeOfBin >= *AllocationSize)
13522 return indicatePessimisticFixpoint();
13523
13524 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13525
13526 if (!changeAllocationSize(NewAllocationSize))
13527 return ChangeStatus::UNCHANGED;
13528
13529 return ChangeStatus::CHANGED;
13530 }
13531
13532 /// See AbstractAttribute::manifest(...).
13533 ChangeStatus manifest(Attributor &A) override {
13534
13535 assert(isValidState() &&
13536 "Manifest should only be called if the state is valid.");
13537
13538 Instruction *I = getIRPosition().getCtxI();
13539
13540 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13541
13542 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13543
13544 switch (I->getOpcode()) {
13545 // TODO: add case for malloc like calls
13546 case Instruction::Alloca: {
13547
13548 AllocaInst *AI = cast<AllocaInst>(I);
13549
13550 Type *CharType = Type::getInt8Ty(I->getContext());
13551
13552 auto *NumBytesToValue =
13553 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13554
13555 BasicBlock::iterator insertPt = AI->getIterator();
13556 insertPt = std::next(insertPt);
13557 AllocaInst *NewAllocaInst =
13558 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13559 AI->getAlign(), AI->getName(), insertPt);
13560
13561 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13562 return ChangeStatus::CHANGED;
13563
13564 break;
13565 }
13566 default:
13567 break;
13568 }
13569
13570 return ChangeStatus::UNCHANGED;
13571 }
13572
13573 /// See AbstractAttribute::getAsStr().
13574 const std::string getAsStr(Attributor *A) const override {
13575 if (!isValidState())
13576 return "allocationinfo(<invalid>)";
13577 return "allocationinfo(" +
13578 (AssumedAllocatedSize == HasNoAllocationSize
13579 ? "none"
13580 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13581 ")";
13582 }
13583
13584private:
13585 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13586
13587 // Maintain the computed allocation size of the object.
13588 // Returns (bool) weather the size of the allocation was modified or not.
13589 bool changeAllocationSize(std::optional<TypeSize> Size) {
13590 if (AssumedAllocatedSize == HasNoAllocationSize ||
13591 AssumedAllocatedSize != Size) {
13592 AssumedAllocatedSize = Size;
13593 return true;
13594 }
13595 return false;
13596 }
13597};
13598
13599struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13600 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13601 : AAAllocationInfoImpl(IRP, A) {}
13602
13603 void trackStatistics() const override {
13604 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13605 }
13606};
13607
13608struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13609 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13610 : AAAllocationInfoImpl(IRP, A) {}
13611
13612 /// See AbstractAttribute::initialize(...).
13613 void initialize(Attributor &A) override {
13614 // TODO: we don't rewrite function argument for now because it will need to
13615 // rewrite the function signature and all call sites
13616 (void)indicatePessimisticFixpoint();
13617 }
13618
13619 void trackStatistics() const override {
13620 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13621 }
13622};
13623
13624struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13625 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13626 : AAAllocationInfoImpl(IRP, A) {}
13627
13628 void trackStatistics() const override {
13629 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13630 }
13631};
13632
13633struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13634 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13635 : AAAllocationInfoImpl(IRP, A) {}
13636
13637 void trackStatistics() const override {
13638 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13639 }
13640};
13641
13642struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13643 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13644 : AAAllocationInfoImpl(IRP, A) {}
13645
13646 /// See AbstractAttribute::initialize(...).
13647 void initialize(Attributor &A) override {
13648
13649 (void)indicatePessimisticFixpoint();
13650 }
13651
13652 void trackStatistics() const override {
13653 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13654 }
13655};
13656} // namespace
13657
13658const char AANoUnwind::ID = 0;
13659const char AANoSync::ID = 0;
13660const char AANoFree::ID = 0;
13661const char AANonNull::ID = 0;
13662const char AAMustProgress::ID = 0;
13663const char AANoRecurse::ID = 0;
13664const char AANonConvergent::ID = 0;
13665const char AAWillReturn::ID = 0;
13666const char AAUndefinedBehavior::ID = 0;
13667const char AANoAlias::ID = 0;
13668const char AAIntraFnReachability::ID = 0;
13669const char AANoReturn::ID = 0;
13670const char AAIsDead::ID = 0;
13671const char AADereferenceable::ID = 0;
13672const char AAAlign::ID = 0;
13673const char AAInstanceInfo::ID = 0;
13674const char AANoCapture::ID = 0;
13675const char AAValueSimplify::ID = 0;
13676const char AAHeapToStack::ID = 0;
13677const char AAPrivatizablePtr::ID = 0;
13678const char AAMemoryBehavior::ID = 0;
13679const char AAMemoryLocation::ID = 0;
13680const char AAValueConstantRange::ID = 0;
13681const char AAPotentialConstantValues::ID = 0;
13682const char AAPotentialValues::ID = 0;
13683const char AANoUndef::ID = 0;
13684const char AANoFPClass::ID = 0;
13685const char AACallEdges::ID = 0;
13686const char AAInterFnReachability::ID = 0;
13687const char AAPointerInfo::ID = 0;
13688const char AAAssumptionInfo::ID = 0;
13689const char AAUnderlyingObjects::ID = 0;
13690const char AAInvariantLoadPointer::ID = 0;
13691const char AAAddressSpace::ID = 0;
13692const char AANoAliasAddrSpace::ID = 0;
13693const char AAAllocationInfo::ID = 0;
13694const char AAIndirectCallInfo::ID = 0;
13695const char AAGlobalValueInfo::ID = 0;
13696const char AADenormalFPMath::ID = 0;
13697
13698// Macro magic to create the static generator function for attributes that
13699// follow the naming scheme.
13700
13701#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13702 case IRPosition::PK: \
13703 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13704
13705#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13706 case IRPosition::PK: \
13707 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13708 ++NumAAs; \
13709 break;
13710
13711#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13712 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13713 CLASS *AA = nullptr; \
13714 switch (IRP.getPositionKind()) { \
13715 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13716 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13717 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13718 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13719 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13720 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13721 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13722 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13723 } \
13724 return *AA; \
13725 }
13726
13727#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13728 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13729 CLASS *AA = nullptr; \
13730 switch (IRP.getPositionKind()) { \
13731 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13732 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13733 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13734 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13735 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13736 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13737 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13738 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13739 } \
13740 return *AA; \
13741 }
13742
13743#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13744 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13745 CLASS *AA = nullptr; \
13746 switch (IRP.getPositionKind()) { \
13747 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13748 default: \
13749 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13750 " position!"); \
13751 } \
13752 return *AA; \
13753 }
13754
13755#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13756 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13757 CLASS *AA = nullptr; \
13758 switch (IRP.getPositionKind()) { \
13759 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13760 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13761 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13762 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13763 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13764 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13765 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13766 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13767 } \
13768 return *AA; \
13769 }
13770
13771#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13772 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13773 CLASS *AA = nullptr; \
13774 switch (IRP.getPositionKind()) { \
13775 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13776 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13777 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13778 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13779 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13780 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13781 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13783 } \
13784 return *AA; \
13785 }
13786
13787#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13788 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13789 CLASS *AA = nullptr; \
13790 switch (IRP.getPositionKind()) { \
13791 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13792 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13793 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13794 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13795 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13796 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13797 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13798 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13799 } \
13800 return *AA; \
13801 }
13802
13812
13830
13835
13840
13847
13849
13850#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13851#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13852#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13853#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13854#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13855#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13856#undef SWITCH_PK_CREATE
13857#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:272
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:308
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:296
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:610
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:617
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:948
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:942
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:256
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
iterator end()
Definition DenseMap.h:81
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:159
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2084
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:534
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2847
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1572
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:77
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:743
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:779
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:284
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:287
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:808
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:807
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:335
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:194
@ Intraprocedural
Definition Attributor.h:195
@ Interprocedural
Definition Attributor.h:196
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:557
@ Length
Definition DWP.cpp:557
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1738
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1668
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:378
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:328
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1648
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1635
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:372
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:508
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:520
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:521
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:519
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:253
static constexpr int64_t Unknown
Definition Attributor.h:332
static RangeTy getUnknown()
Definition Attributor.h:259
Value * getValue() const
Definition Attributor.h:206
const Instruction * getCtxI() const
Definition Attributor.h:207
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:605
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:736
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:673
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:655
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:629
CallBase CallBaseContext
Definition Attributor.h:608
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:823
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:641
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:678
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:619
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:615
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:618
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:616
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:617
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:620
@ IRP_INVALID
An invalid position.
Definition Attributor.h:612
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:789
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:662
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:812
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:648
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:951
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:803
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:722
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:832
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:701
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:901
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:933
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:668
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:777
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.