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 BranchInst *Br = dyn_cast<BranchInst>(I))
670 if (Br->isConditional())
671 BrInsts.push_back(Br);
672 return true;
673 };
674
675 // Here, accumulate conditional branch instructions in the context. We
676 // explore the child paths and collect the known states. The disjunction of
677 // those states can be merged to its own state. Let ParentState_i be a state
678 // to indicate the known information for an i-th branch instruction in the
679 // context. ChildStates are created for its successors respectively.
680 //
681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
683 // ...
684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
685 //
686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
687 //
688 // FIXME: Currently, recursive branches are not handled. For example, we
689 // can't deduce that ptr must be dereferenced in below function.
690 //
691 // void f(int a, int c, int *ptr) {
692 // if(a)
693 // if (b) {
694 // *ptr = 0;
695 // } else {
696 // *ptr = 1;
697 // }
698 // else {
699 // if (b) {
700 // *ptr = 0;
701 // } else {
702 // *ptr = 1;
703 // }
704 // }
705 // }
706
707 Explorer->checkForAllContext(&CtxI, Pred);
708 for (const BranchInst *Br : BrInsts) {
709 StateType ParentState;
710
711 // The known state of the parent state is a conjunction of children's
712 // known states so it is initialized with a best state.
713 ParentState.indicateOptimisticFixpoint();
714
715 for (const BasicBlock *BB : Br->successors()) {
716 StateType ChildState;
717
718 size_t BeforeSize = Uses.size();
719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
720
721 // Erase uses which only appear in the child.
722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
723 It = Uses.erase(It);
724
725 ParentState &= ChildState;
726 }
727
728 // Use only known state.
729 S += ParentState;
730 }
731}
732} // namespace
733
734/// ------------------------ PointerInfo ---------------------------------------
735
736namespace llvm {
737namespace AA {
738namespace PointerInfo {
739
740struct State;
741
742} // namespace PointerInfo
743} // namespace AA
744
745/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
746template <>
749 static inline Access getEmptyKey();
750 static inline Access getTombstoneKey();
751 static unsigned getHashValue(const Access &A);
752 static bool isEqual(const Access &LHS, const Access &RHS);
753};
754
755/// Helper that allows RangeTy as a key in a DenseMap.
756template <> struct DenseMapInfo<AA::RangeTy> {
757 static inline AA::RangeTy getEmptyKey() {
758 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
759 return AA::RangeTy{EmptyKey, EmptyKey};
760 }
761
762 static inline AA::RangeTy getTombstoneKey() {
763 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
764 return AA::RangeTy{TombstoneKey, TombstoneKey};
765 }
766
772
773 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
774 return A == B;
775 }
776};
777
778/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
779/// but the instruction
780struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
783 static inline Access getEmptyKey();
784 static inline Access getTombstoneKey();
785 static unsigned getHashValue(const Access &A);
786 static bool isEqual(const Access &LHS, const Access &RHS);
787};
788
789} // namespace llvm
790
791/// A type to track pointer/struct usage and accesses for AAPointerInfo.
793 /// Return the best possible representable state.
794 static State getBestState(const State &SIS) { return State(); }
795
796 /// Return the worst possible representable state.
797 static State getWorstState(const State &SIS) {
798 State R;
799 R.indicatePessimisticFixpoint();
800 return R;
801 }
802
803 State() = default;
804 State(State &&SIS) = default;
805
806 const State &getAssumed() const { return *this; }
807
808 /// See AbstractState::isValidState().
809 bool isValidState() const override { return BS.isValidState(); }
810
811 /// See AbstractState::isAtFixpoint().
812 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
813
814 /// See AbstractState::indicateOptimisticFixpoint().
816 BS.indicateOptimisticFixpoint();
818 }
819
820 /// See AbstractState::indicatePessimisticFixpoint().
822 BS.indicatePessimisticFixpoint();
824 }
825
826 State &operator=(const State &R) {
827 if (this == &R)
828 return *this;
829 BS = R.BS;
830 AccessList = R.AccessList;
831 OffsetBins = R.OffsetBins;
832 RemoteIMap = R.RemoteIMap;
833 ReturnedOffsets = R.ReturnedOffsets;
834 return *this;
835 }
836
838 if (this == &R)
839 return *this;
840 std::swap(BS, R.BS);
841 std::swap(AccessList, R.AccessList);
842 std::swap(OffsetBins, R.OffsetBins);
843 std::swap(RemoteIMap, R.RemoteIMap);
844 std::swap(ReturnedOffsets, R.ReturnedOffsets);
845 return *this;
846 }
847
848 /// Add a new Access to the state at offset \p Offset and with size \p Size.
849 /// The access is associated with \p I, writes \p Content (if anything), and
850 /// is of kind \p Kind. If an Access already exists for the same \p I and same
851 /// \p RemoteI, the two are combined, potentially losing information about
852 /// offset and size. The resulting access must now be moved from its original
853 /// OffsetBin to the bin for its new offset.
854 ///
855 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
857 Instruction &I, std::optional<Value *> Content,
859 Instruction *RemoteI = nullptr);
860
863 int64_t numOffsetBins() const { return OffsetBins.size(); }
864
865 const AAPointerInfo::Access &getAccess(unsigned Index) const {
866 return AccessList[Index];
867 }
868
869protected:
870 // Every memory instruction results in an Access object. We maintain a list of
871 // all Access objects that we own, along with the following maps:
872 //
873 // - OffsetBins: RangeTy -> { Access }
874 // - RemoteIMap: RemoteI x LocalI -> Access
875 //
876 // A RemoteI is any instruction that accesses memory. RemoteI is different
877 // from LocalI if and only if LocalI is a call; then RemoteI is some
878 // instruction in the callgraph starting from LocalI. Multiple paths in the
879 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
880 // are all combined into a single Access object. This may result in loss of
881 // information in RangeTy in the Access object.
885
886 /// Flag to determine if the underlying pointer is reaching a return statement
887 /// in the associated function or not. Returns in other functions cause
888 /// invalidation.
890
891 /// See AAPointerInfo::forallInterferingAccesses.
892 template <typename F>
894 if (!isValidState() || !ReturnedOffsets.isUnassigned())
895 return false;
896
897 for (const auto &It : OffsetBins) {
898 AA::RangeTy ItRange = It.getFirst();
899 if (!Range.mayOverlap(ItRange))
900 continue;
901 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
902 for (auto Index : It.getSecond()) {
903 auto &Access = AccessList[Index];
904 if (!CB(Access, IsExact))
905 return false;
906 }
907 }
908 return true;
909 }
910
911 /// See AAPointerInfo::forallInterferingAccesses.
912 template <typename F>
914 AA::RangeTy &Range) const {
915 if (!isValidState() || !ReturnedOffsets.isUnassigned())
916 return false;
917
918 auto LocalList = RemoteIMap.find(&I);
919 if (LocalList == RemoteIMap.end()) {
920 return true;
921 }
922
923 for (unsigned Index : LocalList->getSecond()) {
924 for (auto &R : AccessList[Index]) {
925 Range &= R;
926 if (Range.offsetAndSizeAreUnknown())
927 break;
928 }
929 }
931 }
932
933private:
934 /// State to track fixpoint and validity.
935 BooleanState BS;
936};
937
940 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
941 Instruction *RemoteI) {
942 RemoteI = RemoteI ? RemoteI : &I;
943
944 // Check if we have an access for this instruction, if not, simply add it.
945 auto &LocalList = RemoteIMap[RemoteI];
946 bool AccExists = false;
947 unsigned AccIndex = AccessList.size();
948 for (auto Index : LocalList) {
949 auto &A = AccessList[Index];
950 if (A.getLocalInst() == &I) {
951 AccExists = true;
952 AccIndex = Index;
953 break;
954 }
955 }
956
957 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
958 LLVM_DEBUG(if (ToAdd.size()) dbgs()
959 << "[AAPointerInfo] Inserting access in new offset bins\n";);
960
961 for (auto Key : ToAdd) {
962 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
963 OffsetBins[Key].insert(AccIndex);
964 }
965 };
966
967 if (!AccExists) {
968 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
969 assert((AccessList.size() == AccIndex + 1) &&
970 "New Access should have been at AccIndex");
971 LocalList.push_back(AccIndex);
972 AddToBins(AccessList[AccIndex].getRanges());
974 }
975
976 // Combine the new Access with the existing Access, and then update the
977 // mapping in the offset bins.
978 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
979 auto &Current = AccessList[AccIndex];
980 auto Before = Current;
981 Current &= Acc;
982 if (Current == Before)
984
985 auto &ExistingRanges = Before.getRanges();
986 auto &NewRanges = Current.getRanges();
987
988 // Ranges that are in the old access but not the new access need to be removed
989 // from the offset bins.
991 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
992 LLVM_DEBUG(if (ToRemove.size()) dbgs()
993 << "[AAPointerInfo] Removing access from old offset bins\n";);
994
995 for (auto Key : ToRemove) {
996 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
997 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
998 auto &Bin = OffsetBins[Key];
999 assert(Bin.count(AccIndex) &&
1000 "Expected bin to actually contain the Access.");
1001 Bin.erase(AccIndex);
1002 }
1003
1004 // Ranges that are in the new access but not the old access need to be added
1005 // to the offset bins.
1007 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1008 AddToBins(ToAdd);
1009 return ChangeStatus::CHANGED;
1010}
1011
1012namespace {
1013
1014#ifndef NDEBUG
1016 const AAPointerInfo::OffsetInfo &OI) {
1017 OS << llvm::interleaved_array(OI);
1018 return OS;
1019}
1020#endif // NDEBUG
1021
1022struct AAPointerInfoImpl
1023 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1025 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1026
1027 /// See AbstractAttribute::getAsStr().
1028 const std::string getAsStr(Attributor *A) const override {
1029 return std::string("PointerInfo ") +
1030 (isValidState() ? (std::string("#") +
1031 std::to_string(OffsetBins.size()) + " bins")
1032 : "<invalid>") +
1033 (reachesReturn()
1034 ? (" (returned:" +
1035 join(map_range(ReturnedOffsets,
1036 [](int64_t O) { return std::to_string(O); }),
1037 ", ") +
1038 ")")
1039 : "");
1040 }
1041
1042 /// See AbstractAttribute::manifest(...).
1043 ChangeStatus manifest(Attributor &A) override {
1044 return AAPointerInfo::manifest(A);
1045 }
1046
1047 const_bin_iterator begin() const override { return State::begin(); }
1048 const_bin_iterator end() const override { return State::end(); }
1049 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1050 bool reachesReturn() const override {
1051 return !ReturnedOffsets.isUnassigned();
1052 }
1053 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1054 if (ReturnedOffsets.isUnknown()) {
1055 OI.setUnknown();
1056 return;
1057 }
1058
1059 OffsetInfo MergedOI;
1060 for (auto Offset : ReturnedOffsets) {
1061 OffsetInfo TmpOI = OI;
1062 TmpOI.addToAll(Offset);
1063 MergedOI.merge(TmpOI);
1064 }
1065 OI = std::move(MergedOI);
1066 }
1067
1068 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1069 if (ReturnedOffsets.isUnknown())
1070 return ChangeStatus::UNCHANGED;
1071 if (ReachedReturnedOffsets.isUnknown()) {
1072 ReturnedOffsets.setUnknown();
1073 return ChangeStatus::CHANGED;
1074 }
1075 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1076 return ChangeStatus::CHANGED;
1077 return ChangeStatus::UNCHANGED;
1078 }
1079
1080 bool forallInterferingAccesses(
1081 AA::RangeTy Range,
1082 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1083 const override {
1084 return State::forallInterferingAccesses(Range, CB);
1085 }
1086
1087 bool forallInterferingAccesses(
1088 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1089 bool FindInterferingWrites, bool FindInterferingReads,
1090 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1091 AA::RangeTy &Range,
1092 function_ref<bool(const Access &)> SkipCB) const override {
1093 HasBeenWrittenTo = false;
1094
1095 SmallPtrSet<const Access *, 8> DominatingWrites;
1096 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1097
1098 Function &Scope = *I.getFunction();
1099 bool IsKnownNoSync;
1100 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1101 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1102 IsKnownNoSync);
1103 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1104 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1105 bool AllInSameNoSyncFn = IsAssumedNoSync;
1106 bool InstIsExecutedByInitialThreadOnly =
1107 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1108
1109 // If the function is not ending in aligned barriers, we need the stores to
1110 // be in aligned barriers. The load being in one is not sufficient since the
1111 // store might be executed by a thread that disappears after, causing the
1112 // aligned barrier guarding the load to unblock and the load to read a value
1113 // that has no CFG path to the load.
1114 bool InstIsExecutedInAlignedRegion =
1115 FindInterferingReads && ExecDomainAA &&
1116 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1117
1118 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1119 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1120
1121 InformationCache &InfoCache = A.getInfoCache();
1122 bool IsThreadLocalObj =
1123 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1124
1125 // Helper to determine if we need to consider threading, which we cannot
1126 // right now. However, if the function is (assumed) nosync or the thread
1127 // executing all instructions is the main thread only we can ignore
1128 // threading. Also, thread-local objects do not require threading reasoning.
1129 // Finally, we can ignore threading if either access is executed in an
1130 // aligned region.
1131 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1132 if (IsThreadLocalObj || AllInSameNoSyncFn)
1133 return true;
1134 const auto *FnExecDomainAA =
1135 I.getFunction() == &Scope
1136 ? ExecDomainAA
1137 : A.lookupAAFor<AAExecutionDomain>(
1138 IRPosition::function(*I.getFunction()), &QueryingAA,
1139 DepClassTy::NONE);
1140 if (!FnExecDomainAA)
1141 return false;
1142 if (InstIsExecutedInAlignedRegion ||
1143 (FindInterferingWrites &&
1144 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1145 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1146 return true;
1147 }
1148 if (InstIsExecutedByInitialThreadOnly &&
1149 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1150 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1151 return true;
1152 }
1153 return false;
1154 };
1155
1156 // Helper to determine if the access is executed by the same thread as the
1157 // given instruction, for now it is sufficient to avoid any potential
1158 // threading effects as we cannot deal with them anyway.
1159 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1160 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1161 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1162 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1163 };
1164
1165 // TODO: Use inter-procedural reachability and dominance.
1166 bool IsKnownNoRecurse;
1168 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1169 IsKnownNoRecurse);
1170
1171 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1172 // AAExecutionDomain) such that we allow scopes other than kernels as long
1173 // as the reaching kernels are disjoint.
1174 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1175 bool ObjHasKernelLifetime = false;
1176 const bool UseDominanceReasoning =
1177 FindInterferingWrites && IsKnownNoRecurse;
1178 const DominatorTree *DT =
1179 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1180
1181 // Helper to check if a value has "kernel lifetime", that is it will not
1182 // outlive a GPU kernel. This is true for shared, constant, and local
1183 // globals on AMD and NVIDIA GPUs.
1184 auto HasKernelLifetime = [&](Value *V, Module &M) {
1185 if (!AA::isGPU(M))
1186 return false;
1187 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1188 case AA::GPUAddressSpace::Shared:
1189 case AA::GPUAddressSpace::Constant:
1190 case AA::GPUAddressSpace::Local:
1191 return true;
1192 default:
1193 return false;
1194 };
1195 };
1196
1197 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1198 // to determine if we should look at reachability from the callee. For
1199 // certain pointers we know the lifetime and we do not have to step into the
1200 // callee to determine reachability as the pointer would be dead in the
1201 // callee. See the conditional initialization below.
1202 std::function<bool(const Function &)> IsLiveInCalleeCB;
1203
1204 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1205 // If the alloca containing function is not recursive the alloca
1206 // must be dead in the callee.
1207 const Function *AIFn = AI->getFunction();
1208 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1209 bool IsKnownNoRecurse;
1211 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1212 IsKnownNoRecurse)) {
1213 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1214 }
1215 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1216 // If the global has kernel lifetime we can stop if we reach a kernel
1217 // as it is "dead" in the (unknown) callees.
1218 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1219 if (ObjHasKernelLifetime)
1220 IsLiveInCalleeCB = [&A](const Function &Fn) {
1221 return !A.getInfoCache().isKernel(Fn);
1222 };
1223 }
1224
1225 // Set of accesses/instructions that will overwrite the result and are
1226 // therefore blockers in the reachability traversal.
1227 AA::InstExclusionSetTy ExclusionSet;
1228
1229 auto AccessCB = [&](const Access &Acc, bool Exact) {
1230 Function *AccScope = Acc.getRemoteInst()->getFunction();
1231 bool AccInSameScope = AccScope == &Scope;
1232
1233 // If the object has kernel lifetime we can ignore accesses only reachable
1234 // by other kernels. For now we only skip accesses *in* other kernels.
1235 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1236 A.getInfoCache().isKernel(*AccScope))
1237 return true;
1238
1239 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1240 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1241 ExclusionSet.insert(Acc.getRemoteInst());
1242 }
1243
1244 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1245 (!FindInterferingReads || !Acc.isRead()))
1246 return true;
1247
1248 bool Dominates = FindInterferingWrites && DT && Exact &&
1249 Acc.isMustAccess() && AccInSameScope &&
1250 DT->dominates(Acc.getRemoteInst(), &I);
1251 if (Dominates)
1252 DominatingWrites.insert(&Acc);
1253
1254 // Track if all interesting accesses are in the same `nosync` function as
1255 // the given instruction.
1256 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1257
1258 InterferingAccesses.push_back({&Acc, Exact});
1259 return true;
1260 };
1261 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1262 return false;
1263
1264 HasBeenWrittenTo = !DominatingWrites.empty();
1265
1266 // Dominating writes form a chain, find the least/lowest member.
1267 Instruction *LeastDominatingWriteInst = nullptr;
1268 for (const Access *Acc : DominatingWrites) {
1269 if (!LeastDominatingWriteInst) {
1270 LeastDominatingWriteInst = Acc->getRemoteInst();
1271 } else if (DT->dominates(LeastDominatingWriteInst,
1272 Acc->getRemoteInst())) {
1273 LeastDominatingWriteInst = Acc->getRemoteInst();
1274 }
1275 }
1276
1277 // Helper to determine if we can skip a specific write access.
1278 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1279 if (SkipCB && SkipCB(Acc))
1280 return true;
1281 if (!CanIgnoreThreading(Acc))
1282 return false;
1283
1284 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1285 // If we successfully excluded all effects we are interested in, the
1286 // access can be skipped.
1287 bool ReadChecked = !FindInterferingReads;
1288 bool WriteChecked = !FindInterferingWrites;
1289
1290 // If the instruction cannot reach the access, the former does not
1291 // interfere with what the access reads.
1292 if (!ReadChecked) {
1293 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1294 &ExclusionSet, IsLiveInCalleeCB))
1295 ReadChecked = true;
1296 }
1297 // If the instruction cannot be reach from the access, the latter does not
1298 // interfere with what the instruction reads.
1299 if (!WriteChecked) {
1300 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1301 &ExclusionSet, IsLiveInCalleeCB))
1302 WriteChecked = true;
1303 }
1304
1305 // If we still might be affected by the write of the access but there are
1306 // dominating writes in the function of the instruction
1307 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1308 // by them. This would have happend above if they are all in the same
1309 // function, so we only check the inter-procedural case. Effectively, we
1310 // want to show that there is no call after the dominting write that might
1311 // reach the access, and when it returns reach the instruction with the
1312 // updated value. To this end, we iterate all call sites, check if they
1313 // might reach the instruction without going through another access
1314 // (ExclusionSet) and at the same time might reach the access. However,
1315 // that is all part of AAInterFnReachability.
1316 if (!WriteChecked && HasBeenWrittenTo &&
1317 Acc.getRemoteInst()->getFunction() != &Scope) {
1318
1319 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1320 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1321 if (FnReachabilityAA) {
1322 // Without going backwards in the call tree, can we reach the access
1323 // from the least dominating write. Do not allow to pass the
1324 // instruction itself either.
1325 bool Inserted = ExclusionSet.insert(&I).second;
1326
1327 if (!FnReachabilityAA->instructionCanReach(
1328 A, *LeastDominatingWriteInst,
1329 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1330 WriteChecked = true;
1331
1332 if (Inserted)
1333 ExclusionSet.erase(&I);
1334 }
1335 }
1336
1337 if (ReadChecked && WriteChecked)
1338 return true;
1339
1340 if (!DT || !UseDominanceReasoning)
1341 return false;
1342 if (!DominatingWrites.count(&Acc))
1343 return false;
1344 return LeastDominatingWriteInst != Acc.getRemoteInst();
1345 };
1346
1347 // Run the user callback on all accesses we cannot skip and return if
1348 // that succeeded for all or not.
1349 for (auto &It : InterferingAccesses) {
1350 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1351 !CanSkipAccess(*It.first, It.second)) {
1352 if (!UserCB(*It.first, It.second))
1353 return false;
1354 }
1355 }
1356 return true;
1357 }
1358
1359 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1360 const AAPointerInfo &OtherAA,
1361 CallBase &CB) {
1362 using namespace AA::PointerInfo;
1363 if (!OtherAA.getState().isValidState() || !isValidState())
1364 return indicatePessimisticFixpoint();
1365
1366 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1367 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1368 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1369 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1370
1371 // Combine the accesses bin by bin.
1372 const auto &State = OtherAAImpl.getState();
1373 for (const auto &It : State) {
1374 for (auto Index : It.getSecond()) {
1375 const auto &RAcc = State.getAccess(Index);
1376 if (IsByval && !RAcc.isRead())
1377 continue;
1378 bool UsedAssumedInformation = false;
1379 AccessKind AK = RAcc.getKind();
1380 auto Content = A.translateArgumentToCallSiteContent(
1381 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1382 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1383 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1384
1385 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1386 RAcc.getType(), RAcc.getRemoteInst());
1387 }
1388 }
1389 return Changed;
1390 }
1391
1392 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1393 const OffsetInfo &Offsets, CallBase &CB,
1394 bool IsMustAcc) {
1395 using namespace AA::PointerInfo;
1396 if (!OtherAA.getState().isValidState() || !isValidState())
1397 return indicatePessimisticFixpoint();
1398
1399 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1400
1401 // Combine the accesses bin by bin.
1402 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1403 const auto &State = OtherAAImpl.getState();
1404 for (const auto &It : State) {
1405 for (auto Index : It.getSecond()) {
1406 const auto &RAcc = State.getAccess(Index);
1407 if (!IsMustAcc && RAcc.isAssumption())
1408 continue;
1409 for (auto Offset : Offsets) {
1410 auto NewRanges = Offset == AA::RangeTy::Unknown
1412 : RAcc.getRanges();
1413 if (!NewRanges.isUnknown()) {
1414 NewRanges.addToAllOffsets(Offset);
1415 }
1416 AccessKind AK = RAcc.getKind();
1417 if (!IsMustAcc)
1418 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1419 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1420 RAcc.getType(), RAcc.getRemoteInst());
1421 }
1422 }
1423 }
1424 return Changed;
1425 }
1426
1427 /// Statistic tracking for all AAPointerInfo implementations.
1428 /// See AbstractAttribute::trackStatistics().
1429 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1430
1431 /// Dump the state into \p O.
1432 void dumpState(raw_ostream &O) {
1433 for (auto &It : OffsetBins) {
1434 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1435 << "] : " << It.getSecond().size() << "\n";
1436 for (auto AccIndex : It.getSecond()) {
1437 auto &Acc = AccessList[AccIndex];
1438 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1439 if (Acc.getLocalInst() != Acc.getRemoteInst())
1440 O << " --> " << *Acc.getRemoteInst()
1441 << "\n";
1442 if (!Acc.isWrittenValueYetUndetermined()) {
1443 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1444 O << " - c: func " << Acc.getWrittenValue()->getName()
1445 << "\n";
1446 else if (Acc.getWrittenValue())
1447 O << " - c: " << *Acc.getWrittenValue() << "\n";
1448 else
1449 O << " - c: <unknown>\n";
1450 }
1451 }
1452 }
1453 }
1454};
1455
1456struct AAPointerInfoFloating : public AAPointerInfoImpl {
1458 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1459 : AAPointerInfoImpl(IRP, A) {}
1460
1461 /// Deal with an access and signal if it was handled successfully.
1462 bool handleAccess(Attributor &A, Instruction &I,
1463 std::optional<Value *> Content, AccessKind Kind,
1464 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1465 Type &Ty) {
1466 using namespace AA::PointerInfo;
1468 const DataLayout &DL = A.getDataLayout();
1469 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1470 if (!AccessSize.isScalable())
1471 Size = AccessSize.getFixedValue();
1472
1473 // Make a strictly ascending list of offsets as required by addAccess()
1474 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1475 llvm::sort(OffsetsSorted);
1476
1478 if (!VT || VT->getElementCount().isScalable() ||
1479 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1480 (*Content)->getType() != VT ||
1481 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1482 Changed =
1483 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1484 } else {
1485 // Handle vector stores with constant content element-wise.
1486 // TODO: We could look for the elements or create instructions
1487 // representing them.
1488 // TODO: We need to push the Content into the range abstraction
1489 // (AA::RangeTy) to allow different content values for different
1490 // ranges. ranges. Hence, support vectors storing different values.
1491 Type *ElementType = VT->getElementType();
1492 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1493 auto *ConstContent = cast<Constant>(*Content);
1494 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1495 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1496
1497 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1498 Value *ElementContent = ConstantExpr::getExtractElement(
1499 ConstContent, ConstantInt::get(Int32Ty, i));
1500
1501 // Add the element access.
1502 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1503 ElementContent, Kind, ElementType);
1504
1505 // Advance the offsets for the next element.
1506 for (auto &ElementOffset : ElementOffsets)
1507 ElementOffset += ElementSize;
1508 }
1509 }
1510 return true;
1511 };
1512
1513 /// See AbstractAttribute::updateImpl(...).
1514 ChangeStatus updateImpl(Attributor &A) override;
1515
1516 /// If the indices to \p GEP can be traced to constants, incorporate all
1517 /// of these into \p UsrOI.
1518 ///
1519 /// \return true iff \p UsrOI is updated.
1520 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1521 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1522 const GEPOperator *GEP);
1523
1524 /// See AbstractAttribute::trackStatistics()
1525 void trackStatistics() const override {
1526 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1527 }
1528};
1529
1530bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1531 const DataLayout &DL,
1532 OffsetInfo &UsrOI,
1533 const OffsetInfo &PtrOI,
1534 const GEPOperator *GEP) {
1535 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1536 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1537 APInt ConstantOffset(BitWidth, 0);
1538
1539 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1540 "Don't look for constant values if the offset has already been "
1541 "determined to be unknown.");
1542
1543 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1544 UsrOI.setUnknown();
1545 return true;
1546 }
1547
1548 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1549 << (VariableOffsets.empty() ? "" : "not") << " constant "
1550 << *GEP << "\n");
1551
1552 auto Union = PtrOI;
1553 Union.addToAll(ConstantOffset.getSExtValue());
1554
1555 // Each VI in VariableOffsets has a set of potential constant values. Every
1556 // combination of elements, picked one each from these sets, is separately
1557 // added to the original set of offsets, thus resulting in more offsets.
1558 for (const auto &VI : VariableOffsets) {
1559 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1560 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1561 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1562 UsrOI.setUnknown();
1563 return true;
1564 }
1565
1566 // UndefValue is treated as a zero, which leaves Union as is.
1567 if (PotentialConstantsAA->undefIsContained())
1568 continue;
1569
1570 // We need at least one constant in every set to compute an actual offset.
1571 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1572 // don't actually exist. In other words, the absence of constant values
1573 // implies that the operation can be assumed dead for now.
1574 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1575 if (AssumedSet.empty())
1576 return false;
1577
1578 OffsetInfo Product;
1579 for (const auto &ConstOffset : AssumedSet) {
1580 auto CopyPerOffset = Union;
1581 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1582 VI.second.getZExtValue());
1583 Product.merge(CopyPerOffset);
1584 }
1585 Union = Product;
1586 }
1587
1588 UsrOI = std::move(Union);
1589 return true;
1590}
1591
1592ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1593 using namespace AA::PointerInfo;
1595 const DataLayout &DL = A.getDataLayout();
1596 Value &AssociatedValue = getAssociatedValue();
1597
1598 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1599 OffsetInfoMap[&AssociatedValue].insert(0);
1600
1601 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1602 // One does not simply walk into a map and assign a reference to a possibly
1603 // new location. That can cause an invalidation before the assignment
1604 // happens, like so:
1605 //
1606 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1607 //
1608 // The RHS is a reference that may be invalidated by an insertion caused by
1609 // the LHS. So we ensure that the side-effect of the LHS happens first.
1610
1611 assert(OffsetInfoMap.contains(CurPtr) &&
1612 "CurPtr does not exist in the map!");
1613
1614 auto &UsrOI = OffsetInfoMap[Usr];
1615 auto &PtrOI = OffsetInfoMap[CurPtr];
1616 assert(!PtrOI.isUnassigned() &&
1617 "Cannot pass through if the input Ptr was not visited!");
1618 UsrOI.merge(PtrOI);
1619 Follow = true;
1620 return true;
1621 };
1622
1623 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1624 Value *CurPtr = U.get();
1625 User *Usr = U.getUser();
1626 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1627 << "\n");
1628 assert(OffsetInfoMap.count(CurPtr) &&
1629 "The current pointer offset should have been seeded!");
1630 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1631 "Current pointer should be assigned");
1632
1633 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1634 if (CE->isCast())
1635 return HandlePassthroughUser(Usr, CurPtr, Follow);
1636 if (!isa<GEPOperator>(CE)) {
1637 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1638 << "\n");
1639 return false;
1640 }
1641 }
1642 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1643 // Note the order here, the Usr access might change the map, CurPtr is
1644 // already in it though.
1645 auto &UsrOI = OffsetInfoMap[Usr];
1646 auto &PtrOI = OffsetInfoMap[CurPtr];
1647
1648 if (UsrOI.isUnknown())
1649 return true;
1650
1651 if (PtrOI.isUnknown()) {
1652 Follow = true;
1653 UsrOI.setUnknown();
1654 return true;
1655 }
1656
1657 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1658 return true;
1659 }
1660 if (isa<PtrToIntInst>(Usr))
1661 return false;
1662 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1663 return HandlePassthroughUser(Usr, CurPtr, Follow);
1664 // Returns are allowed if they are in the associated functions. Users can
1665 // then check the call site return. Returns from other functions can't be
1666 // tracked and are cause for invalidation.
1667 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1668 if (RI->getFunction() == getAssociatedFunction()) {
1669 auto &PtrOI = OffsetInfoMap[CurPtr];
1670 Changed |= setReachesReturn(PtrOI);
1671 return true;
1672 }
1673 return false;
1674 }
1675
1676 // For PHIs we need to take care of the recurrence explicitly as the value
1677 // might change while we iterate through a loop. For now, we give up if
1678 // the PHI is not invariant.
1679 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1680 // Note the order here, the Usr access might change the map, CurPtr is
1681 // already in it though.
1682 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1683 auto &UsrOI = PhiIt->second;
1684 auto &PtrOI = OffsetInfoMap[CurPtr];
1685
1686 // Check if the PHI operand has already an unknown offset as we can't
1687 // improve on that anymore.
1688 if (PtrOI.isUnknown()) {
1689 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1690 << *CurPtr << " in " << *PHI << "\n");
1691 Follow = !UsrOI.isUnknown();
1692 UsrOI.setUnknown();
1693 return true;
1694 }
1695
1696 // Check if the PHI is invariant (so far).
1697 if (UsrOI == PtrOI) {
1698 assert(!PtrOI.isUnassigned() &&
1699 "Cannot assign if the current Ptr was not visited!");
1700 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1701 return true;
1702 }
1703
1704 // Check if the PHI operand can be traced back to AssociatedValue.
1705 APInt Offset(
1706 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1707 0);
1708 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1709 DL, Offset, /* AllowNonInbounds */ true);
1710 auto It = OffsetInfoMap.find(CurPtrBase);
1711 if (It == OffsetInfoMap.end()) {
1712 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1713 << *CurPtr << " in " << *PHI
1714 << " (base: " << *CurPtrBase << ")\n");
1715 UsrOI.setUnknown();
1716 Follow = true;
1717 return true;
1718 }
1719
1720 // Check if the PHI operand is not dependent on the PHI itself. Every
1721 // recurrence is a cyclic net of PHIs in the data flow, and has an
1722 // equivalent Cycle in the control flow. One of those PHIs must be in the
1723 // header of that control flow Cycle. This is independent of the choice of
1724 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1725 // every Cycle header; if such a node is marked unknown, this will
1726 // eventually propagate through the whole net of PHIs in the recurrence.
1727 const auto *CI =
1728 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1729 *PHI->getFunction());
1730 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1731 auto BaseOI = It->getSecond();
1732 BaseOI.addToAll(Offset.getZExtValue());
1733 if (IsFirstPHIUser || BaseOI == UsrOI) {
1734 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1735 << " in " << *Usr << "\n");
1736 return HandlePassthroughUser(Usr, CurPtr, Follow);
1737 }
1738
1739 LLVM_DEBUG(
1740 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1741 << *CurPtr << " in " << *PHI << "\n");
1742 UsrOI.setUnknown();
1743 Follow = true;
1744 return true;
1745 }
1746
1747 UsrOI.merge(PtrOI);
1748 Follow = true;
1749 return true;
1750 }
1751
1752 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1753 // If the access is to a pointer that may or may not be the associated
1754 // value, e.g. due to a PHI, we cannot assume it will be read.
1755 AccessKind AK = AccessKind::AK_R;
1756 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1757 AK = AccessKind(AK | AccessKind::AK_MUST);
1758 else
1759 AK = AccessKind(AK | AccessKind::AK_MAY);
1760 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1761 OffsetInfoMap[CurPtr].Offsets, Changed,
1762 *LoadI->getType()))
1763 return false;
1764
1765 auto IsAssumption = [](Instruction &I) {
1766 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1767 return II->isAssumeLikeIntrinsic();
1768 return false;
1769 };
1770
1771 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1772 // Check if the assumption and the load are executed together without
1773 // memory modification.
1774 do {
1775 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1776 return true;
1777 FromI = FromI->getNextNode();
1778 } while (FromI && FromI != ToI);
1779 return false;
1780 };
1781
1782 BasicBlock *BB = LoadI->getParent();
1783 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1784 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1785 return false;
1786 BasicBlock *IntrBB = IntrI.getParent();
1787 if (IntrI.getParent() == BB) {
1788 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1789 return false;
1790 } else {
1791 auto PredIt = pred_begin(IntrBB);
1792 if (PredIt == pred_end(IntrBB))
1793 return false;
1794 if ((*PredIt) != BB)
1795 return false;
1796 if (++PredIt != pred_end(IntrBB))
1797 return false;
1798 for (auto *SuccBB : successors(BB)) {
1799 if (SuccBB == IntrBB)
1800 continue;
1801 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1802 continue;
1803 return false;
1804 }
1805 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1806 return false;
1807 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1808 return false;
1809 }
1810 return true;
1811 };
1812
1813 std::pair<Value *, IntrinsicInst *> Assumption;
1814 for (const Use &LoadU : LoadI->uses()) {
1815 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1816 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1817 continue;
1818 for (const Use &CmpU : CmpI->uses()) {
1819 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1820 if (!IsValidAssume(*IntrI))
1821 continue;
1822 int Idx = CmpI->getOperandUse(0) == LoadU;
1823 Assumption = {CmpI->getOperand(Idx), IntrI};
1824 break;
1825 }
1826 }
1827 }
1828 if (Assumption.first)
1829 break;
1830 }
1831
1832 // Check if we found an assumption associated with this load.
1833 if (!Assumption.first || !Assumption.second)
1834 return true;
1835
1836 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1837 << *Assumption.second << ": " << *LoadI
1838 << " == " << *Assumption.first << "\n");
1839 bool UsedAssumedInformation = false;
1840 std::optional<Value *> Content = nullptr;
1841 if (Assumption.first)
1842 Content =
1843 A.getAssumedSimplified(*Assumption.first, *this,
1844 UsedAssumedInformation, AA::Interprocedural);
1845 return handleAccess(
1846 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1847 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1848 }
1849
1850 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1851 ArrayRef<Value *> OtherOps, AccessKind AK) {
1852 for (auto *OtherOp : OtherOps) {
1853 if (OtherOp == CurPtr) {
1854 LLVM_DEBUG(
1855 dbgs()
1856 << "[AAPointerInfo] Escaping use in store like instruction " << I
1857 << "\n");
1858 return false;
1859 }
1860 }
1861
1862 // If the access is to a pointer that may or may not be the associated
1863 // value, e.g. due to a PHI, we cannot assume it will be written.
1864 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1865 AK = AccessKind(AK | AccessKind::AK_MUST);
1866 else
1867 AK = AccessKind(AK | AccessKind::AK_MAY);
1868 bool UsedAssumedInformation = false;
1869 std::optional<Value *> Content = nullptr;
1870 if (ValueOp)
1871 Content = A.getAssumedSimplified(
1872 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1873 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1874 Changed, ValueTy);
1875 };
1876
1877 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1878 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1879 *StoreI->getValueOperand()->getType(),
1880 {StoreI->getValueOperand()}, AccessKind::AK_W);
1881 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1882 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1883 {RMWI->getValOperand()}, AccessKind::AK_RW);
1884 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1885 return HandleStoreLike(
1886 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1887 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1888 AccessKind::AK_RW);
1889
1890 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1891 if (CB->isLifetimeStartOrEnd())
1892 return true;
1893 const auto *TLI =
1894 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1895 if (getFreedOperand(CB, TLI) == U)
1896 return true;
1897 if (CB->isArgOperand(&U)) {
1898 unsigned ArgNo = CB->getArgOperandNo(&U);
1899 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1900 *this, IRPosition::callsite_argument(*CB, ArgNo),
1902 if (!CSArgPI)
1903 return false;
1904 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1905 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1906 IsArgMustAcc) |
1907 Changed;
1908 if (!CSArgPI->reachesReturn())
1909 return isValidState();
1910
1912 if (!Callee || Callee->arg_size() <= ArgNo)
1913 return false;
1914 bool UsedAssumedInformation = false;
1915 auto ReturnedValue = A.getAssumedSimplified(
1916 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1918 auto *ReturnedArg =
1919 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1920 auto *Arg = Callee->getArg(ArgNo);
1921 if (ReturnedArg && Arg != ReturnedArg)
1922 return true;
1923 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1924 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1926 if (!CSRetPI)
1927 return false;
1928 OffsetInfo OI = OffsetInfoMap[CurPtr];
1929 CSArgPI->addReturnedOffsetsTo(OI);
1930 Changed =
1931 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1932 return isValidState();
1933 }
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1935 << "\n");
1936 return false;
1937 }
1938
1939 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1940 return false;
1941 };
1942 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1943 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1944 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1945 if (OffsetInfoMap.count(NewU)) {
1946 LLVM_DEBUG({
1947 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1948 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1949 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1950 << "\n";
1951 }
1952 });
1953 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1954 }
1955 bool Unused;
1956 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1957 };
1958 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1959 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1960 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1961 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1962 return indicatePessimisticFixpoint();
1963 }
1964
1965 LLVM_DEBUG({
1966 dbgs() << "Accesses by bin after update:\n";
1967 dumpState(dbgs());
1968 });
1969
1970 return Changed;
1971}
1972
1973struct AAPointerInfoReturned final : AAPointerInfoImpl {
1974 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1975 : AAPointerInfoImpl(IRP, A) {}
1976
1977 /// See AbstractAttribute::updateImpl(...).
1978 ChangeStatus updateImpl(Attributor &A) override {
1979 return indicatePessimisticFixpoint();
1980 }
1981
1982 /// See AbstractAttribute::trackStatistics()
1983 void trackStatistics() const override {
1984 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1985 }
1986};
1987
1988struct AAPointerInfoArgument final : AAPointerInfoFloating {
1989 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1990 : AAPointerInfoFloating(IRP, A) {}
1991
1992 /// See AbstractAttribute::trackStatistics()
1993 void trackStatistics() const override {
1994 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1995 }
1996};
1997
1998struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1999 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
2000 : AAPointerInfoFloating(IRP, A) {}
2001
2002 /// See AbstractAttribute::updateImpl(...).
2003 ChangeStatus updateImpl(Attributor &A) override {
2004 using namespace AA::PointerInfo;
2005 // We handle memory intrinsics explicitly, at least the first (=
2006 // destination) and second (=source) arguments as we know how they are
2007 // accessed.
2008 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2009 int64_t LengthVal = AA::RangeTy::Unknown;
2010 if (auto Length = MI->getLengthInBytes())
2011 LengthVal = Length->getSExtValue();
2012 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2013 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2014 if (ArgNo > 1) {
2015 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2016 << *MI << "\n");
2017 return indicatePessimisticFixpoint();
2018 } else {
2019 auto Kind =
2020 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2021 Changed =
2022 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2023 }
2024 LLVM_DEBUG({
2025 dbgs() << "Accesses by bin after update:\n";
2026 dumpState(dbgs());
2027 });
2028
2029 return Changed;
2030 }
2031
2032 // TODO: Once we have call site specific value information we can provide
2033 // call site specific liveness information and then it makes
2034 // sense to specialize attributes for call sites arguments instead of
2035 // redirecting requests to the callee argument.
2036 Argument *Arg = getAssociatedArgument();
2037 if (Arg) {
2038 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2039 auto *ArgAA =
2040 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2041 if (ArgAA && ArgAA->getState().isValidState())
2042 return translateAndAddStateFromCallee(A, *ArgAA,
2043 *cast<CallBase>(getCtxI()));
2044 if (!Arg->getParent()->isDeclaration())
2045 return indicatePessimisticFixpoint();
2046 }
2047
2048 bool IsKnownNoCapture;
2050 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2051 return indicatePessimisticFixpoint();
2052
2053 bool IsKnown = false;
2054 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2055 return ChangeStatus::UNCHANGED;
2056 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2057 auto Kind =
2058 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2059 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2060 nullptr);
2061 }
2062
2063 /// See AbstractAttribute::trackStatistics()
2064 void trackStatistics() const override {
2065 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2066 }
2067};
2068
2069struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2070 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2071 : AAPointerInfoFloating(IRP, A) {}
2072
2073 /// See AbstractAttribute::trackStatistics()
2074 void trackStatistics() const override {
2075 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2076 }
2077};
2078} // namespace
2079
2080/// -----------------------NoUnwind Function Attribute--------------------------
2081
2082namespace {
2083struct AANoUnwindImpl : AANoUnwind {
2084 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2085
2086 /// See AbstractAttribute::initialize(...).
2087 void initialize(Attributor &A) override {
2088 bool IsKnown;
2090 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2091 (void)IsKnown;
2092 }
2093
2094 const std::string getAsStr(Attributor *A) const override {
2095 return getAssumed() ? "nounwind" : "may-unwind";
2096 }
2097
2098 /// See AbstractAttribute::updateImpl(...).
2099 ChangeStatus updateImpl(Attributor &A) override {
2100 auto Opcodes = {
2101 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2102 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2103 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2104
2105 auto CheckForNoUnwind = [&](Instruction &I) {
2106 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2107 return true;
2108
2109 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2110 bool IsKnownNoUnwind;
2112 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2113 IsKnownNoUnwind);
2114 }
2115 return false;
2116 };
2117
2118 bool UsedAssumedInformation = false;
2119 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2120 UsedAssumedInformation))
2121 return indicatePessimisticFixpoint();
2122
2123 return ChangeStatus::UNCHANGED;
2124 }
2125};
2126
2127struct AANoUnwindFunction final : public AANoUnwindImpl {
2128 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2129 : AANoUnwindImpl(IRP, A) {}
2130
2131 /// See AbstractAttribute::trackStatistics()
2132 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2133};
2134
2135/// NoUnwind attribute deduction for a call sites.
2136struct AANoUnwindCallSite final
2137 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2138 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2139 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2140
2141 /// See AbstractAttribute::trackStatistics()
2142 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2143};
2144} // namespace
2145
2146/// ------------------------ NoSync Function Attribute -------------------------
2147
2148bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2149 switch (CB.getIntrinsicID()) {
2150 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2151 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2152 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2153 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2154 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2155 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2156 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2157 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2158 return true;
2159 case Intrinsic::amdgcn_s_barrier:
2160 if (ExecutedAligned)
2161 return true;
2162 break;
2163 default:
2164 break;
2165 }
2166 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2167}
2168
2170 if (!I->isAtomic())
2171 return false;
2172
2173 if (auto *FI = dyn_cast<FenceInst>(I))
2174 // All legal orderings for fence are stronger than monotonic.
2175 return FI->getSyncScopeID() != SyncScope::SingleThread;
2176 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2177 // Unordered is not a legal ordering for cmpxchg.
2178 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2179 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2180 }
2181
2182 AtomicOrdering Ordering;
2183 switch (I->getOpcode()) {
2184 case Instruction::AtomicRMW:
2185 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2186 break;
2187 case Instruction::Store:
2188 Ordering = cast<StoreInst>(I)->getOrdering();
2189 break;
2190 case Instruction::Load:
2191 Ordering = cast<LoadInst>(I)->getOrdering();
2192 break;
2193 default:
2195 "New atomic operations need to be known in the attributor.");
2196 }
2197
2198 return (Ordering != AtomicOrdering::Unordered &&
2199 Ordering != AtomicOrdering::Monotonic);
2200}
2201
2202/// Return true if this intrinsic is nosync. This is only used for intrinsics
2203/// which would be nosync except that they have a volatile flag. All other
2204/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2206 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2207 return !MI->isVolatile();
2208 return false;
2209}
2210
2211namespace {
2212struct AANoSyncImpl : AANoSync {
2213 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2214
2215 /// See AbstractAttribute::initialize(...).
2216 void initialize(Attributor &A) override {
2217 bool IsKnown;
2218 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2219 DepClassTy::NONE, IsKnown));
2220 (void)IsKnown;
2221 }
2222
2223 const std::string getAsStr(Attributor *A) const override {
2224 return getAssumed() ? "nosync" : "may-sync";
2225 }
2226
2227 /// See AbstractAttribute::updateImpl(...).
2228 ChangeStatus updateImpl(Attributor &A) override;
2229};
2230
2231ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2232
2233 auto CheckRWInstForNoSync = [&](Instruction &I) {
2234 return AA::isNoSyncInst(A, I, *this);
2235 };
2236
2237 auto CheckForNoSync = [&](Instruction &I) {
2238 // At this point we handled all read/write effects and they are all
2239 // nosync, so they can be skipped.
2240 if (I.mayReadOrWriteMemory())
2241 return true;
2242
2243 bool IsKnown;
2244 CallBase &CB = cast<CallBase>(I);
2247 IsKnown))
2248 return true;
2249
2250 // non-convergent and readnone imply nosync.
2251 return !CB.isConvergent();
2252 };
2253
2254 bool UsedAssumedInformation = false;
2255 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2256 UsedAssumedInformation) ||
2257 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2258 UsedAssumedInformation))
2259 return indicatePessimisticFixpoint();
2260
2262}
2263
2264struct AANoSyncFunction final : public AANoSyncImpl {
2265 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2266 : AANoSyncImpl(IRP, A) {}
2267
2268 /// See AbstractAttribute::trackStatistics()
2269 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2270};
2271
2272/// NoSync attribute deduction for a call sites.
2273struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2274 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2275 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2276
2277 /// See AbstractAttribute::trackStatistics()
2278 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2279};
2280} // namespace
2281
2282/// ------------------------ No-Free Attributes ----------------------------
2283
2284namespace {
2285struct AANoFreeImpl : public AANoFree {
2286 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2287
2288 /// See AbstractAttribute::initialize(...).
2289 void initialize(Attributor &A) override {
2290 bool IsKnown;
2291 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2292 DepClassTy::NONE, IsKnown));
2293 (void)IsKnown;
2294 }
2295
2296 /// See AbstractAttribute::updateImpl(...).
2297 ChangeStatus updateImpl(Attributor &A) override {
2298 auto CheckForNoFree = [&](Instruction &I) {
2299 bool IsKnown;
2302 DepClassTy::REQUIRED, IsKnown);
2303 };
2304
2305 bool UsedAssumedInformation = false;
2306 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2307 UsedAssumedInformation))
2308 return indicatePessimisticFixpoint();
2309 return ChangeStatus::UNCHANGED;
2310 }
2311
2312 /// See AbstractAttribute::getAsStr().
2313 const std::string getAsStr(Attributor *A) const override {
2314 return getAssumed() ? "nofree" : "may-free";
2315 }
2316};
2317
2318struct AANoFreeFunction final : public AANoFreeImpl {
2319 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2320 : AANoFreeImpl(IRP, A) {}
2321
2322 /// See AbstractAttribute::trackStatistics()
2323 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2324};
2325
2326/// NoFree attribute deduction for a call sites.
2327struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2328 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2329 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2330
2331 /// See AbstractAttribute::trackStatistics()
2332 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2333};
2334
2335/// NoFree attribute for floating values.
2336struct AANoFreeFloating : AANoFreeImpl {
2337 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2338 : AANoFreeImpl(IRP, A) {}
2339
2340 /// See AbstractAttribute::trackStatistics()
2341 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2342
2343 /// See Abstract Attribute::updateImpl(...).
2344 ChangeStatus updateImpl(Attributor &A) override {
2345 const IRPosition &IRP = getIRPosition();
2346
2347 bool IsKnown;
2350 DepClassTy::OPTIONAL, IsKnown))
2351 return ChangeStatus::UNCHANGED;
2352
2353 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2354 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2355 Instruction *UserI = cast<Instruction>(U.getUser());
2356 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2357 if (CB->isBundleOperand(&U))
2358 return false;
2359 if (!CB->isArgOperand(&U))
2360 return true;
2361 unsigned ArgNo = CB->getArgOperandNo(&U);
2362
2363 bool IsKnown;
2365 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2366 DepClassTy::REQUIRED, IsKnown);
2367 }
2368
2369 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2370 isa<SelectInst>(UserI)) {
2371 Follow = true;
2372 return true;
2373 }
2374 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2375 return true;
2376
2377 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2378 return true;
2379
2380 // Unknown user.
2381 return false;
2382 };
2383 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2384 return indicatePessimisticFixpoint();
2385
2386 return ChangeStatus::UNCHANGED;
2387 }
2388};
2389
2390/// NoFree attribute for a call site argument.
2391struct AANoFreeArgument final : AANoFreeFloating {
2392 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2393 : AANoFreeFloating(IRP, A) {}
2394
2395 /// See AbstractAttribute::trackStatistics()
2396 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2397};
2398
2399/// NoFree attribute for call site arguments.
2400struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2401 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2402 : AANoFreeFloating(IRP, A) {}
2403
2404 /// See AbstractAttribute::updateImpl(...).
2405 ChangeStatus updateImpl(Attributor &A) override {
2406 // TODO: Once we have call site specific value information we can provide
2407 // call site specific liveness information and then it makes
2408 // sense to specialize attributes for call sites arguments instead of
2409 // redirecting requests to the callee argument.
2410 Argument *Arg = getAssociatedArgument();
2411 if (!Arg)
2412 return indicatePessimisticFixpoint();
2413 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2414 bool IsKnown;
2416 DepClassTy::REQUIRED, IsKnown))
2417 return ChangeStatus::UNCHANGED;
2418 return indicatePessimisticFixpoint();
2419 }
2420
2421 /// See AbstractAttribute::trackStatistics()
2422 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2423};
2424
2425/// NoFree attribute for function return value.
2426struct AANoFreeReturned final : AANoFreeFloating {
2427 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2428 : AANoFreeFloating(IRP, A) {
2429 llvm_unreachable("NoFree is not applicable to function returns!");
2430 }
2431
2432 /// See AbstractAttribute::initialize(...).
2433 void initialize(Attributor &A) override {
2434 llvm_unreachable("NoFree is not applicable to function returns!");
2435 }
2436
2437 /// See AbstractAttribute::updateImpl(...).
2438 ChangeStatus updateImpl(Attributor &A) override {
2439 llvm_unreachable("NoFree is not applicable to function returns!");
2440 }
2441
2442 /// See AbstractAttribute::trackStatistics()
2443 void trackStatistics() const override {}
2444};
2445
2446/// NoFree attribute deduction for a call site return value.
2447struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2448 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2449 : AANoFreeFloating(IRP, A) {}
2450
2451 ChangeStatus manifest(Attributor &A) override {
2452 return ChangeStatus::UNCHANGED;
2453 }
2454 /// See AbstractAttribute::trackStatistics()
2455 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2456};
2457} // namespace
2458
2459/// ------------------------ NonNull Argument Attribute ------------------------
2460
2462 Attribute::AttrKind ImpliedAttributeKind,
2463 bool IgnoreSubsumingPositions) {
2465 AttrKinds.push_back(Attribute::NonNull);
2468 AttrKinds.push_back(Attribute::Dereferenceable);
2469 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2470 return true;
2471
2472 DominatorTree *DT = nullptr;
2473 AssumptionCache *AC = nullptr;
2474 InformationCache &InfoCache = A.getInfoCache();
2475 if (const Function *Fn = IRP.getAnchorScope()) {
2476 if (!Fn->isDeclaration()) {
2479 }
2480 }
2481
2483 if (IRP.getPositionKind() != IRP_RETURNED) {
2484 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2485 } else {
2486 bool UsedAssumedInformation = false;
2487 if (!A.checkForAllInstructions(
2488 [&](Instruction &I) {
2489 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2490 return true;
2491 },
2492 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2493 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2494 return false;
2495 }
2496
2497 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2498 return !isKnownNonZero(
2499 VAC.getValue(),
2500 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2501 }))
2502 return false;
2503
2504 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2505 Attribute::NonNull)});
2506 return true;
2507}
2508
2509namespace {
2510static int64_t getKnownNonNullAndDerefBytesForUse(
2511 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2512 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2513 TrackUse = false;
2514
2515 const Value *UseV = U->get();
2516 if (!UseV->getType()->isPointerTy())
2517 return 0;
2518
2519 // We need to follow common pointer manipulation uses to the accesses they
2520 // feed into. We can try to be smart to avoid looking through things we do not
2521 // like for now, e.g., non-inbounds GEPs.
2522 if (isa<CastInst>(I)) {
2523 TrackUse = true;
2524 return 0;
2525 }
2526
2528 TrackUse = true;
2529 return 0;
2530 }
2531
2532 Type *PtrTy = UseV->getType();
2533 const Function *F = I->getFunction();
2536 const DataLayout &DL = A.getInfoCache().getDL();
2537 if (const auto *CB = dyn_cast<CallBase>(I)) {
2538 if (CB->isBundleOperand(U)) {
2539 if (RetainedKnowledge RK = getKnowledgeFromUse(
2540 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2541 IsNonNull |=
2542 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2543 return RK.ArgValue;
2544 }
2545 return 0;
2546 }
2547
2548 if (CB->isCallee(U)) {
2549 IsNonNull |= !NullPointerIsDefined;
2550 return 0;
2551 }
2552
2553 unsigned ArgNo = CB->getArgOperandNo(U);
2554 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2555 // As long as we only use known information there is no need to track
2556 // dependences here.
2557 bool IsKnownNonNull;
2559 DepClassTy::NONE, IsKnownNonNull);
2560 IsNonNull |= IsKnownNonNull;
2561 auto *DerefAA =
2562 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2563 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2564 }
2565
2566 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2567 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2568 Loc->Size.isScalable() || I->isVolatile())
2569 return 0;
2570
2571 int64_t Offset;
2572 const Value *Base =
2573 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2574 if (Base && Base == &AssociatedValue) {
2575 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2576 IsNonNull |= !NullPointerIsDefined;
2577 return std::max(int64_t(0), DerefBytes);
2578 }
2579
2580 /// Corner case when an offset is 0.
2582 /*AllowNonInbounds*/ true);
2583 if (Base && Base == &AssociatedValue && Offset == 0) {
2584 int64_t DerefBytes = Loc->Size.getValue();
2585 IsNonNull |= !NullPointerIsDefined;
2586 return std::max(int64_t(0), DerefBytes);
2587 }
2588
2589 return 0;
2590}
2591
2592struct AANonNullImpl : AANonNull {
2593 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2594
2595 /// See AbstractAttribute::initialize(...).
2596 void initialize(Attributor &A) override {
2597 Value &V = *getAssociatedValue().stripPointerCasts();
2598 if (isa<ConstantPointerNull>(V)) {
2599 indicatePessimisticFixpoint();
2600 return;
2601 }
2602
2603 if (Instruction *CtxI = getCtxI())
2604 followUsesInMBEC(*this, A, getState(), *CtxI);
2605 }
2606
2607 /// See followUsesInMBEC
2608 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2609 AANonNull::StateType &State) {
2610 bool IsNonNull = false;
2611 bool TrackUse = false;
2612 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2613 IsNonNull, TrackUse);
2614 State.setKnown(IsNonNull);
2615 return TrackUse;
2616 }
2617
2618 /// See AbstractAttribute::getAsStr().
2619 const std::string getAsStr(Attributor *A) const override {
2620 return getAssumed() ? "nonnull" : "may-null";
2621 }
2622};
2623
2624/// NonNull attribute for a floating value.
2625struct AANonNullFloating : public AANonNullImpl {
2626 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2627 : AANonNullImpl(IRP, A) {}
2628
2629 /// See AbstractAttribute::updateImpl(...).
2630 ChangeStatus updateImpl(Attributor &A) override {
2631 auto CheckIRP = [&](const IRPosition &IRP) {
2632 bool IsKnownNonNull;
2634 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2635 };
2636
2637 bool Stripped;
2638 bool UsedAssumedInformation = false;
2639 Value *AssociatedValue = &getAssociatedValue();
2641 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2642 AA::AnyScope, UsedAssumedInformation))
2643 Stripped = false;
2644 else
2645 Stripped =
2646 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2647
2648 if (!Stripped) {
2649 bool IsKnown;
2650 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2651 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2652 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2653 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2654 IsKnown);
2655 }))
2656 return ChangeStatus::UNCHANGED;
2657 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2659 A, this, IRPosition::value(*Select->getFalseValue()),
2660 DepClassTy::OPTIONAL, IsKnown) &&
2662 A, this, IRPosition::value(*Select->getTrueValue()),
2663 DepClassTy::OPTIONAL, IsKnown))
2664 return ChangeStatus::UNCHANGED;
2665
2666 // If we haven't stripped anything we might still be able to use a
2667 // different AA, but only if the IRP changes. Effectively when we
2668 // interpret this not as a call site value but as a floating/argument
2669 // value.
2670 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2671 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2672 return indicatePessimisticFixpoint();
2673 return ChangeStatus::UNCHANGED;
2674 }
2675
2676 for (const auto &VAC : Values)
2677 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2678 return indicatePessimisticFixpoint();
2679
2680 return ChangeStatus::UNCHANGED;
2681 }
2682
2683 /// See AbstractAttribute::trackStatistics()
2684 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2685};
2686
2687/// NonNull attribute for function return value.
2688struct AANonNullReturned final
2689 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2690 false, AANonNull::IRAttributeKind, false> {
2691 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2692 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2693 false, Attribute::NonNull, false>(IRP, A) {
2694 }
2695
2696 /// See AbstractAttribute::getAsStr().
2697 const std::string getAsStr(Attributor *A) const override {
2698 return getAssumed() ? "nonnull" : "may-null";
2699 }
2700
2701 /// See AbstractAttribute::trackStatistics()
2702 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2703};
2704
2705/// NonNull attribute for function argument.
2706struct AANonNullArgument final
2707 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2708 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2709 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2710
2711 /// See AbstractAttribute::trackStatistics()
2712 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2713};
2714
2715struct AANonNullCallSiteArgument final : AANonNullFloating {
2716 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2717 : AANonNullFloating(IRP, A) {}
2718
2719 /// See AbstractAttribute::trackStatistics()
2720 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2721};
2722
2723/// NonNull attribute for a call site return position.
2724struct AANonNullCallSiteReturned final
2725 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2726 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2727 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2728
2729 /// See AbstractAttribute::trackStatistics()
2730 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2731};
2732} // namespace
2733
2734/// ------------------------ Must-Progress Attributes --------------------------
2735namespace {
2736struct AAMustProgressImpl : public AAMustProgress {
2737 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2738 : AAMustProgress(IRP, A) {}
2739
2740 /// See AbstractAttribute::initialize(...).
2741 void initialize(Attributor &A) override {
2742 bool IsKnown;
2744 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2745 (void)IsKnown;
2746 }
2747
2748 /// See AbstractAttribute::getAsStr()
2749 const std::string getAsStr(Attributor *A) const override {
2750 return getAssumed() ? "mustprogress" : "may-not-progress";
2751 }
2752};
2753
2754struct AAMustProgressFunction final : AAMustProgressImpl {
2755 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2756 : AAMustProgressImpl(IRP, A) {}
2757
2758 /// See AbstractAttribute::updateImpl(...).
2759 ChangeStatus updateImpl(Attributor &A) override {
2760 bool IsKnown;
2762 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2763 if (IsKnown)
2764 return indicateOptimisticFixpoint();
2765 return ChangeStatus::UNCHANGED;
2766 }
2767
2768 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2769 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2770 bool IsKnownMustProgress;
2772 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2773 /* IgnoreSubsumingPositions */ true);
2774 };
2775
2776 bool AllCallSitesKnown = true;
2777 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2778 /* RequireAllCallSites */ true,
2779 AllCallSitesKnown))
2780 return indicatePessimisticFixpoint();
2781
2782 return ChangeStatus::UNCHANGED;
2783 }
2784
2785 /// See AbstractAttribute::trackStatistics()
2786 void trackStatistics() const override {
2787 STATS_DECLTRACK_FN_ATTR(mustprogress)
2788 }
2789};
2790
2791/// MustProgress attribute deduction for a call sites.
2792struct AAMustProgressCallSite final : AAMustProgressImpl {
2793 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2794 : AAMustProgressImpl(IRP, A) {}
2795
2796 /// See AbstractAttribute::updateImpl(...).
2797 ChangeStatus updateImpl(Attributor &A) override {
2798 // TODO: Once we have call site specific value information we can provide
2799 // call site specific liveness information and then it makes
2800 // sense to specialize attributes for call sites arguments instead of
2801 // redirecting requests to the callee argument.
2802 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2803 bool IsKnownMustProgress;
2805 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2806 return indicatePessimisticFixpoint();
2807 return ChangeStatus::UNCHANGED;
2808 }
2809
2810 /// See AbstractAttribute::trackStatistics()
2811 void trackStatistics() const override {
2812 STATS_DECLTRACK_CS_ATTR(mustprogress);
2813 }
2814};
2815} // namespace
2816
2817/// ------------------------ No-Recurse Attributes ----------------------------
2818
2819namespace {
2820struct AANoRecurseImpl : public AANoRecurse {
2821 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2822
2823 /// See AbstractAttribute::initialize(...).
2824 void initialize(Attributor &A) override {
2825 bool IsKnown;
2827 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2828 (void)IsKnown;
2829 }
2830
2831 /// See AbstractAttribute::getAsStr()
2832 const std::string getAsStr(Attributor *A) const override {
2833 return getAssumed() ? "norecurse" : "may-recurse";
2834 }
2835};
2836
2837struct AANoRecurseFunction final : AANoRecurseImpl {
2838 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2839 : AANoRecurseImpl(IRP, A) {}
2840
2841 /// See AbstractAttribute::updateImpl(...).
2842 ChangeStatus updateImpl(Attributor &A) override {
2843
2844 // If all live call sites are known to be no-recurse, we are as well.
2845 auto CallSitePred = [&](AbstractCallSite ACS) {
2846 bool IsKnownNoRecurse;
2848 A, this,
2849 IRPosition::function(*ACS.getInstruction()->getFunction()),
2850 DepClassTy::NONE, IsKnownNoRecurse))
2851 return false;
2852 return IsKnownNoRecurse;
2853 };
2854 bool UsedAssumedInformation = false;
2855 if (A.checkForAllCallSites(CallSitePred, *this, true,
2856 UsedAssumedInformation)) {
2857 // If we know all call sites and all are known no-recurse, we are done.
2858 // If all known call sites, which might not be all that exist, are known
2859 // to be no-recurse, we are not done but we can continue to assume
2860 // no-recurse. If one of the call sites we have not visited will become
2861 // live, another update is triggered.
2862 if (!UsedAssumedInformation)
2863 indicateOptimisticFixpoint();
2864 return ChangeStatus::UNCHANGED;
2865 }
2866
2867 const AAInterFnReachability *EdgeReachability =
2868 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2869 DepClassTy::REQUIRED);
2870 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2871 return indicatePessimisticFixpoint();
2872 return ChangeStatus::UNCHANGED;
2873 }
2874
2875 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2876};
2877
2878/// NoRecurse attribute deduction for a call sites.
2879struct AANoRecurseCallSite final
2880 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2881 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2882 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2883
2884 /// See AbstractAttribute::trackStatistics()
2885 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2886};
2887} // namespace
2888
2889/// ------------------------ No-Convergent Attribute --------------------------
2890
2891namespace {
2892struct AANonConvergentImpl : public AANonConvergent {
2893 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2894 : AANonConvergent(IRP, A) {}
2895
2896 /// See AbstractAttribute::getAsStr()
2897 const std::string getAsStr(Attributor *A) const override {
2898 return getAssumed() ? "non-convergent" : "may-be-convergent";
2899 }
2900};
2901
2902struct AANonConvergentFunction final : AANonConvergentImpl {
2903 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2904 : AANonConvergentImpl(IRP, A) {}
2905
2906 /// See AbstractAttribute::updateImpl(...).
2907 ChangeStatus updateImpl(Attributor &A) override {
2908 // If all function calls are known to not be convergent, we are not
2909 // convergent.
2910 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2911 CallBase &CB = cast<CallBase>(Inst);
2913 if (!Callee || Callee->isIntrinsic()) {
2914 return false;
2915 }
2916 if (Callee->isDeclaration()) {
2917 return !Callee->hasFnAttribute(Attribute::Convergent);
2918 }
2919 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2920 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2921 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2922 };
2923
2924 bool UsedAssumedInformation = false;
2925 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2926 UsedAssumedInformation)) {
2927 return indicatePessimisticFixpoint();
2928 }
2929 return ChangeStatus::UNCHANGED;
2930 }
2931
2932 ChangeStatus manifest(Attributor &A) override {
2933 if (isKnownNotConvergent() &&
2934 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2935 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2936 return ChangeStatus::CHANGED;
2937 }
2938 return ChangeStatus::UNCHANGED;
2939 }
2940
2941 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2942};
2943} // namespace
2944
2945/// -------------------- Undefined-Behavior Attributes ------------------------
2946
2947namespace {
2948struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2949 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2950 : AAUndefinedBehavior(IRP, A) {}
2951
2952 /// See AbstractAttribute::updateImpl(...).
2953 // through a pointer (i.e. also branches etc.)
2954 ChangeStatus updateImpl(Attributor &A) override {
2955 const size_t UBPrevSize = KnownUBInsts.size();
2956 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2957
2958 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2959 // Lang ref now states volatile store is not UB, let's skip them.
2960 if (I.isVolatile() && I.mayWriteToMemory())
2961 return true;
2962
2963 // Skip instructions that are already saved.
2964 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2965 return true;
2966
2967 // If we reach here, we know we have an instruction
2968 // that accesses memory through a pointer operand,
2969 // for which getPointerOperand() should give it to us.
2970 Value *PtrOp =
2971 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2972 assert(PtrOp &&
2973 "Expected pointer operand of memory accessing instruction");
2974
2975 // Either we stopped and the appropriate action was taken,
2976 // or we got back a simplified value to continue.
2977 std::optional<Value *> SimplifiedPtrOp =
2978 stopOnUndefOrAssumed(A, PtrOp, &I);
2979 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2980 return true;
2981 const Value *PtrOpVal = *SimplifiedPtrOp;
2982
2983 // A memory access through a pointer is considered UB
2984 // only if the pointer has constant null value.
2985 // TODO: Expand it to not only check constant values.
2986 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2987 AssumedNoUBInsts.insert(&I);
2988 return true;
2989 }
2990 const Type *PtrTy = PtrOpVal->getType();
2991
2992 // Because we only consider instructions inside functions,
2993 // assume that a parent function exists.
2994 const Function *F = I.getFunction();
2995
2996 // A memory access using constant null pointer is only considered UB
2997 // if null pointer is _not_ defined for the target platform.
2999 AssumedNoUBInsts.insert(&I);
3000 else
3001 KnownUBInsts.insert(&I);
3002 return true;
3003 };
3004
3005 auto InspectBrInstForUB = [&](Instruction &I) {
3006 // A conditional branch instruction is considered UB if it has `undef`
3007 // condition.
3008
3009 // Skip instructions that are already saved.
3010 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3011 return true;
3012
3013 // We know we have a branch instruction.
3014 auto *BrInst = cast<CondBrInst>(&I);
3015
3016 // Either we stopped and the appropriate action was taken,
3017 // or we got back a simplified value to continue.
3018 std::optional<Value *> SimplifiedCond =
3019 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3020 if (!SimplifiedCond || !*SimplifiedCond)
3021 return true;
3022 AssumedNoUBInsts.insert(&I);
3023 return true;
3024 };
3025
3026 auto InspectCallSiteForUB = [&](Instruction &I) {
3027 // Check whether a callsite always cause UB or not
3028
3029 // Skip instructions that are already saved.
3030 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3031 return true;
3032
3033 // Check nonnull and noundef argument attribute violation for each
3034 // callsite.
3035 CallBase &CB = cast<CallBase>(I);
3037 if (!Callee)
3038 return true;
3039 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3040 // If current argument is known to be simplified to null pointer and the
3041 // corresponding argument position is known to have nonnull attribute,
3042 // the argument is poison. Furthermore, if the argument is poison and
3043 // the position is known to have noundef attriubte, this callsite is
3044 // considered UB.
3045 if (idx >= Callee->arg_size())
3046 break;
3047 Value *ArgVal = CB.getArgOperand(idx);
3048 if (!ArgVal)
3049 continue;
3050 // Here, we handle three cases.
3051 // (1) Not having a value means it is dead. (we can replace the value
3052 // with undef)
3053 // (2) Simplified to undef. The argument violate noundef attriubte.
3054 // (3) Simplified to null pointer where known to be nonnull.
3055 // The argument is a poison value and violate noundef attribute.
3056 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3057 bool IsKnownNoUndef;
3059 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3060 if (!IsKnownNoUndef)
3061 continue;
3062 bool UsedAssumedInformation = false;
3063 std::optional<Value *> SimplifiedVal =
3064 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3065 UsedAssumedInformation, AA::Interprocedural);
3066 if (UsedAssumedInformation)
3067 continue;
3068 if (SimplifiedVal && !*SimplifiedVal)
3069 return true;
3070 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3071 KnownUBInsts.insert(&I);
3072 continue;
3073 }
3074 if (!ArgVal->getType()->isPointerTy() ||
3075 !isa<ConstantPointerNull>(**SimplifiedVal))
3076 continue;
3077 bool IsKnownNonNull;
3079 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3080 if (IsKnownNonNull)
3081 KnownUBInsts.insert(&I);
3082 }
3083 return true;
3084 };
3085
3086 auto InspectReturnInstForUB = [&](Instruction &I) {
3087 auto &RI = cast<ReturnInst>(I);
3088 // Either we stopped and the appropriate action was taken,
3089 // or we got back a simplified return value to continue.
3090 std::optional<Value *> SimplifiedRetValue =
3091 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3092 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3093 return true;
3094
3095 // Check if a return instruction always cause UB or not
3096 // Note: It is guaranteed that the returned position of the anchor
3097 // scope has noundef attribute when this is called.
3098 // We also ensure the return position is not "assumed dead"
3099 // because the returned value was then potentially simplified to
3100 // `undef` in AAReturnedValues without removing the `noundef`
3101 // attribute yet.
3102
3103 // When the returned position has noundef attriubte, UB occurs in the
3104 // following cases.
3105 // (1) Returned value is known to be undef.
3106 // (2) The value is known to be a null pointer and the returned
3107 // position has nonnull attribute (because the returned value is
3108 // poison).
3109 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3110 bool IsKnownNonNull;
3112 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3113 IsKnownNonNull);
3114 if (IsKnownNonNull)
3115 KnownUBInsts.insert(&I);
3116 }
3117
3118 return true;
3119 };
3120
3121 bool UsedAssumedInformation = false;
3122 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3123 {Instruction::Load, Instruction::Store,
3124 Instruction::AtomicCmpXchg,
3125 Instruction::AtomicRMW},
3126 UsedAssumedInformation,
3127 /* CheckBBLivenessOnly */ true);
3128 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3129 UsedAssumedInformation,
3130 /* CheckBBLivenessOnly */ true);
3131 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3132 UsedAssumedInformation);
3133
3134 // If the returned position of the anchor scope has noundef attriubte, check
3135 // all returned instructions.
3136 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3137 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3138 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3139 bool IsKnownNoUndef;
3141 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3142 if (IsKnownNoUndef)
3143 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3144 {Instruction::Ret}, UsedAssumedInformation,
3145 /* CheckBBLivenessOnly */ true);
3146 }
3147 }
3148
3149 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3150 UBPrevSize != KnownUBInsts.size())
3151 return ChangeStatus::CHANGED;
3152 return ChangeStatus::UNCHANGED;
3153 }
3154
3155 bool isKnownToCauseUB(Instruction *I) const override {
3156 return KnownUBInsts.count(I);
3157 }
3158
3159 bool isAssumedToCauseUB(Instruction *I) const override {
3160 // In simple words, if an instruction is not in the assumed to _not_
3161 // cause UB, then it is assumed UB (that includes those
3162 // in the KnownUBInsts set). The rest is boilerplate
3163 // is to ensure that it is one of the instructions we test
3164 // for UB.
3165
3166 switch (I->getOpcode()) {
3167 case Instruction::Load:
3168 case Instruction::Store:
3169 case Instruction::AtomicCmpXchg:
3170 case Instruction::AtomicRMW:
3171 case Instruction::CondBr:
3172 return !AssumedNoUBInsts.count(I);
3173 default:
3174 return false;
3175 }
3176 return false;
3177 }
3178
3179 ChangeStatus manifest(Attributor &A) override {
3180 if (KnownUBInsts.empty())
3181 return ChangeStatus::UNCHANGED;
3182 for (Instruction *I : KnownUBInsts)
3183 A.changeToUnreachableAfterManifest(I);
3184 return ChangeStatus::CHANGED;
3185 }
3186
3187 /// See AbstractAttribute::getAsStr()
3188 const std::string getAsStr(Attributor *A) const override {
3189 return getAssumed() ? "undefined-behavior" : "no-ub";
3190 }
3191
3192 /// Note: The correctness of this analysis depends on the fact that the
3193 /// following 2 sets will stop changing after some point.
3194 /// "Change" here means that their size changes.
3195 /// The size of each set is monotonically increasing
3196 /// (we only add items to them) and it is upper bounded by the number of
3197 /// instructions in the processed function (we can never save more
3198 /// elements in either set than this number). Hence, at some point,
3199 /// they will stop increasing.
3200 /// Consequently, at some point, both sets will have stopped
3201 /// changing, effectively making the analysis reach a fixpoint.
3202
3203 /// Note: These 2 sets are disjoint and an instruction can be considered
3204 /// one of 3 things:
3205 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3206 /// the KnownUBInsts set.
3207 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3208 /// has a reason to assume it).
3209 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3210 /// could not find a reason to assume or prove that it can cause UB,
3211 /// hence it assumes it doesn't. We have a set for these instructions
3212 /// so that we don't reprocess them in every update.
3213 /// Note however that instructions in this set may cause UB.
3214
3215protected:
3216 /// A set of all live instructions _known_ to cause UB.
3217 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3218
3219private:
3220 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3221 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3222
3223 // Should be called on updates in which if we're processing an instruction
3224 // \p I that depends on a value \p V, one of the following has to happen:
3225 // - If the value is assumed, then stop.
3226 // - If the value is known but undef, then consider it UB.
3227 // - Otherwise, do specific processing with the simplified value.
3228 // We return std::nullopt in the first 2 cases to signify that an appropriate
3229 // action was taken and the caller should stop.
3230 // Otherwise, we return the simplified value that the caller should
3231 // use for specific processing.
3232 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3233 Instruction *I) {
3234 bool UsedAssumedInformation = false;
3235 std::optional<Value *> SimplifiedV =
3236 A.getAssumedSimplified(IRPosition::value(*V), *this,
3237 UsedAssumedInformation, AA::Interprocedural);
3238 if (!UsedAssumedInformation) {
3239 // Don't depend on assumed values.
3240 if (!SimplifiedV) {
3241 // If it is known (which we tested above) but it doesn't have a value,
3242 // then we can assume `undef` and hence the instruction is UB.
3243 KnownUBInsts.insert(I);
3244 return std::nullopt;
3245 }
3246 if (!*SimplifiedV)
3247 return nullptr;
3248 V = *SimplifiedV;
3249 }
3250 if (isa<UndefValue>(V)) {
3251 KnownUBInsts.insert(I);
3252 return std::nullopt;
3253 }
3254 return V;
3255 }
3256};
3257
3258struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3259 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3260 : AAUndefinedBehaviorImpl(IRP, A) {}
3261
3262 /// See AbstractAttribute::trackStatistics()
3263 void trackStatistics() const override {
3264 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3265 "Number of instructions known to have UB");
3266 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3267 KnownUBInsts.size();
3268 }
3269};
3270} // namespace
3271
3272/// ------------------------ Will-Return Attributes ----------------------------
3273
3274namespace {
3275// Helper function that checks whether a function has any cycle which we don't
3276// know if it is bounded or not.
3277// Loops with maximum trip count are considered bounded, any other cycle not.
3278static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3279 ScalarEvolution *SE =
3280 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3281 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3282 // If either SCEV or LoopInfo is not available for the function then we assume
3283 // any cycle to be unbounded cycle.
3284 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3285 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3286 if (!SE || !LI) {
3287 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3288 if (SCCI.hasCycle())
3289 return true;
3290 return false;
3291 }
3292
3293 // If there's irreducible control, the function may contain non-loop cycles.
3295 return true;
3296
3297 // Any loop that does not have a max trip count is considered unbounded cycle.
3298 for (auto *L : LI->getLoopsInPreorder()) {
3299 if (!SE->getSmallConstantMaxTripCount(L))
3300 return true;
3301 }
3302 return false;
3303}
3304
3305struct AAWillReturnImpl : public AAWillReturn {
3306 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3307 : AAWillReturn(IRP, A) {}
3308
3309 /// See AbstractAttribute::initialize(...).
3310 void initialize(Attributor &A) override {
3311 bool IsKnown;
3313 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3314 (void)IsKnown;
3315 }
3316
3317 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3318 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3319 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3320 return false;
3321
3322 bool IsKnown;
3323 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3324 return IsKnown || !KnownOnly;
3325 return false;
3326 }
3327
3328 /// See AbstractAttribute::updateImpl(...).
3329 ChangeStatus updateImpl(Attributor &A) override {
3330 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3331 return ChangeStatus::UNCHANGED;
3332
3333 auto CheckForWillReturn = [&](Instruction &I) {
3335 bool IsKnown;
3337 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3338 if (IsKnown)
3339 return true;
3340 } else {
3341 return false;
3342 }
3343 bool IsKnownNoRecurse;
3345 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3346 };
3347
3348 bool UsedAssumedInformation = false;
3349 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3350 UsedAssumedInformation))
3351 return indicatePessimisticFixpoint();
3352
3353 return ChangeStatus::UNCHANGED;
3354 }
3355
3356 /// See AbstractAttribute::getAsStr()
3357 const std::string getAsStr(Attributor *A) const override {
3358 return getAssumed() ? "willreturn" : "may-noreturn";
3359 }
3360};
3361
3362struct AAWillReturnFunction final : AAWillReturnImpl {
3363 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3364 : AAWillReturnImpl(IRP, A) {}
3365
3366 /// See AbstractAttribute::initialize(...).
3367 void initialize(Attributor &A) override {
3368 AAWillReturnImpl::initialize(A);
3369
3370 Function *F = getAnchorScope();
3371 assert(F && "Did expect an anchor function");
3372 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3373 indicatePessimisticFixpoint();
3374 }
3375
3376 /// See AbstractAttribute::trackStatistics()
3377 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3378};
3379
3380/// WillReturn attribute deduction for a call sites.
3381struct AAWillReturnCallSite final
3382 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3383 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3384 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3385
3386 /// See AbstractAttribute::updateImpl(...).
3387 ChangeStatus updateImpl(Attributor &A) override {
3388 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3389 return ChangeStatus::UNCHANGED;
3390
3391 return AACalleeToCallSite::updateImpl(A);
3392 }
3393
3394 /// See AbstractAttribute::trackStatistics()
3395 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3396};
3397} // namespace
3398
3399/// -------------------AAIntraFnReachability Attribute--------------------------
3400
3401/// All information associated with a reachability query. This boilerplate code
3402/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3403/// different \p ToTy values.
3404template <typename ToTy> struct ReachabilityQueryInfo {
3405 enum class Reachable {
3408 };
3409
3410 /// Start here,
3411 const Instruction *From = nullptr;
3412 /// reach this place,
3413 const ToTy *To = nullptr;
3414 /// without going through any of these instructions,
3416 /// and remember if it worked:
3418
3419 /// Precomputed hash for this RQI.
3420 unsigned Hash = 0;
3421
3422 unsigned computeHashValue() const {
3423 assert(Hash == 0 && "Computed hash twice!");
3426 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3427 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3428 InstSetDMI::getHashValue(ExclusionSet));
3429 }
3430
3432 : From(From), To(To) {}
3433
3434 /// Constructor replacement to ensure unique and stable sets are used for the
3435 /// cache.
3437 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3438 : From(&From), To(&To), ExclusionSet(ES) {
3439
3440 if (!ES || ES->empty()) {
3441 ExclusionSet = nullptr;
3442 } else if (MakeUnique) {
3443 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3444 }
3445 }
3446
3449};
3450
3451namespace llvm {
3452template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3455
3458
3461 return &TombstoneKey;
3462 }
3463 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3464 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3465 }
3466 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3467 const ReachabilityQueryInfo<ToTy> *RHS) {
3468 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3469 return false;
3470 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3471 }
3472};
3473
3474#define DefineKeys(ToTy) \
3475 template <> \
3476 ReachabilityQueryInfo<ToTy> \
3477 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3478 ReachabilityQueryInfo<ToTy>( \
3479 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3480 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3481 template <> \
3482 ReachabilityQueryInfo<ToTy> \
3483 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3484 ReachabilityQueryInfo<ToTy>( \
3485 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3486 DenseMapInfo<const ToTy *>::getTombstoneKey());
3487
3489#undef DefineKeys
3490
3491} // namespace llvm
3492
3493namespace {
3494
3495template <typename BaseTy, typename ToTy>
3496struct CachedReachabilityAA : public BaseTy {
3497 using RQITy = ReachabilityQueryInfo<ToTy>;
3498
3499 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3500
3501 /// See AbstractAttribute::isQueryAA.
3502 bool isQueryAA() const override { return true; }
3503
3504 /// See AbstractAttribute::updateImpl(...).
3505 ChangeStatus updateImpl(Attributor &A) override {
3506 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3507 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3508 RQITy *RQI = QueryVector[u];
3509 if (RQI->Result == RQITy::Reachable::No &&
3510 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3511 Changed = ChangeStatus::CHANGED;
3512 }
3513 return Changed;
3514 }
3515
3516 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3517 bool IsTemporaryRQI) = 0;
3518
3519 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3520 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3521 RQI.Result = Result;
3522
3523 // Remove the temporary RQI from the cache.
3524 if (IsTemporaryRQI)
3525 QueryCache.erase(&RQI);
3526
3527 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3528 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3529 // this query. 2) We did not use the exclusion set, potentially because
3530 // there is none.
3531 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3532 RQITy PlainRQI(RQI.From, RQI.To);
3533 if (!QueryCache.count(&PlainRQI)) {
3534 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3535 RQIPtr->Result = Result;
3536 QueryVector.push_back(RQIPtr);
3537 QueryCache.insert(RQIPtr);
3538 }
3539 }
3540
3541 // Check if we need to insert a new permanent RQI with the exclusion set.
3542 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3543 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3544 "Did not expect empty set!");
3545 RQITy *RQIPtr = new (A.Allocator)
3546 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3547 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3548 RQIPtr->Result = Result;
3549 assert(!QueryCache.count(RQIPtr));
3550 QueryVector.push_back(RQIPtr);
3551 QueryCache.insert(RQIPtr);
3552 }
3553
3554 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3555 A.registerForUpdate(*this);
3556 return Result == RQITy::Reachable::Yes;
3557 }
3558
3559 const std::string getAsStr(Attributor *A) const override {
3560 // TODO: Return the number of reachable queries.
3561 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3562 }
3563
3564 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3565 typename RQITy::Reachable &Result) {
3566 if (!this->getState().isValidState()) {
3567 Result = RQITy::Reachable::Yes;
3568 return true;
3569 }
3570
3571 // If we have an exclusion set we might be able to find our answer by
3572 // ignoring it first.
3573 if (StackRQI.ExclusionSet) {
3574 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3575 auto It = QueryCache.find(&PlainRQI);
3576 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3577 Result = RQITy::Reachable::No;
3578 return true;
3579 }
3580 }
3581
3582 auto It = QueryCache.find(&StackRQI);
3583 if (It != QueryCache.end()) {
3584 Result = (*It)->Result;
3585 return true;
3586 }
3587
3588 // Insert a temporary for recursive queries. We will replace it with a
3589 // permanent entry later.
3590 QueryCache.insert(&StackRQI);
3591 return false;
3592 }
3593
3594private:
3595 SmallVector<RQITy *> QueryVector;
3596 DenseSet<RQITy *> QueryCache;
3597};
3598
3599struct AAIntraFnReachabilityFunction final
3600 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3601 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3602 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3603 : Base(IRP, A) {
3604 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3605 *IRP.getAssociatedFunction());
3606 }
3607
3608 bool isAssumedReachable(
3609 Attributor &A, const Instruction &From, const Instruction &To,
3610 const AA::InstExclusionSetTy *ExclusionSet) const override {
3611 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3612 if (&From == &To)
3613 return true;
3614
3615 RQITy StackRQI(A, From, To, ExclusionSet, false);
3616 RQITy::Reachable Result;
3617 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3618 return NonConstThis->isReachableImpl(A, StackRQI,
3619 /*IsTemporaryRQI=*/true);
3620 return Result == RQITy::Reachable::Yes;
3621 }
3622
3623 ChangeStatus updateImpl(Attributor &A) override {
3624 // We only depend on liveness. DeadEdges is all we care about, check if any
3625 // of them changed.
3626 auto *LivenessAA =
3627 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3628 if (LivenessAA &&
3629 llvm::all_of(DeadEdges,
3630 [&](const auto &DeadEdge) {
3631 return LivenessAA->isEdgeDead(DeadEdge.first,
3632 DeadEdge.second);
3633 }) &&
3634 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3635 return LivenessAA->isAssumedDead(BB);
3636 })) {
3637 return ChangeStatus::UNCHANGED;
3638 }
3639 DeadEdges.clear();
3640 DeadBlocks.clear();
3641 return Base::updateImpl(A);
3642 }
3643
3644 bool isReachableImpl(Attributor &A, RQITy &RQI,
3645 bool IsTemporaryRQI) override {
3646 const Instruction *Origin = RQI.From;
3647 bool UsedExclusionSet = false;
3648
3649 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3650 const AA::InstExclusionSetTy *ExclusionSet) {
3651 const Instruction *IP = &From;
3652 while (IP && IP != &To) {
3653 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3654 UsedExclusionSet = true;
3655 break;
3656 }
3657 IP = IP->getNextNode();
3658 }
3659 return IP == &To;
3660 };
3661
3662 const BasicBlock *FromBB = RQI.From->getParent();
3663 const BasicBlock *ToBB = RQI.To->getParent();
3664 assert(FromBB->getParent() == ToBB->getParent() &&
3665 "Not an intra-procedural query!");
3666
3667 // Check intra-block reachability, however, other reaching paths are still
3668 // possible.
3669 if (FromBB == ToBB &&
3670 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3671 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3672 IsTemporaryRQI);
3673
3674 // Check if reaching the ToBB block is sufficient or if even that would not
3675 // ensure reaching the target. In the latter case we are done.
3676 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3677 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3678 IsTemporaryRQI);
3679
3680 const Function *Fn = FromBB->getParent();
3681 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3682 if (RQI.ExclusionSet)
3683 for (auto *I : *RQI.ExclusionSet)
3684 if (I->getFunction() == Fn)
3685 ExclusionBlocks.insert(I->getParent());
3686
3687 // Check if we make it out of the FromBB block at all.
3688 if (ExclusionBlocks.count(FromBB) &&
3689 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3690 RQI.ExclusionSet))
3691 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3692
3693 auto *LivenessAA =
3694 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3695 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3696 DeadBlocks.insert(ToBB);
3697 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3698 IsTemporaryRQI);
3699 }
3700
3701 SmallPtrSet<const BasicBlock *, 16> Visited;
3703 Worklist.push_back(FromBB);
3704
3705 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3706 while (!Worklist.empty()) {
3707 const BasicBlock *BB = Worklist.pop_back_val();
3708 if (!Visited.insert(BB).second)
3709 continue;
3710 for (const BasicBlock *SuccBB : successors(BB)) {
3711 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3712 LocalDeadEdges.insert({BB, SuccBB});
3713 continue;
3714 }
3715 // We checked before if we just need to reach the ToBB block.
3716 if (SuccBB == ToBB)
3717 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3718 IsTemporaryRQI);
3719 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3720 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3721 IsTemporaryRQI);
3722
3723 if (ExclusionBlocks.count(SuccBB)) {
3724 UsedExclusionSet = true;
3725 continue;
3726 }
3727 Worklist.push_back(SuccBB);
3728 }
3729 }
3730
3731 DeadEdges.insert_range(LocalDeadEdges);
3732 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3733 IsTemporaryRQI);
3734 }
3735
3736 /// See AbstractAttribute::trackStatistics()
3737 void trackStatistics() const override {}
3738
3739private:
3740 // Set of assumed dead blocks we used in the last query. If any changes we
3741 // update the state.
3742 DenseSet<const BasicBlock *> DeadBlocks;
3743
3744 // Set of assumed dead edges we used in the last query. If any changes we
3745 // update the state.
3746 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3747
3748 /// The dominator tree of the function to short-circuit reasoning.
3749 const DominatorTree *DT = nullptr;
3750};
3751} // namespace
3752
3753/// ------------------------ NoAlias Argument Attribute ------------------------
3754
3756 Attribute::AttrKind ImpliedAttributeKind,
3757 bool IgnoreSubsumingPositions) {
3758 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3759 "Unexpected attribute kind");
3760 Value *Val = &IRP.getAssociatedValue();
3762 if (isa<AllocaInst>(Val))
3763 return true;
3764 } else {
3765 IgnoreSubsumingPositions = true;
3766 }
3767
3768 if (isa<UndefValue>(Val))
3769 return true;
3770
3771 if (isa<ConstantPointerNull>(Val) &&
3774 return true;
3775
3776 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3777 IgnoreSubsumingPositions, Attribute::NoAlias))
3778 return true;
3779
3780 return false;
3781}
3782
3783namespace {
3784struct AANoAliasImpl : AANoAlias {
3785 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3786 assert(getAssociatedType()->isPointerTy() &&
3787 "Noalias is a pointer attribute");
3788 }
3789
3790 const std::string getAsStr(Attributor *A) const override {
3791 return getAssumed() ? "noalias" : "may-alias";
3792 }
3793};
3794
3795/// NoAlias attribute for a floating value.
3796struct AANoAliasFloating final : AANoAliasImpl {
3797 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3798 : AANoAliasImpl(IRP, A) {}
3799
3800 /// See AbstractAttribute::updateImpl(...).
3801 ChangeStatus updateImpl(Attributor &A) override {
3802 // TODO: Implement this.
3803 return indicatePessimisticFixpoint();
3804 }
3805
3806 /// See AbstractAttribute::trackStatistics()
3807 void trackStatistics() const override {
3809 }
3810};
3811
3812/// NoAlias attribute for an argument.
3813struct AANoAliasArgument final
3814 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3815 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3816 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3817
3818 /// See AbstractAttribute::update(...).
3819 ChangeStatus updateImpl(Attributor &A) override {
3820 // We have to make sure no-alias on the argument does not break
3821 // synchronization when this is a callback argument, see also [1] below.
3822 // If synchronization cannot be affected, we delegate to the base updateImpl
3823 // function, otherwise we give up for now.
3824
3825 // If the function is no-sync, no-alias cannot break synchronization.
3826 bool IsKnownNoSycn;
3828 A, this, IRPosition::function_scope(getIRPosition()),
3829 DepClassTy::OPTIONAL, IsKnownNoSycn))
3830 return Base::updateImpl(A);
3831
3832 // If the argument is read-only, no-alias cannot break synchronization.
3833 bool IsKnown;
3834 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3835 return Base::updateImpl(A);
3836
3837 // If the argument is never passed through callbacks, no-alias cannot break
3838 // synchronization.
3839 bool UsedAssumedInformation = false;
3840 if (A.checkForAllCallSites(
3841 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3842 true, UsedAssumedInformation))
3843 return Base::updateImpl(A);
3844
3845 // TODO: add no-alias but make sure it doesn't break synchronization by
3846 // introducing fake uses. See:
3847 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3848 // International Workshop on OpenMP 2018,
3849 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3850
3851 return indicatePessimisticFixpoint();
3852 }
3853
3854 /// See AbstractAttribute::trackStatistics()
3855 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3856};
3857
3858struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3859 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3860 : AANoAliasImpl(IRP, A) {}
3861
3862 /// Determine if the underlying value may alias with the call site argument
3863 /// \p OtherArgNo of \p ICS (= the underlying call site).
3864 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3865 const AAMemoryBehavior &MemBehaviorAA,
3866 const CallBase &CB, unsigned OtherArgNo) {
3867 // We do not need to worry about aliasing with the underlying IRP.
3868 if (this->getCalleeArgNo() == (int)OtherArgNo)
3869 return false;
3870
3871 // If it is not a pointer or pointer vector we do not alias.
3872 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3873 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3874 return false;
3875
3876 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3877 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3878
3879 // If the argument is readnone, there is no read-write aliasing.
3880 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3881 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3882 return false;
3883 }
3884
3885 // If the argument is readonly and the underlying value is readonly, there
3886 // is no read-write aliasing.
3887 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3888 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3889 IsReadOnly) {
3890 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3891 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3892 return false;
3893 }
3894
3895 // We have to utilize actual alias analysis queries so we need the object.
3896 if (!AAR)
3897 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3898 *getAnchorScope());
3899
3900 // Try to rule it out at the call site.
3901 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3902 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3903 "callsite arguments: "
3904 << getAssociatedValue() << " " << *ArgOp << " => "
3905 << (IsAliasing ? "" : "no-") << "alias \n");
3906
3907 return IsAliasing;
3908 }
3909
3910 bool isKnownNoAliasDueToNoAliasPreservation(
3911 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3912 // We can deduce "noalias" if the following conditions hold.
3913 // (i) Associated value is assumed to be noalias in the definition.
3914 // (ii) Associated value is assumed to be no-capture in all the uses
3915 // possibly executed before this callsite.
3916 // (iii) There is no other pointer argument which could alias with the
3917 // value.
3918
3919 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3920 const Function *ScopeFn = VIRP.getAnchorScope();
3921 // Check whether the value is captured in the scope using AANoCapture.
3922 // Look at CFG and check only uses possibly executed before this
3923 // callsite.
3924 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3925 Instruction *UserI = cast<Instruction>(U.getUser());
3926
3927 // If UserI is the curr instruction and there is a single potential use of
3928 // the value in UserI we allow the use.
3929 // TODO: We should inspect the operands and allow those that cannot alias
3930 // with the value.
3931 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3932 return true;
3933
3934 if (ScopeFn) {
3935 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3936 if (CB->isArgOperand(&U)) {
3937
3938 unsigned ArgNo = CB->getArgOperandNo(&U);
3939
3940 bool IsKnownNoCapture;
3942 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3943 DepClassTy::OPTIONAL, IsKnownNoCapture))
3944 return true;
3945 }
3946 }
3947
3949 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3950 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3951 return true;
3952 }
3953
3954 // TODO: We should track the capturing uses in AANoCapture but the problem
3955 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3956 // a value in the module slice.
3957 // TODO(captures): Make this more precise.
3958 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3959 if (capturesNothing(CI))
3960 return true;
3961 if (CI.isPassthrough()) {
3962 Follow = true;
3963 return true;
3964 }
3965 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3966 return false;
3967 };
3968
3969 bool IsKnownNoCapture;
3970 const AANoCapture *NoCaptureAA = nullptr;
3971 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3972 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3973 if (!IsAssumedNoCapture &&
3974 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3975 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3976 LLVM_DEBUG(
3977 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3978 << " cannot be noalias as it is potentially captured\n");
3979 return false;
3980 }
3981 }
3982 if (NoCaptureAA)
3983 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3984
3985 // Check there is no other pointer argument which could alias with the
3986 // value passed at this call site.
3987 // TODO: AbstractCallSite
3988 const auto &CB = cast<CallBase>(getAnchorValue());
3989 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3990 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3991 return false;
3992
3993 return true;
3994 }
3995
3996 /// See AbstractAttribute::updateImpl(...).
3997 ChangeStatus updateImpl(Attributor &A) override {
3998 // If the argument is readnone we are done as there are no accesses via the
3999 // argument.
4000 auto *MemBehaviorAA =
4001 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4002 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4003 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4004 return ChangeStatus::UNCHANGED;
4005 }
4006
4007 bool IsKnownNoAlias;
4008 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4010 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4011 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4012 << " is not no-alias at the definition\n");
4013 return indicatePessimisticFixpoint();
4014 }
4015
4016 AAResults *AAR = nullptr;
4017 if (MemBehaviorAA &&
4018 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4019 LLVM_DEBUG(
4020 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4021 return ChangeStatus::UNCHANGED;
4022 }
4023
4024 return indicatePessimisticFixpoint();
4025 }
4026
4027 /// See AbstractAttribute::trackStatistics()
4028 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4029};
4030
4031/// NoAlias attribute for function return value.
4032struct AANoAliasReturned final : AANoAliasImpl {
4033 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4034 : AANoAliasImpl(IRP, A) {}
4035
4036 /// See AbstractAttribute::updateImpl(...).
4037 ChangeStatus updateImpl(Attributor &A) override {
4038
4039 auto CheckReturnValue = [&](Value &RV) -> bool {
4040 if (Constant *C = dyn_cast<Constant>(&RV))
4041 if (C->isNullValue() || isa<UndefValue>(C))
4042 return true;
4043
4044 /// For now, we can only deduce noalias if we have call sites.
4045 /// FIXME: add more support.
4046 if (!isa<CallBase>(&RV))
4047 return false;
4048
4049 const IRPosition &RVPos = IRPosition::value(RV);
4050 bool IsKnownNoAlias;
4052 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4053 return false;
4054
4055 bool IsKnownNoCapture;
4056 const AANoCapture *NoCaptureAA = nullptr;
4057 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4058 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4059 &NoCaptureAA);
4060 return IsAssumedNoCapture ||
4061 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4062 };
4063
4064 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4065 return indicatePessimisticFixpoint();
4066
4067 return ChangeStatus::UNCHANGED;
4068 }
4069
4070 /// See AbstractAttribute::trackStatistics()
4071 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4072};
4073
4074/// NoAlias attribute deduction for a call site return value.
4075struct AANoAliasCallSiteReturned final
4076 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4077 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4078 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4079
4080 /// See AbstractAttribute::trackStatistics()
4081 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4082};
4083} // namespace
4084
4085/// -------------------AAIsDead Function Attribute-----------------------
4086
4087namespace {
4088struct AAIsDeadValueImpl : public AAIsDead {
4089 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4090
4091 /// See AAIsDead::isAssumedDead().
4092 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4093
4094 /// See AAIsDead::isKnownDead().
4095 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4096
4097 /// See AAIsDead::isAssumedDead(BasicBlock *).
4098 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4099
4100 /// See AAIsDead::isKnownDead(BasicBlock *).
4101 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4102
4103 /// See AAIsDead::isAssumedDead(Instruction *I).
4104 bool isAssumedDead(const Instruction *I) const override {
4105 return I == getCtxI() && isAssumedDead();
4106 }
4107
4108 /// See AAIsDead::isKnownDead(Instruction *I).
4109 bool isKnownDead(const Instruction *I) const override {
4110 return isAssumedDead(I) && isKnownDead();
4111 }
4112
4113 /// See AbstractAttribute::getAsStr().
4114 const std::string getAsStr(Attributor *A) const override {
4115 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4116 }
4117
4118 /// Check if all uses are assumed dead.
4119 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4120 // Callers might not check the type, void has no uses.
4121 if (V.getType()->isVoidTy() || V.use_empty())
4122 return true;
4123
4124 // If we replace a value with a constant there are no uses left afterwards.
4125 if (!isa<Constant>(V)) {
4126 if (auto *I = dyn_cast<Instruction>(&V))
4127 if (!A.isRunOn(*I->getFunction()))
4128 return false;
4129 bool UsedAssumedInformation = false;
4130 std::optional<Constant *> C =
4131 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4132 if (!C || *C)
4133 return true;
4134 }
4135
4136 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4137 // Explicitly set the dependence class to required because we want a long
4138 // chain of N dependent instructions to be considered live as soon as one is
4139 // without going through N update cycles. This is not required for
4140 // correctness.
4141 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4142 DepClassTy::REQUIRED,
4143 /* IgnoreDroppableUses */ false);
4144 }
4145
4146 /// Determine if \p I is assumed to be side-effect free.
4147 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4149 return true;
4150
4151 auto *CB = dyn_cast<CallBase>(I);
4152 if (!CB || isa<IntrinsicInst>(CB))
4153 return false;
4154
4155 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4156
4157 bool IsKnownNoUnwind;
4159 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4160 return false;
4161
4162 bool IsKnown;
4163 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4164 }
4165};
4166
4167struct AAIsDeadFloating : public AAIsDeadValueImpl {
4168 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4169 : AAIsDeadValueImpl(IRP, A) {}
4170
4171 /// See AbstractAttribute::initialize(...).
4172 void initialize(Attributor &A) override {
4173 AAIsDeadValueImpl::initialize(A);
4174
4175 if (isa<UndefValue>(getAssociatedValue())) {
4176 indicatePessimisticFixpoint();
4177 return;
4178 }
4179
4180 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4181 if (!isAssumedSideEffectFree(A, I)) {
4183 indicatePessimisticFixpoint();
4184 else
4185 removeAssumedBits(HAS_NO_EFFECT);
4186 }
4187 }
4188
4189 bool isDeadFence(Attributor &A, FenceInst &FI) {
4190 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4191 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4192 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4193 return false;
4194 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4195 return true;
4196 }
4197
4198 bool isDeadStore(Attributor &A, StoreInst &SI,
4199 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4200 // Lang ref now states volatile store is not UB/dead, let's skip them.
4201 if (SI.isVolatile())
4202 return false;
4203
4204 // If we are collecting assumes to be deleted we are in the manifest stage.
4205 // It's problematic to collect the potential copies again now so we use the
4206 // cached ones.
4207 bool UsedAssumedInformation = false;
4208 if (!AssumeOnlyInst) {
4209 PotentialCopies.clear();
4210 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4211 UsedAssumedInformation)) {
4212 LLVM_DEBUG(
4213 dbgs()
4214 << "[AAIsDead] Could not determine potential copies of store!\n");
4215 return false;
4216 }
4217 }
4218 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4219 << " potential copies.\n");
4220
4221 InformationCache &InfoCache = A.getInfoCache();
4222 return llvm::all_of(PotentialCopies, [&](Value *V) {
4223 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4224 UsedAssumedInformation))
4225 return true;
4226 if (auto *LI = dyn_cast<LoadInst>(V)) {
4227 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4228 auto &UserI = cast<Instruction>(*U.getUser());
4229 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4230 if (AssumeOnlyInst)
4231 AssumeOnlyInst->insert(&UserI);
4232 return true;
4233 }
4234 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4235 })) {
4236 return true;
4237 }
4238 }
4239 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4240 << " is assumed live!\n");
4241 return false;
4242 });
4243 }
4244
4245 /// See AbstractAttribute::getAsStr().
4246 const std::string getAsStr(Attributor *A) const override {
4247 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4249 if (isValidState())
4250 return "assumed-dead-store";
4252 if (isValidState())
4253 return "assumed-dead-fence";
4254 return AAIsDeadValueImpl::getAsStr(A);
4255 }
4256
4257 /// See AbstractAttribute::updateImpl(...).
4258 ChangeStatus updateImpl(Attributor &A) override {
4259 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4260 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4261 if (!isDeadStore(A, *SI))
4262 return indicatePessimisticFixpoint();
4263 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4264 if (!isDeadFence(A, *FI))
4265 return indicatePessimisticFixpoint();
4266 } else {
4267 if (!isAssumedSideEffectFree(A, I))
4268 return indicatePessimisticFixpoint();
4269 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4270 return indicatePessimisticFixpoint();
4271 }
4273 }
4274
4275 bool isRemovableStore() const override {
4276 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4277 }
4278
4279 /// See AbstractAttribute::manifest(...).
4280 ChangeStatus manifest(Attributor &A) override {
4281 Value &V = getAssociatedValue();
4282 if (auto *I = dyn_cast<Instruction>(&V)) {
4283 // If we get here we basically know the users are all dead. We check if
4284 // isAssumedSideEffectFree returns true here again because it might not be
4285 // the case and only the users are dead but the instruction (=call) is
4286 // still needed.
4287 if (auto *SI = dyn_cast<StoreInst>(I)) {
4288 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4289 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4290 (void)IsDead;
4291 assert(IsDead && "Store was assumed to be dead!");
4292 A.deleteAfterManifest(*I);
4293 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4294 Instruction *AOI = AssumeOnlyInst[i];
4295 for (auto *Usr : AOI->users())
4296 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4297 A.deleteAfterManifest(*AOI);
4298 }
4299 return ChangeStatus::CHANGED;
4300 }
4301 if (auto *FI = dyn_cast<FenceInst>(I)) {
4302 assert(isDeadFence(A, *FI));
4303 A.deleteAfterManifest(*FI);
4304 return ChangeStatus::CHANGED;
4305 }
4306 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4307 A.deleteAfterManifest(*I);
4308 return ChangeStatus::CHANGED;
4309 }
4310 }
4312 }
4313
4314 /// See AbstractAttribute::trackStatistics()
4315 void trackStatistics() const override {
4317 }
4318
4319private:
4320 // The potential copies of a dead store, used for deletion during manifest.
4321 SmallSetVector<Value *, 4> PotentialCopies;
4322};
4323
4324struct AAIsDeadArgument : public AAIsDeadFloating {
4325 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4326 : AAIsDeadFloating(IRP, A) {}
4327
4328 /// See AbstractAttribute::manifest(...).
4329 ChangeStatus manifest(Attributor &A) override {
4330 Argument &Arg = *getAssociatedArgument();
4331 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4332 if (A.registerFunctionSignatureRewrite(
4333 Arg, /* ReplacementTypes */ {},
4336 return ChangeStatus::CHANGED;
4337 }
4338 return ChangeStatus::UNCHANGED;
4339 }
4340
4341 /// See AbstractAttribute::trackStatistics()
4342 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4343};
4344
4345struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4346 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4347 : AAIsDeadValueImpl(IRP, A) {}
4348
4349 /// See AbstractAttribute::initialize(...).
4350 void initialize(Attributor &A) override {
4351 AAIsDeadValueImpl::initialize(A);
4352 if (isa<UndefValue>(getAssociatedValue()))
4353 indicatePessimisticFixpoint();
4354 }
4355
4356 /// See AbstractAttribute::updateImpl(...).
4357 ChangeStatus updateImpl(Attributor &A) override {
4358 // TODO: Once we have call site specific value information we can provide
4359 // call site specific liveness information and then it makes
4360 // sense to specialize attributes for call sites arguments instead of
4361 // redirecting requests to the callee argument.
4362 Argument *Arg = getAssociatedArgument();
4363 if (!Arg)
4364 return indicatePessimisticFixpoint();
4365 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4366 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4367 if (!ArgAA)
4368 return indicatePessimisticFixpoint();
4369 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4370 }
4371
4372 /// See AbstractAttribute::manifest(...).
4373 ChangeStatus manifest(Attributor &A) override {
4374 CallBase &CB = cast<CallBase>(getAnchorValue());
4375 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4376 assert(!isa<UndefValue>(U.get()) &&
4377 "Expected undef values to be filtered out!");
4378 UndefValue &UV = *UndefValue::get(U->getType());
4379 if (A.changeUseAfterManifest(U, UV))
4380 return ChangeStatus::CHANGED;
4381 return ChangeStatus::UNCHANGED;
4382 }
4383
4384 /// See AbstractAttribute::trackStatistics()
4385 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4386};
4387
4388struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4389 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4390 : AAIsDeadFloating(IRP, A) {}
4391
4392 /// See AAIsDead::isAssumedDead().
4393 bool isAssumedDead() const override {
4394 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4395 }
4396
4397 /// See AbstractAttribute::initialize(...).
4398 void initialize(Attributor &A) override {
4399 AAIsDeadFloating::initialize(A);
4400 if (isa<UndefValue>(getAssociatedValue())) {
4401 indicatePessimisticFixpoint();
4402 return;
4403 }
4404
4405 // We track this separately as a secondary state.
4406 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4407 }
4408
4409 /// See AbstractAttribute::updateImpl(...).
4410 ChangeStatus updateImpl(Attributor &A) override {
4411 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4412 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4413 IsAssumedSideEffectFree = false;
4414 Changed = ChangeStatus::CHANGED;
4415 }
4416 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4417 return indicatePessimisticFixpoint();
4418 return Changed;
4419 }
4420
4421 /// See AbstractAttribute::trackStatistics()
4422 void trackStatistics() const override {
4423 if (IsAssumedSideEffectFree)
4425 else
4426 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4427 }
4428
4429 /// See AbstractAttribute::getAsStr().
4430 const std::string getAsStr(Attributor *A) const override {
4431 return isAssumedDead()
4432 ? "assumed-dead"
4433 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4434 }
4435
4436private:
4437 bool IsAssumedSideEffectFree = true;
4438};
4439
4440struct AAIsDeadReturned : public AAIsDeadValueImpl {
4441 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4442 : AAIsDeadValueImpl(IRP, A) {}
4443
4444 /// See AbstractAttribute::updateImpl(...).
4445 ChangeStatus updateImpl(Attributor &A) override {
4446
4447 bool UsedAssumedInformation = false;
4448 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4449 {Instruction::Ret}, UsedAssumedInformation);
4450
4451 auto PredForCallSite = [&](AbstractCallSite ACS) {
4452 if (ACS.isCallbackCall() || !ACS.getInstruction())
4453 return false;
4454 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4455 };
4456
4457 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4458 UsedAssumedInformation))
4459 return indicatePessimisticFixpoint();
4460
4461 return ChangeStatus::UNCHANGED;
4462 }
4463
4464 /// See AbstractAttribute::manifest(...).
4465 ChangeStatus manifest(Attributor &A) override {
4466 // TODO: Rewrite the signature to return void?
4467 bool AnyChange = false;
4468 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4469 auto RetInstPred = [&](Instruction &I) {
4470 ReturnInst &RI = cast<ReturnInst>(I);
4472 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4473 return true;
4474 };
4475 bool UsedAssumedInformation = false;
4476 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4477 UsedAssumedInformation);
4478 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4479 }
4480
4481 /// See AbstractAttribute::trackStatistics()
4482 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4483};
4484
4485struct AAIsDeadFunction : public AAIsDead {
4486 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4487
4488 /// See AbstractAttribute::initialize(...).
4489 void initialize(Attributor &A) override {
4490 Function *F = getAnchorScope();
4491 assert(F && "Did expect an anchor function");
4492 if (!isAssumedDeadInternalFunction(A)) {
4493 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4494 assumeLive(A, F->getEntryBlock());
4495 }
4496 }
4497
4498 bool isAssumedDeadInternalFunction(Attributor &A) {
4499 if (!getAnchorScope()->hasLocalLinkage())
4500 return false;
4501 bool UsedAssumedInformation = false;
4502 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4503 true, UsedAssumedInformation);
4504 }
4505
4506 /// See AbstractAttribute::getAsStr().
4507 const std::string getAsStr(Attributor *A) const override {
4508 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4509 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4510 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4511 std::to_string(KnownDeadEnds.size()) + "]";
4512 }
4513
4514 /// See AbstractAttribute::manifest(...).
4515 ChangeStatus manifest(Attributor &A) override {
4516 assert(getState().isValidState() &&
4517 "Attempted to manifest an invalid state!");
4518
4519 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4520 Function &F = *getAnchorScope();
4521
4522 if (AssumedLiveBlocks.empty()) {
4523 A.deleteAfterManifest(F);
4524 return ChangeStatus::CHANGED;
4525 }
4526
4527 // Flag to determine if we can change an invoke to a call assuming the
4528 // callee is nounwind. This is not possible if the personality of the
4529 // function allows to catch asynchronous exceptions.
4530 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4531
4532 KnownDeadEnds.set_union(ToBeExploredFrom);
4533 for (const Instruction *DeadEndI : KnownDeadEnds) {
4534 auto *CB = dyn_cast<CallBase>(DeadEndI);
4535 if (!CB)
4536 continue;
4537 bool IsKnownNoReturn;
4539 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4540 IsKnownNoReturn);
4541 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4542 continue;
4543
4544 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4545 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4546 else
4547 A.changeToUnreachableAfterManifest(
4548 const_cast<Instruction *>(DeadEndI->getNextNode()));
4549 HasChanged = ChangeStatus::CHANGED;
4550 }
4551
4552 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4553 for (BasicBlock &BB : F)
4554 if (!AssumedLiveBlocks.count(&BB)) {
4555 A.deleteAfterManifest(BB);
4556 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4557 HasChanged = ChangeStatus::CHANGED;
4558 }
4559
4560 return HasChanged;
4561 }
4562
4563 /// See AbstractAttribute::updateImpl(...).
4564 ChangeStatus updateImpl(Attributor &A) override;
4565
4566 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4567 assert(From->getParent() == getAnchorScope() &&
4568 To->getParent() == getAnchorScope() &&
4569 "Used AAIsDead of the wrong function");
4570 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4571 }
4572
4573 /// See AbstractAttribute::trackStatistics()
4574 void trackStatistics() const override {}
4575
4576 /// Returns true if the function is assumed dead.
4577 bool isAssumedDead() const override { return false; }
4578
4579 /// See AAIsDead::isKnownDead().
4580 bool isKnownDead() const override { return false; }
4581
4582 /// See AAIsDead::isAssumedDead(BasicBlock *).
4583 bool isAssumedDead(const BasicBlock *BB) const override {
4584 assert(BB->getParent() == getAnchorScope() &&
4585 "BB must be in the same anchor scope function.");
4586
4587 if (!getAssumed())
4588 return false;
4589 return !AssumedLiveBlocks.count(BB);
4590 }
4591
4592 /// See AAIsDead::isKnownDead(BasicBlock *).
4593 bool isKnownDead(const BasicBlock *BB) const override {
4594 return getKnown() && isAssumedDead(BB);
4595 }
4596
4597 /// See AAIsDead::isAssumed(Instruction *I).
4598 bool isAssumedDead(const Instruction *I) const override {
4599 assert(I->getParent()->getParent() == getAnchorScope() &&
4600 "Instruction must be in the same anchor scope function.");
4601
4602 if (!getAssumed())
4603 return false;
4604
4605 // If it is not in AssumedLiveBlocks then it for sure dead.
4606 // Otherwise, it can still be after noreturn call in a live block.
4607 if (!AssumedLiveBlocks.count(I->getParent()))
4608 return true;
4609
4610 // If it is not after a liveness barrier it is live.
4611 const Instruction *PrevI = I->getPrevNode();
4612 while (PrevI) {
4613 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4614 return true;
4615 PrevI = PrevI->getPrevNode();
4616 }
4617 return false;
4618 }
4619
4620 /// See AAIsDead::isKnownDead(Instruction *I).
4621 bool isKnownDead(const Instruction *I) const override {
4622 return getKnown() && isAssumedDead(I);
4623 }
4624
4625 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4626 /// that internal function called from \p BB should now be looked at.
4627 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4628 if (!AssumedLiveBlocks.insert(&BB).second)
4629 return false;
4630
4631 // We assume that all of BB is (probably) live now and if there are calls to
4632 // internal functions we will assume that those are now live as well. This
4633 // is a performance optimization for blocks with calls to a lot of internal
4634 // functions. It can however cause dead functions to be treated as live.
4635 for (const Instruction &I : BB)
4636 if (const auto *CB = dyn_cast<CallBase>(&I))
4638 if (F->hasLocalLinkage())
4639 A.markLiveInternalFunction(*F);
4640 return true;
4641 }
4642
4643 /// Collection of instructions that need to be explored again, e.g., we
4644 /// did assume they do not transfer control to (one of their) successors.
4645 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4646
4647 /// Collection of instructions that are known to not transfer control.
4648 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4649
4650 /// Collection of all assumed live edges
4651 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4652
4653 /// Collection of all assumed live BasicBlocks.
4654 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4655};
4656
4657static bool
4658identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4659 AbstractAttribute &AA,
4660 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4661 const IRPosition &IPos = IRPosition::callsite_function(CB);
4662
4663 bool IsKnownNoReturn;
4665 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4666 return !IsKnownNoReturn;
4667 if (CB.isTerminator())
4668 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4669 else
4670 AliveSuccessors.push_back(CB.getNextNode());
4671 return false;
4672}
4673
4674static bool
4675identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4676 AbstractAttribute &AA,
4677 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4678 bool UsedAssumedInformation =
4679 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4680
4681 // First, determine if we can change an invoke to a call assuming the
4682 // callee is nounwind. This is not possible if the personality of the
4683 // function allows to catch asynchronous exceptions.
4684 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4685 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4686 } else {
4687 const IRPosition &IPos = IRPosition::callsite_function(II);
4688
4689 bool IsKnownNoUnwind;
4691 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4692 UsedAssumedInformation |= !IsKnownNoUnwind;
4693 } else {
4694 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4695 }
4696 }
4697 return UsedAssumedInformation;
4698}
4699
4700static bool
4701identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4702 AbstractAttribute &AA,
4703 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4704 bool UsedAssumedInformation = false;
4705 if (BI.getNumSuccessors() == 1) {
4706 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4707 } else {
4708 std::optional<Constant *> C =
4709 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4710 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4711 // No value yet, assume both edges are dead.
4712 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4713 const BasicBlock *SuccBB =
4714 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4715 AliveSuccessors.push_back(&SuccBB->front());
4716 } else {
4717 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4718 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4719 UsedAssumedInformation = false;
4720 }
4721 }
4722 return UsedAssumedInformation;
4723}
4724
4725static bool
4726identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4727 AbstractAttribute &AA,
4728 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4729 bool UsedAssumedInformation = false;
4731 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4732 Values, AA::AnyScope,
4733 UsedAssumedInformation)) {
4734 // Something went wrong, assume all successors are live.
4735 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4736 AliveSuccessors.push_back(&SuccBB->front());
4737 return false;
4738 }
4739
4740 if (Values.empty() ||
4741 (Values.size() == 1 &&
4742 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4743 // No valid value yet, assume all edges are dead.
4744 return UsedAssumedInformation;
4745 }
4746
4747 Type &Ty = *SI.getCondition()->getType();
4748 SmallPtrSet<ConstantInt *, 8> Constants;
4749 auto CheckForConstantInt = [&](Value *V) {
4750 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4751 Constants.insert(CI);
4752 return true;
4753 }
4754 return false;
4755 };
4756
4757 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4758 return CheckForConstantInt(VAC.getValue());
4759 })) {
4760 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4761 AliveSuccessors.push_back(&SuccBB->front());
4762 return UsedAssumedInformation;
4763 }
4764
4765 unsigned MatchedCases = 0;
4766 for (const auto &CaseIt : SI.cases()) {
4767 if (Constants.count(CaseIt.getCaseValue())) {
4768 ++MatchedCases;
4769 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4770 }
4771 }
4772
4773 // If all potential values have been matched, we will not visit the default
4774 // case.
4775 if (MatchedCases < Constants.size())
4776 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4777 return UsedAssumedInformation;
4778}
4779
4780ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4782
4783 if (AssumedLiveBlocks.empty()) {
4784 if (isAssumedDeadInternalFunction(A))
4786
4787 Function *F = getAnchorScope();
4788 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4789 assumeLive(A, F->getEntryBlock());
4790 Change = ChangeStatus::CHANGED;
4791 }
4792
4793 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4794 << getAnchorScope()->size() << "] BBs and "
4795 << ToBeExploredFrom.size() << " exploration points and "
4796 << KnownDeadEnds.size() << " known dead ends\n");
4797
4798 // Copy and clear the list of instructions we need to explore from. It is
4799 // refilled with instructions the next update has to look at.
4800 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4801 ToBeExploredFrom.end());
4802 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4803
4805 while (!Worklist.empty()) {
4806 const Instruction *I = Worklist.pop_back_val();
4807 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4808
4809 // Fast forward for uninteresting instructions. We could look for UB here
4810 // though.
4811 while (!I->isTerminator() && !isa<CallBase>(I))
4812 I = I->getNextNode();
4813
4814 AliveSuccessors.clear();
4815
4816 bool UsedAssumedInformation = false;
4817 switch (I->getOpcode()) {
4818 // TODO: look for (assumed) UB to backwards propagate "deadness".
4819 default:
4820 assert(I->isTerminator() &&
4821 "Expected non-terminators to be handled already!");
4822 for (const BasicBlock *SuccBB : successors(I->getParent()))
4823 AliveSuccessors.push_back(&SuccBB->front());
4824 break;
4825 case Instruction::Call:
4826 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4827 *this, AliveSuccessors);
4828 break;
4829 case Instruction::Invoke:
4830 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4831 *this, AliveSuccessors);
4832 break;
4833 case Instruction::UncondBr:
4834 case Instruction::CondBr:
4835 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4836 *this, AliveSuccessors);
4837 break;
4838 case Instruction::Switch:
4839 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4840 *this, AliveSuccessors);
4841 break;
4842 }
4843
4844 if (UsedAssumedInformation) {
4845 NewToBeExploredFrom.insert(I);
4846 } else if (AliveSuccessors.empty() ||
4847 (I->isTerminator() &&
4848 AliveSuccessors.size() < I->getNumSuccessors())) {
4849 if (KnownDeadEnds.insert(I))
4850 Change = ChangeStatus::CHANGED;
4851 }
4852
4853 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4854 << AliveSuccessors.size() << " UsedAssumedInformation: "
4855 << UsedAssumedInformation << "\n");
4856
4857 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4858 if (!I->isTerminator()) {
4859 assert(AliveSuccessors.size() == 1 &&
4860 "Non-terminator expected to have a single successor!");
4861 Worklist.push_back(AliveSuccessor);
4862 } else {
4863 // record the assumed live edge
4864 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4865 if (AssumedLiveEdges.insert(Edge).second)
4866 Change = ChangeStatus::CHANGED;
4867 if (assumeLive(A, *AliveSuccessor->getParent()))
4868 Worklist.push_back(AliveSuccessor);
4869 }
4870 }
4871 }
4872
4873 // Check if the content of ToBeExploredFrom changed, ignore the order.
4874 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4875 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4876 return !ToBeExploredFrom.count(I);
4877 })) {
4878 Change = ChangeStatus::CHANGED;
4879 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4880 }
4881
4882 // If we know everything is live there is no need to query for liveness.
4883 // Instead, indicating a pessimistic fixpoint will cause the state to be
4884 // "invalid" and all queries to be answered conservatively without lookups.
4885 // To be in this state we have to (1) finished the exploration and (3) not
4886 // discovered any non-trivial dead end and (2) not ruled unreachable code
4887 // dead.
4888 if (ToBeExploredFrom.empty() &&
4889 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4890 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4891 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4892 }))
4893 return indicatePessimisticFixpoint();
4894 return Change;
4895}
4896
4897/// Liveness information for a call sites.
4898struct AAIsDeadCallSite final : AAIsDeadFunction {
4899 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4900 : AAIsDeadFunction(IRP, A) {}
4901
4902 /// See AbstractAttribute::initialize(...).
4903 void initialize(Attributor &A) override {
4904 // TODO: Once we have call site specific value information we can provide
4905 // call site specific liveness information and then it makes
4906 // sense to specialize attributes for call sites instead of
4907 // redirecting requests to the callee.
4908 llvm_unreachable("Abstract attributes for liveness are not "
4909 "supported for call sites yet!");
4910 }
4911
4912 /// See AbstractAttribute::updateImpl(...).
4913 ChangeStatus updateImpl(Attributor &A) override {
4914 return indicatePessimisticFixpoint();
4915 }
4916
4917 /// See AbstractAttribute::trackStatistics()
4918 void trackStatistics() const override {}
4919};
4920} // namespace
4921
4922/// -------------------- Dereferenceable Argument Attribute --------------------
4923
4924namespace {
4925struct AADereferenceableImpl : AADereferenceable {
4926 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4927 : AADereferenceable(IRP, A) {}
4928 using StateType = DerefState;
4929
4930 /// See AbstractAttribute::initialize(...).
4931 void initialize(Attributor &A) override {
4932 Value &V = *getAssociatedValue().stripPointerCasts();
4934 A.getAttrs(getIRPosition(),
4935 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4936 Attrs, /* IgnoreSubsumingPositions */ false);
4937 for (const Attribute &Attr : Attrs)
4938 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4939
4940 // Ensure we initialize the non-null AA (if necessary).
4941 bool IsKnownNonNull;
4943 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4944
4945 bool CanBeNull, CanBeFreed;
4946 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4947 A.getDataLayout(), CanBeNull, CanBeFreed));
4948
4949 if (Instruction *CtxI = getCtxI())
4950 followUsesInMBEC(*this, A, getState(), *CtxI);
4951 }
4952
4953 /// See AbstractAttribute::getState()
4954 /// {
4955 StateType &getState() override { return *this; }
4956 const StateType &getState() const override { return *this; }
4957 /// }
4958
4959 /// Helper function for collecting accessed bytes in must-be-executed-context
4960 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4961 DerefState &State) {
4962 const Value *UseV = U->get();
4963 if (!UseV->getType()->isPointerTy())
4964 return;
4965
4966 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4967 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4968 return;
4969
4970 int64_t Offset;
4972 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4973 if (Base && Base == &getAssociatedValue())
4974 State.addAccessedBytes(Offset, Loc->Size.getValue());
4975 }
4976
4977 /// See followUsesInMBEC
4978 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4979 AADereferenceable::StateType &State) {
4980 bool IsNonNull = false;
4981 bool TrackUse = false;
4982 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4983 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4984 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4985 << " for instruction " << *I << "\n");
4986
4987 addAccessedBytesForUse(A, U, I, State);
4988 State.takeKnownDerefBytesMaximum(DerefBytes);
4989 return TrackUse;
4990 }
4991
4992 /// See AbstractAttribute::manifest(...).
4993 ChangeStatus manifest(Attributor &A) override {
4994 ChangeStatus Change = AADereferenceable::manifest(A);
4995 bool IsKnownNonNull;
4996 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4997 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4998 if (IsAssumedNonNull &&
4999 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5000 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5001 return ChangeStatus::CHANGED;
5002 }
5003 return Change;
5004 }
5005
5006 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5007 SmallVectorImpl<Attribute> &Attrs) const override {
5008 // TODO: Add *_globally support
5009 bool IsKnownNonNull;
5010 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5011 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5012 if (IsAssumedNonNull)
5013 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5014 Ctx, getAssumedDereferenceableBytes()));
5015 else
5016 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5017 Ctx, getAssumedDereferenceableBytes()));
5018 }
5019
5020 /// See AbstractAttribute::getAsStr().
5021 const std::string getAsStr(Attributor *A) const override {
5022 if (!getAssumedDereferenceableBytes())
5023 return "unknown-dereferenceable";
5024 bool IsKnownNonNull;
5025 bool IsAssumedNonNull = false;
5026 if (A)
5028 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5029 return std::string("dereferenceable") +
5030 (IsAssumedNonNull ? "" : "_or_null") +
5031 (isAssumedGlobal() ? "_globally" : "") + "<" +
5032 std::to_string(getKnownDereferenceableBytes()) + "-" +
5033 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5034 (!A ? " [non-null is unknown]" : "");
5035 }
5036};
5037
5038/// Dereferenceable attribute for a floating value.
5039struct AADereferenceableFloating : AADereferenceableImpl {
5040 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5041 : AADereferenceableImpl(IRP, A) {}
5042
5043 /// See AbstractAttribute::updateImpl(...).
5044 ChangeStatus updateImpl(Attributor &A) override {
5045 bool Stripped;
5046 bool UsedAssumedInformation = false;
5048 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5049 AA::AnyScope, UsedAssumedInformation)) {
5050 Values.push_back({getAssociatedValue(), getCtxI()});
5051 Stripped = false;
5052 } else {
5053 Stripped = Values.size() != 1 ||
5054 Values.front().getValue() != &getAssociatedValue();
5055 }
5056
5057 const DataLayout &DL = A.getDataLayout();
5058 DerefState T;
5059
5060 auto VisitValueCB = [&](const Value &V) -> bool {
5061 unsigned IdxWidth =
5062 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5063 APInt Offset(IdxWidth, 0);
5065 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5066 /* AllowNonInbounds */ true);
5067
5068 const auto *AA = A.getAAFor<AADereferenceable>(
5069 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5070 int64_t DerefBytes = 0;
5071 if (!AA || (!Stripped && this == AA)) {
5072 // Use IR information if we did not strip anything.
5073 // TODO: track globally.
5074 bool CanBeNull, CanBeFreed;
5075 DerefBytes =
5076 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5077 T.GlobalState.indicatePessimisticFixpoint();
5078 } else {
5079 const DerefState &DS = AA->getState();
5080 DerefBytes = DS.DerefBytesState.getAssumed();
5081 T.GlobalState &= DS.GlobalState;
5082 }
5083
5084 // For now we do not try to "increase" dereferenceability due to negative
5085 // indices as we first have to come up with code to deal with loops and
5086 // for overflows of the dereferenceable bytes.
5087 int64_t OffsetSExt = Offset.getSExtValue();
5088 if (OffsetSExt < 0)
5089 OffsetSExt = 0;
5090
5091 T.takeAssumedDerefBytesMinimum(
5092 std::max(int64_t(0), DerefBytes - OffsetSExt));
5093
5094 if (this == AA) {
5095 if (!Stripped) {
5096 // If nothing was stripped IR information is all we got.
5097 T.takeKnownDerefBytesMaximum(
5098 std::max(int64_t(0), DerefBytes - OffsetSExt));
5099 T.indicatePessimisticFixpoint();
5100 } else if (OffsetSExt > 0) {
5101 // If something was stripped but there is circular reasoning we look
5102 // for the offset. If it is positive we basically decrease the
5103 // dereferenceable bytes in a circular loop now, which will simply
5104 // drive them down to the known value in a very slow way which we
5105 // can accelerate.
5106 T.indicatePessimisticFixpoint();
5107 }
5108 }
5109
5110 return T.isValidState();
5111 };
5112
5113 for (const auto &VAC : Values)
5114 if (!VisitValueCB(*VAC.getValue()))
5115 return indicatePessimisticFixpoint();
5116
5117 return clampStateAndIndicateChange(getState(), T);
5118 }
5119
5120 /// See AbstractAttribute::trackStatistics()
5121 void trackStatistics() const override {
5122 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5123 }
5124};
5125
5126/// Dereferenceable attribute for a return value.
5127struct AADereferenceableReturned final
5128 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5129 using Base =
5130 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5131 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5132 : Base(IRP, A) {}
5133
5134 /// See AbstractAttribute::trackStatistics()
5135 void trackStatistics() const override {
5136 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5137 }
5138};
5139
5140/// Dereferenceable attribute for an argument
5141struct AADereferenceableArgument final
5142 : AAArgumentFromCallSiteArguments<AADereferenceable,
5143 AADereferenceableImpl> {
5144 using Base =
5145 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5146 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5147 : Base(IRP, A) {}
5148
5149 /// See AbstractAttribute::trackStatistics()
5150 void trackStatistics() const override {
5151 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5152 }
5153};
5154
5155/// Dereferenceable attribute for a call site argument.
5156struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5157 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5158 : AADereferenceableFloating(IRP, A) {}
5159
5160 /// See AbstractAttribute::trackStatistics()
5161 void trackStatistics() const override {
5162 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5163 }
5164};
5165
5166/// Dereferenceable attribute deduction for a call site return value.
5167struct AADereferenceableCallSiteReturned final
5168 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5169 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5170 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5171 : Base(IRP, A) {}
5172
5173 /// See AbstractAttribute::trackStatistics()
5174 void trackStatistics() const override {
5175 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5176 }
5177};
5178} // namespace
5179
5180// ------------------------ Align Argument Attribute ------------------------
5181
5182namespace {
5183
5184static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5185 Value &AssociatedValue, const Use *U,
5186 const Instruction *I, bool &TrackUse) {
5187 // We need to follow common pointer manipulation uses to the accesses they
5188 // feed into.
5189 if (isa<CastInst>(I)) {
5190 // Follow all but ptr2int casts.
5191 TrackUse = !isa<PtrToIntInst>(I);
5192 return 0;
5193 }
5194 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5195 if (GEP->hasAllConstantIndices())
5196 TrackUse = true;
5197 return 0;
5198 }
5199 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5200 switch (II->getIntrinsicID()) {
5201 case Intrinsic::ptrmask: {
5202 // Is it appropriate to pull attribute in initialization?
5203 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5204 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5205 const auto *AlignAA = A.getAAFor<AAAlign>(
5206 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5207 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5208 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5210 Align ConstAlign(UINT64_C(1) << ShiftValue);
5211 if (ConstAlign >= AlignAA->getKnownAlign())
5212 return Align(1).value();
5213 }
5214 if (AlignAA)
5215 return AlignAA->getKnownAlign().value();
5216 break;
5217 }
5218 case Intrinsic::amdgcn_make_buffer_rsrc: {
5219 const auto *AlignAA = A.getAAFor<AAAlign>(
5220 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5221 if (AlignAA)
5222 return AlignAA->getKnownAlign().value();
5223 break;
5224 }
5225 default:
5226 break;
5227 }
5228
5229 MaybeAlign MA;
5230 if (const auto *CB = dyn_cast<CallBase>(I)) {
5231 if (CB->isBundleOperand(U) || CB->isCallee(U))
5232 return 0;
5233
5234 unsigned ArgNo = CB->getArgOperandNo(U);
5235 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5236 // As long as we only use known information there is no need to track
5237 // dependences here.
5238 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5239 if (AlignAA)
5240 MA = MaybeAlign(AlignAA->getKnownAlign());
5241 }
5242
5243 const DataLayout &DL = A.getDataLayout();
5244 const Value *UseV = U->get();
5245 if (auto *SI = dyn_cast<StoreInst>(I)) {
5246 if (SI->getPointerOperand() == UseV)
5247 MA = SI->getAlign();
5248 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5249 if (LI->getPointerOperand() == UseV)
5250 MA = LI->getAlign();
5251 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5252 if (AI->getPointerOperand() == UseV)
5253 MA = AI->getAlign();
5254 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5255 if (AI->getPointerOperand() == UseV)
5256 MA = AI->getAlign();
5257 }
5258
5259 if (!MA || *MA <= QueryingAA.getKnownAlign())
5260 return 0;
5261
5262 unsigned Alignment = MA->value();
5263 int64_t Offset;
5264
5265 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5266 if (Base == &AssociatedValue) {
5267 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5268 // So we can say that the maximum power of two which is a divisor of
5269 // gcd(Offset, Alignment) is an alignment.
5270
5271 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5272 Alignment = llvm::bit_floor(gcd);
5273 }
5274 }
5275
5276 return Alignment;
5277}
5278
5279struct AAAlignImpl : AAAlign {
5280 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5281
5282 /// See AbstractAttribute::initialize(...).
5283 void initialize(Attributor &A) override {
5285 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5286 for (const Attribute &Attr : Attrs)
5287 takeKnownMaximum(Attr.getValueAsInt());
5288
5289 Value &V = *getAssociatedValue().stripPointerCasts();
5290 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5291
5292 if (Instruction *CtxI = getCtxI())
5293 followUsesInMBEC(*this, A, getState(), *CtxI);
5294 }
5295
5296 /// See AbstractAttribute::manifest(...).
5297 ChangeStatus manifest(Attributor &A) override {
5298 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5299
5300 // Check for users that allow alignment annotations.
5301 Value &AssociatedValue = getAssociatedValue();
5302 if (isa<ConstantData>(AssociatedValue))
5303 return ChangeStatus::UNCHANGED;
5304
5305 for (const Use &U : AssociatedValue.uses()) {
5306 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5307 if (SI->getPointerOperand() == &AssociatedValue)
5308 if (SI->getAlign() < getAssumedAlign()) {
5309 STATS_DECLTRACK(AAAlign, Store,
5310 "Number of times alignment added to a store");
5311 SI->setAlignment(getAssumedAlign());
5312 InstrChanged = ChangeStatus::CHANGED;
5313 }
5314 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5315 if (LI->getPointerOperand() == &AssociatedValue)
5316 if (LI->getAlign() < getAssumedAlign()) {
5317 LI->setAlignment(getAssumedAlign());
5318 STATS_DECLTRACK(AAAlign, Load,
5319 "Number of times alignment added to a load");
5320 InstrChanged = ChangeStatus::CHANGED;
5321 }
5322 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5323 if (RMW->getPointerOperand() == &AssociatedValue) {
5324 if (RMW->getAlign() < getAssumedAlign()) {
5325 STATS_DECLTRACK(AAAlign, AtomicRMW,
5326 "Number of times alignment added to atomicrmw");
5327
5328 RMW->setAlignment(getAssumedAlign());
5329 InstrChanged = ChangeStatus::CHANGED;
5330 }
5331 }
5332 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5333 if (CAS->getPointerOperand() == &AssociatedValue) {
5334 if (CAS->getAlign() < getAssumedAlign()) {
5335 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5336 "Number of times alignment added to cmpxchg");
5337 CAS->setAlignment(getAssumedAlign());
5338 InstrChanged = ChangeStatus::CHANGED;
5339 }
5340 }
5341 }
5342 }
5343
5344 ChangeStatus Changed = AAAlign::manifest(A);
5345
5346 Align InheritAlign =
5347 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5348 if (InheritAlign >= getAssumedAlign())
5349 return InstrChanged;
5350 return Changed | InstrChanged;
5351 }
5352
5353 // TODO: Provide a helper to determine the implied ABI alignment and check in
5354 // the existing manifest method and a new one for AAAlignImpl that value
5355 // to avoid making the alignment explicit if it did not improve.
5356
5357 /// See AbstractAttribute::getDeducedAttributes
5358 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5359 SmallVectorImpl<Attribute> &Attrs) const override {
5360 if (getAssumedAlign() > 1)
5361 Attrs.emplace_back(
5362 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5363 }
5364
5365 /// See followUsesInMBEC
5366 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5367 AAAlign::StateType &State) {
5368 bool TrackUse = false;
5369
5370 unsigned int KnownAlign =
5371 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5372 State.takeKnownMaximum(KnownAlign);
5373
5374 return TrackUse;
5375 }
5376
5377 /// See AbstractAttribute::getAsStr().
5378 const std::string getAsStr(Attributor *A) const override {
5379 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5380 std::to_string(getAssumedAlign().value()) + ">";
5381 }
5382};
5383
5384/// Align attribute for a floating value.
5385struct AAAlignFloating : AAAlignImpl {
5386 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5387
5388 /// See AbstractAttribute::updateImpl(...).
5389 ChangeStatus updateImpl(Attributor &A) override {
5390 const DataLayout &DL = A.getDataLayout();
5391
5392 bool Stripped;
5393 bool UsedAssumedInformation = false;
5395 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5396 AA::AnyScope, UsedAssumedInformation)) {
5397 Values.push_back({getAssociatedValue(), getCtxI()});
5398 Stripped = false;
5399 } else {
5400 Stripped = Values.size() != 1 ||
5401 Values.front().getValue() != &getAssociatedValue();
5402 }
5403
5404 StateType T;
5405 auto VisitValueCB = [&](Value &V) -> bool {
5407 return true;
5408 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5409 DepClassTy::REQUIRED);
5410 if (!AA || (!Stripped && this == AA)) {
5411 int64_t Offset;
5412 unsigned Alignment = 1;
5413 if (const Value *Base =
5415 // TODO: Use AAAlign for the base too.
5416 Align PA = Base->getPointerAlignment(DL);
5417 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5418 // So we can say that the maximum power of two which is a divisor of
5419 // gcd(Offset, Alignment) is an alignment.
5420
5421 uint32_t gcd =
5422 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5423 Alignment = llvm::bit_floor(gcd);
5424 } else {
5425 Alignment = V.getPointerAlignment(DL).value();
5426 }
5427 // Use only IR information if we did not strip anything.
5428 T.takeKnownMaximum(Alignment);
5429 T.indicatePessimisticFixpoint();
5430 } else {
5431 // Use abstract attribute information.
5432 const AAAlign::StateType &DS = AA->getState();
5433 T ^= DS;
5434 }
5435 return T.isValidState();
5436 };
5437
5438 for (const auto &VAC : Values) {
5439 if (!VisitValueCB(*VAC.getValue()))
5440 return indicatePessimisticFixpoint();
5441 }
5442
5443 // TODO: If we know we visited all incoming values, thus no are assumed
5444 // dead, we can take the known information from the state T.
5445 return clampStateAndIndicateChange(getState(), T);
5446 }
5447
5448 /// See AbstractAttribute::trackStatistics()
5449 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5450};
5451
5452/// Align attribute for function return value.
5453struct AAAlignReturned final
5454 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5455 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5456 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5457
5458 /// See AbstractAttribute::trackStatistics()
5459 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5460};
5461
5462/// Align attribute for function argument.
5463struct AAAlignArgument final
5464 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5465 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5466 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5467
5468 /// See AbstractAttribute::manifest(...).
5469 ChangeStatus manifest(Attributor &A) override {
5470 // If the associated argument is involved in a must-tail call we give up
5471 // because we would need to keep the argument alignments of caller and
5472 // callee in-sync. Just does not seem worth the trouble right now.
5473 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5474 return ChangeStatus::UNCHANGED;
5475 return Base::manifest(A);
5476 }
5477
5478 /// See AbstractAttribute::trackStatistics()
5479 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5480};
5481
5482struct AAAlignCallSiteArgument final : AAAlignFloating {
5483 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5484 : AAAlignFloating(IRP, A) {}
5485
5486 /// See AbstractAttribute::manifest(...).
5487 ChangeStatus manifest(Attributor &A) override {
5488 // If the associated argument is involved in a must-tail call we give up
5489 // because we would need to keep the argument alignments of caller and
5490 // callee in-sync. Just does not seem worth the trouble right now.
5491 if (Argument *Arg = getAssociatedArgument())
5492 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5493 return ChangeStatus::UNCHANGED;
5494 ChangeStatus Changed = AAAlignImpl::manifest(A);
5495 Align InheritAlign =
5496 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5497 if (InheritAlign >= getAssumedAlign())
5498 Changed = ChangeStatus::UNCHANGED;
5499 return Changed;
5500 }
5501
5502 /// See AbstractAttribute::updateImpl(Attributor &A).
5503 ChangeStatus updateImpl(Attributor &A) override {
5504 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5505 if (Argument *Arg = getAssociatedArgument()) {
5506 // We only take known information from the argument
5507 // so we do not need to track a dependence.
5508 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5509 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5510 if (ArgAlignAA)
5511 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5512 }
5513 return Changed;
5514 }
5515
5516 /// See AbstractAttribute::trackStatistics()
5517 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5518};
5519
5520/// Align attribute deduction for a call site return value.
5521struct AAAlignCallSiteReturned final
5522 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5523 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5524 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5525 : Base(IRP, A) {}
5526
5527 ChangeStatus updateImpl(Attributor &A) override {
5528 Instruction *I = getIRPosition().getCtxI();
5529 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5530 switch (II->getIntrinsicID()) {
5531 case Intrinsic::ptrmask: {
5532 Align Alignment;
5533 bool Valid = false;
5534
5535 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5536 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5537 if (ConstVals && ConstVals->isValidState()) {
5538 unsigned ShiftValue =
5539 std::min(ConstVals->getAssumedMinTrailingZeros(),
5540 Value::MaxAlignmentExponent);
5541 Alignment = Align(UINT64_C(1) << ShiftValue);
5542 Valid = true;
5543 }
5544
5545 const auto *AlignAA =
5546 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5547 DepClassTy::REQUIRED);
5548 if (AlignAA) {
5549 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5550 Valid = true;
5551 }
5552
5553 if (Valid)
5555 this->getState(),
5556 std::min(this->getAssumedAlign(), Alignment).value());
5557 break;
5558 }
5559 // FIXME: Should introduce target specific sub-attributes and letting
5560 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5561 // specific intrinsics.
5562 case Intrinsic::amdgcn_make_buffer_rsrc: {
5563 const auto *AlignAA =
5564 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5565 DepClassTy::REQUIRED);
5566 if (AlignAA)
5568 this->getState(), AlignAA->getAssumedAlign().value());
5569 break;
5570 }
5571 default:
5572 break;
5573 }
5574 }
5575 return Base::updateImpl(A);
5576 };
5577 /// See AbstractAttribute::trackStatistics()
5578 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5579};
5580} // namespace
5581
5582/// ------------------ Function No-Return Attribute ----------------------------
5583namespace {
5584struct AANoReturnImpl : public AANoReturn {
5585 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5586
5587 /// See AbstractAttribute::initialize(...).
5588 void initialize(Attributor &A) override {
5589 bool IsKnown;
5591 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5592 (void)IsKnown;
5593 }
5594
5595 /// See AbstractAttribute::getAsStr().
5596 const std::string getAsStr(Attributor *A) const override {
5597 return getAssumed() ? "noreturn" : "may-return";
5598 }
5599
5600 /// See AbstractAttribute::updateImpl(Attributor &A).
5601 ChangeStatus updateImpl(Attributor &A) override {
5602 auto CheckForNoReturn = [](Instruction &) { return false; };
5603 bool UsedAssumedInformation = false;
5604 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5605 {(unsigned)Instruction::Ret},
5606 UsedAssumedInformation))
5607 return indicatePessimisticFixpoint();
5608 return ChangeStatus::UNCHANGED;
5609 }
5610};
5611
5612struct AANoReturnFunction final : AANoReturnImpl {
5613 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5614 : AANoReturnImpl(IRP, A) {}
5615
5616 /// See AbstractAttribute::trackStatistics()
5617 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5618};
5619
5620/// NoReturn attribute deduction for a call sites.
5621struct AANoReturnCallSite final
5622 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5623 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5624 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5625
5626 /// See AbstractAttribute::trackStatistics()
5627 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5628};
5629} // namespace
5630
5631/// ----------------------- Instance Info ---------------------------------
5632
5633namespace {
5634/// A class to hold the state of for no-capture attributes.
5635struct AAInstanceInfoImpl : public AAInstanceInfo {
5636 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5637 : AAInstanceInfo(IRP, A) {}
5638
5639 /// See AbstractAttribute::initialize(...).
5640 void initialize(Attributor &A) override {
5641 Value &V = getAssociatedValue();
5642 if (auto *C = dyn_cast<Constant>(&V)) {
5643 if (C->isThreadDependent())
5644 indicatePessimisticFixpoint();
5645 else
5646 indicateOptimisticFixpoint();
5647 return;
5648 }
5649 if (auto *CB = dyn_cast<CallBase>(&V))
5650 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5651 !CB->mayReadFromMemory()) {
5652 indicateOptimisticFixpoint();
5653 return;
5654 }
5655 if (auto *I = dyn_cast<Instruction>(&V)) {
5656 const auto *CI =
5657 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5658 *I->getFunction());
5659 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5660 indicatePessimisticFixpoint();
5661 return;
5662 }
5663 }
5664 }
5665
5666 /// See AbstractAttribute::updateImpl(...).
5667 ChangeStatus updateImpl(Attributor &A) override {
5668 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5669
5670 Value &V = getAssociatedValue();
5671 const Function *Scope = nullptr;
5672 if (auto *I = dyn_cast<Instruction>(&V))
5673 Scope = I->getFunction();
5674 if (auto *A = dyn_cast<Argument>(&V)) {
5675 Scope = A->getParent();
5676 if (!Scope->hasLocalLinkage())
5677 return Changed;
5678 }
5679 if (!Scope)
5680 return indicateOptimisticFixpoint();
5681
5682 bool IsKnownNoRecurse;
5684 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5685 IsKnownNoRecurse))
5686 return Changed;
5687
5688 auto UsePred = [&](const Use &U, bool &Follow) {
5689 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5690 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5691 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5692 Follow = true;
5693 return true;
5694 }
5695 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5696 (isa<StoreInst>(UserI) &&
5697 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5698 return true;
5699 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5700 // This check is not guaranteeing uniqueness but for now that we cannot
5701 // end up with two versions of \p U thinking it was one.
5703 if (!Callee || !Callee->hasLocalLinkage())
5704 return true;
5705 if (!CB->isArgOperand(&U))
5706 return false;
5707 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5709 DepClassTy::OPTIONAL);
5710 if (!ArgInstanceInfoAA ||
5711 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5712 return false;
5713 // If this call base might reach the scope again we might forward the
5714 // argument back here. This is very conservative.
5716 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5717 [Scope](const Function &Fn) { return &Fn != Scope; }))
5718 return false;
5719 return true;
5720 }
5721 return false;
5722 };
5723
5724 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5725 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5726 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5727 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5728 AA::isDynamicallyUnique(A, *this, *Ptr))
5729 return true;
5730 }
5731 return false;
5732 };
5733
5734 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5735 DepClassTy::OPTIONAL,
5736 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5737 return indicatePessimisticFixpoint();
5738
5739 return Changed;
5740 }
5741
5742 /// See AbstractState::getAsStr().
5743 const std::string getAsStr(Attributor *A) const override {
5744 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5745 }
5746
5747 /// See AbstractAttribute::trackStatistics()
5748 void trackStatistics() const override {}
5749};
5750
5751/// InstanceInfo attribute for floating values.
5752struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5753 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5754 : AAInstanceInfoImpl(IRP, A) {}
5755};
5756
5757/// NoCapture attribute for function arguments.
5758struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5759 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5760 : AAInstanceInfoFloating(IRP, A) {}
5761};
5762
5763/// InstanceInfo attribute for call site arguments.
5764struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5765 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5766 : AAInstanceInfoImpl(IRP, A) {}
5767
5768 /// See AbstractAttribute::updateImpl(...).
5769 ChangeStatus updateImpl(Attributor &A) override {
5770 // TODO: Once we have call site specific value information we can provide
5771 // call site specific liveness information and then it makes
5772 // sense to specialize attributes for call sites arguments instead of
5773 // redirecting requests to the callee argument.
5774 Argument *Arg = getAssociatedArgument();
5775 if (!Arg)
5776 return indicatePessimisticFixpoint();
5777 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5778 auto *ArgAA =
5779 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5780 if (!ArgAA)
5781 return indicatePessimisticFixpoint();
5782 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5783 }
5784};
5785
5786/// InstanceInfo attribute for function return value.
5787struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5788 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5789 : AAInstanceInfoImpl(IRP, A) {
5790 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5791 }
5792
5793 /// See AbstractAttribute::initialize(...).
5794 void initialize(Attributor &A) override {
5795 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5796 }
5797
5798 /// See AbstractAttribute::updateImpl(...).
5799 ChangeStatus updateImpl(Attributor &A) override {
5800 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5801 }
5802};
5803
5804/// InstanceInfo attribute deduction for a call site return value.
5805struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5806 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5807 : AAInstanceInfoFloating(IRP, A) {}
5808};
5809} // namespace
5810
5811/// ----------------------- Variable Capturing ---------------------------------
5813 Attribute::AttrKind ImpliedAttributeKind,
5814 bool IgnoreSubsumingPositions) {
5815 assert(ImpliedAttributeKind == Attribute::Captures &&
5816 "Unexpected attribute kind");
5817 Value &V = IRP.getAssociatedValue();
5818 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5819 return V.use_empty();
5820
5821 // You cannot "capture" null in the default address space.
5822 //
5823 // FIXME: This should use NullPointerIsDefined to account for the function
5824 // attribute.
5826 V.getType()->getPointerAddressSpace() == 0)) {
5827 return true;
5828 }
5829
5831 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5832 /* IgnoreSubsumingPositions */ true);
5833 for (const Attribute &Attr : Attrs)
5834 if (capturesNothing(Attr.getCaptureInfo()))
5835 return true;
5836
5838 if (Argument *Arg = IRP.getAssociatedArgument()) {
5840 A.getAttrs(IRPosition::argument(*Arg),
5841 {Attribute::Captures, Attribute::ByVal}, Attrs,
5842 /* IgnoreSubsumingPositions */ true);
5843 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5844 return Attr.getKindAsEnum() == Attribute::ByVal ||
5846 });
5847 if (ArgNoCapture) {
5848 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5849 V.getContext(), CaptureInfo::none()));
5850 return true;
5851 }
5852 }
5853
5854 if (const Function *F = IRP.getAssociatedFunction()) {
5855 // Check what state the associated function can actually capture.
5858 if (State.isKnown(NO_CAPTURE)) {
5859 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5861 return true;
5862 }
5863 }
5864
5865 return false;
5866}
5867
5868/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5869/// depending on the ability of the function associated with \p IRP to capture
5870/// state in memory and through "returning/throwing", respectively.
5872 const Function &F,
5873 BitIntegerState &State) {
5874 // TODO: Once we have memory behavior attributes we should use them here.
5875
5876 // If we know we cannot communicate or write to memory, we do not care about
5877 // ptr2int anymore.
5878 bool ReadOnly = F.onlyReadsMemory();
5879 bool NoThrow = F.doesNotThrow();
5880 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5881 if (ReadOnly && NoThrow && IsVoidReturn) {
5882 State.addKnownBits(NO_CAPTURE);
5883 return;
5884 }
5885
5886 // A function cannot capture state in memory if it only reads memory, it can
5887 // however return/throw state and the state might be influenced by the
5888 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5889 if (ReadOnly)
5890 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5891
5892 // A function cannot communicate state back if it does not through
5893 // exceptions and doesn not return values.
5894 if (NoThrow && IsVoidReturn)
5895 State.addKnownBits(NOT_CAPTURED_IN_RET);
5896
5897 // Check existing "returned" attributes.
5898 int ArgNo = IRP.getCalleeArgNo();
5899 if (!NoThrow || ArgNo < 0 ||
5900 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5901 return;
5902
5903 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5904 if (F.hasParamAttribute(U, Attribute::Returned)) {
5905 if (U == unsigned(ArgNo))
5906 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5907 else if (ReadOnly)
5908 State.addKnownBits(NO_CAPTURE);
5909 else
5910 State.addKnownBits(NOT_CAPTURED_IN_RET);
5911 break;
5912 }
5913}
5914
5915namespace {
5916/// A class to hold the state of for no-capture attributes.
5917struct AANoCaptureImpl : public AANoCapture {
5918 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5919
5920 /// See AbstractAttribute::initialize(...).
5921 void initialize(Attributor &A) override {
5922 bool IsKnown;
5924 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5925 (void)IsKnown;
5926 }
5927
5928 /// See AbstractAttribute::updateImpl(...).
5929 ChangeStatus updateImpl(Attributor &A) override;
5930
5931 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5932 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5933 SmallVectorImpl<Attribute> &Attrs) const override {
5934 if (!isAssumedNoCaptureMaybeReturned())
5935 return;
5936
5937 if (isArgumentPosition()) {
5938 if (isAssumedNoCapture())
5939 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5940 else if (ManifestInternal)
5941 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5942 }
5943 }
5944
5945 /// See AbstractState::getAsStr().
5946 const std::string getAsStr(Attributor *A) const override {
5947 if (isKnownNoCapture())
5948 return "known not-captured";
5949 if (isAssumedNoCapture())
5950 return "assumed not-captured";
5951 if (isKnownNoCaptureMaybeReturned())
5952 return "known not-captured-maybe-returned";
5953 if (isAssumedNoCaptureMaybeReturned())
5954 return "assumed not-captured-maybe-returned";
5955 return "assumed-captured";
5956 }
5957
5958 /// Check the use \p U and update \p State accordingly. Return true if we
5959 /// should continue to update the state.
5960 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5961 bool &Follow) {
5962 Instruction *UInst = cast<Instruction>(U.getUser());
5963 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5964 << *UInst << "\n");
5965
5966 // Deal with ptr2int by following uses.
5967 if (isa<PtrToIntInst>(UInst)) {
5968 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5969 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5970 /* Return */ true);
5971 }
5972
5973 // For stores we already checked if we can follow them, if they make it
5974 // here we give up.
5975 if (isa<StoreInst>(UInst))
5976 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5977 /* Return */ true);
5978
5979 // Explicitly catch return instructions.
5980 if (isa<ReturnInst>(UInst)) {
5981 if (UInst->getFunction() == getAnchorScope())
5982 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5983 /* Return */ true);
5984 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5985 /* Return */ true);
5986 }
5987
5988 // For now we only use special logic for call sites. However, the tracker
5989 // itself knows about a lot of other non-capturing cases already.
5990 auto *CB = dyn_cast<CallBase>(UInst);
5991 if (!CB || !CB->isArgOperand(&U))
5992 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5993 /* Return */ true);
5994
5995 unsigned ArgNo = CB->getArgOperandNo(&U);
5996 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5997 // If we have a abstract no-capture attribute for the argument we can use
5998 // it to justify a non-capture attribute here. This allows recursion!
5999 bool IsKnownNoCapture;
6000 const AANoCapture *ArgNoCaptureAA = nullptr;
6001 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6002 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6003 &ArgNoCaptureAA);
6004 if (IsAssumedNoCapture)
6005 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6006 /* Return */ false);
6007 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6008 Follow = true;
6009 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6010 /* Return */ false);
6011 }
6012
6013 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6014 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6015 /* Return */ true);
6016 }
6017
6018 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6019 /// \p CapturedInRet, then return true if we should continue updating the
6020 /// state.
6021 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6022 bool CapturedInInt, bool CapturedInRet) {
6023 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6024 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6025 if (CapturedInMem)
6026 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6027 if (CapturedInInt)
6028 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6029 if (CapturedInRet)
6030 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6031 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6032 }
6033};
6034
6035ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6036 const IRPosition &IRP = getIRPosition();
6037 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6038 : &IRP.getAssociatedValue();
6039 if (!V)
6040 return indicatePessimisticFixpoint();
6041
6042 const Function *F =
6043 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6044
6045 // TODO: Is the checkForAllUses below useful for constants?
6046 if (!F)
6047 return indicatePessimisticFixpoint();
6048
6050 const IRPosition &FnPos = IRPosition::function(*F);
6051
6052 // Readonly means we cannot capture through memory.
6053 bool IsKnown;
6054 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6055 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6056 if (IsKnown)
6057 addKnownBits(NOT_CAPTURED_IN_MEM);
6058 }
6059
6060 // Make sure all returned values are different than the underlying value.
6061 // TODO: we could do this in a more sophisticated way inside
6062 // AAReturnedValues, e.g., track all values that escape through returns
6063 // directly somehow.
6064 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6066 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6068 UsedAssumedInformation))
6069 return false;
6070 bool SeenConstant = false;
6071 for (const AA::ValueAndContext &VAC : Values) {
6072 if (isa<Constant>(VAC.getValue())) {
6073 if (SeenConstant)
6074 return false;
6075 SeenConstant = true;
6076 } else if (!isa<Argument>(VAC.getValue()) ||
6077 VAC.getValue() == getAssociatedArgument())
6078 return false;
6079 }
6080 return true;
6081 };
6082
6083 bool IsKnownNoUnwind;
6085 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6086 bool IsVoidTy = F->getReturnType()->isVoidTy();
6087 bool UsedAssumedInformation = false;
6088 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6089 T.addKnownBits(NOT_CAPTURED_IN_RET);
6090 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6092 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6093 addKnownBits(NOT_CAPTURED_IN_RET);
6094 if (isKnown(NOT_CAPTURED_IN_MEM))
6095 return indicateOptimisticFixpoint();
6096 }
6097 }
6098 }
6099
6100 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6101 // TODO(captures): Make this more precise.
6102 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6103 if (capturesNothing(CI))
6104 return true;
6105 if (CI.isPassthrough()) {
6106 Follow = true;
6107 return true;
6108 }
6109 return checkUse(A, T, U, Follow);
6110 };
6111
6112 if (!A.checkForAllUses(UseCheck, *this, *V))
6113 return indicatePessimisticFixpoint();
6114
6115 AANoCapture::StateType &S = getState();
6116 auto Assumed = S.getAssumed();
6117 S.intersectAssumedBits(T.getAssumed());
6118 if (!isAssumedNoCaptureMaybeReturned())
6119 return indicatePessimisticFixpoint();
6120 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6122}
6123
6124/// NoCapture attribute for function arguments.
6125struct AANoCaptureArgument final : AANoCaptureImpl {
6126 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6127 : AANoCaptureImpl(IRP, A) {}
6128
6129 /// See AbstractAttribute::trackStatistics()
6130 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6131};
6132
6133/// NoCapture attribute for call site arguments.
6134struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6135 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6136 : AANoCaptureImpl(IRP, A) {}
6137
6138 /// See AbstractAttribute::updateImpl(...).
6139 ChangeStatus updateImpl(Attributor &A) override {
6140 // TODO: Once we have call site specific value information we can provide
6141 // call site specific liveness information and then it makes
6142 // sense to specialize attributes for call sites arguments instead of
6143 // redirecting requests to the callee argument.
6144 Argument *Arg = getAssociatedArgument();
6145 if (!Arg)
6146 return indicatePessimisticFixpoint();
6147 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6148 bool IsKnownNoCapture;
6149 const AANoCapture *ArgAA = nullptr;
6151 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6152 &ArgAA))
6153 return ChangeStatus::UNCHANGED;
6154 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6155 return indicatePessimisticFixpoint();
6156 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6157 }
6158
6159 /// See AbstractAttribute::trackStatistics()
6160 void trackStatistics() const override {
6162 };
6163};
6164
6165/// NoCapture attribute for floating values.
6166struct AANoCaptureFloating final : AANoCaptureImpl {
6167 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6168 : AANoCaptureImpl(IRP, A) {}
6169
6170 /// See AbstractAttribute::trackStatistics()
6171 void trackStatistics() const override {
6173 }
6174};
6175
6176/// NoCapture attribute for function return value.
6177struct AANoCaptureReturned final : AANoCaptureImpl {
6178 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6179 : AANoCaptureImpl(IRP, A) {
6180 llvm_unreachable("NoCapture is not applicable to function returns!");
6181 }
6182
6183 /// See AbstractAttribute::initialize(...).
6184 void initialize(Attributor &A) override {
6185 llvm_unreachable("NoCapture is not applicable to function returns!");
6186 }
6187
6188 /// See AbstractAttribute::updateImpl(...).
6189 ChangeStatus updateImpl(Attributor &A) override {
6190 llvm_unreachable("NoCapture is not applicable to function returns!");
6191 }
6192
6193 /// See AbstractAttribute::trackStatistics()
6194 void trackStatistics() const override {}
6195};
6196
6197/// NoCapture attribute deduction for a call site return value.
6198struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6199 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6200 : AANoCaptureImpl(IRP, A) {}
6201
6202 /// See AbstractAttribute::initialize(...).
6203 void initialize(Attributor &A) override {
6204 const Function *F = getAnchorScope();
6205 // Check what state the associated function can actually capture.
6206 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6207 }
6208
6209 /// See AbstractAttribute::trackStatistics()
6210 void trackStatistics() const override {
6212 }
6213};
6214} // namespace
6215
6216/// ------------------ Value Simplify Attribute ----------------------------
6217
6218bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6219 // FIXME: Add a typecast support.
6222 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6223 return false;
6224
6225 LLVM_DEBUG({
6227 dbgs() << "[ValueSimplify] is assumed to be "
6228 << **SimplifiedAssociatedValue << "\n";
6229 else
6230 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6231 });
6232 return true;
6233}
6234
6235namespace {
6236struct AAValueSimplifyImpl : AAValueSimplify {
6237 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6238 : AAValueSimplify(IRP, A) {}
6239
6240 /// See AbstractAttribute::initialize(...).
6241 void initialize(Attributor &A) override {
6242 if (getAssociatedValue().getType()->isVoidTy())
6243 indicatePessimisticFixpoint();
6244 if (A.hasSimplificationCallback(getIRPosition()))
6245 indicatePessimisticFixpoint();
6246 }
6247
6248 /// See AbstractAttribute::getAsStr().
6249 const std::string getAsStr(Attributor *A) const override {
6250 LLVM_DEBUG({
6251 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6252 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6253 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6254 });
6255 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6256 : "not-simple";
6257 }
6258
6259 /// See AbstractAttribute::trackStatistics()
6260 void trackStatistics() const override {}
6261
6262 /// See AAValueSimplify::getAssumedSimplifiedValue()
6263 std::optional<Value *>
6264 getAssumedSimplifiedValue(Attributor &A) const override {
6265 return SimplifiedAssociatedValue;
6266 }
6267
6268 /// Ensure the return value is \p V with type \p Ty, if not possible return
6269 /// nullptr. If \p Check is true we will only verify such an operation would
6270 /// suceed and return a non-nullptr value if that is the case. No IR is
6271 /// generated or modified.
6272 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6273 bool Check) {
6274 if (auto *TypedV = AA::getWithType(V, Ty))
6275 return TypedV;
6276 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6277 return Check ? &V
6278 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6279 &V, &Ty, "", CtxI->getIterator());
6280 return nullptr;
6281 }
6282
6283 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6284 /// If \p Check is true we will only verify such an operation would suceed and
6285 /// return a non-nullptr value if that is the case. No IR is generated or
6286 /// modified.
6287 static Value *reproduceInst(Attributor &A,
6288 const AbstractAttribute &QueryingAA,
6289 Instruction &I, Type &Ty, Instruction *CtxI,
6290 bool Check, ValueToValueMapTy &VMap) {
6291 assert(CtxI && "Cannot reproduce an instruction without context!");
6292 if (Check && (I.mayReadFromMemory() ||
6293 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6294 /* TLI */ nullptr)))
6295 return nullptr;
6296 for (Value *Op : I.operands()) {
6297 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6298 if (!NewOp) {
6299 assert(Check && "Manifest of new value unexpectedly failed!");
6300 return nullptr;
6301 }
6302 if (!Check)
6303 VMap[Op] = NewOp;
6304 }
6305 if (Check)
6306 return &I;
6307
6308 Instruction *CloneI = I.clone();
6309 // TODO: Try to salvage debug information here.
6310 CloneI->setDebugLoc(DebugLoc());
6311 VMap[&I] = CloneI;
6312 CloneI->insertBefore(CtxI->getIterator());
6313 RemapInstruction(CloneI, VMap);
6314 return CloneI;
6315 }
6316
6317 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6318 /// If \p Check is true we will only verify such an operation would suceed and
6319 /// return a non-nullptr value if that is the case. No IR is generated or
6320 /// modified.
6321 static Value *reproduceValue(Attributor &A,
6322 const AbstractAttribute &QueryingAA, Value &V,
6323 Type &Ty, Instruction *CtxI, bool Check,
6324 ValueToValueMapTy &VMap) {
6325 if (const auto &NewV = VMap.lookup(&V))
6326 return NewV;
6327 bool UsedAssumedInformation = false;
6328 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6329 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6330 if (!SimpleV.has_value())
6331 return PoisonValue::get(&Ty);
6332 Value *EffectiveV = &V;
6333 if (*SimpleV)
6334 EffectiveV = *SimpleV;
6335 if (auto *C = dyn_cast<Constant>(EffectiveV))
6336 return C;
6337 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6338 A.getInfoCache()))
6339 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6340 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6341 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6342 return ensureType(A, *NewV, Ty, CtxI, Check);
6343 return nullptr;
6344 }
6345
6346 /// Return a value we can use as replacement for the associated one, or
6347 /// nullptr if we don't have one that makes sense.
6348 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6349 Value *NewV = SimplifiedAssociatedValue
6350 ? *SimplifiedAssociatedValue
6351 : UndefValue::get(getAssociatedType());
6352 if (NewV && NewV != &getAssociatedValue()) {
6353 ValueToValueMapTy VMap;
6354 // First verify we can reprduce the value with the required type at the
6355 // context location before we actually start modifying the IR.
6356 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6357 /* CheckOnly */ true, VMap))
6358 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6359 /* CheckOnly */ false, VMap);
6360 }
6361 return nullptr;
6362 }
6363
6364 /// Helper function for querying AAValueSimplify and updating candidate.
6365 /// \param IRP The value position we are trying to unify with SimplifiedValue
6366 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6367 const IRPosition &IRP, bool Simplify = true) {
6368 bool UsedAssumedInformation = false;
6369 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6370 if (Simplify)
6371 QueryingValueSimplified = A.getAssumedSimplified(
6372 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6373 return unionAssumed(QueryingValueSimplified);
6374 }
6375
6376 /// Returns a candidate is found or not
6377 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6378 if (!getAssociatedValue().getType()->isIntegerTy())
6379 return false;
6380
6381 // This will also pass the call base context.
6382 const auto *AA =
6383 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6384 if (!AA)
6385 return false;
6386
6387 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6388
6389 if (!COpt) {
6390 SimplifiedAssociatedValue = std::nullopt;
6391 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6392 return true;
6393 }
6394 if (auto *C = *COpt) {
6395 SimplifiedAssociatedValue = C;
6396 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6397 return true;
6398 }
6399 return false;
6400 }
6401
6402 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6403 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6404 return true;
6405 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6406 return true;
6407 return false;
6408 }
6409
6410 /// See AbstractAttribute::manifest(...).
6411 ChangeStatus manifest(Attributor &A) override {
6412 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6413 for (auto &U : getAssociatedValue().uses()) {
6414 // Check if we need to adjust the insertion point to make sure the IR is
6415 // valid.
6416 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6417 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6418 IP = PHI->getIncomingBlock(U)->getTerminator();
6419 if (auto *NewV = manifestReplacementValue(A, IP)) {
6420 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6421 << " -> " << *NewV << " :: " << *this << "\n");
6422 if (A.changeUseAfterManifest(U, *NewV))
6423 Changed = ChangeStatus::CHANGED;
6424 }
6425 }
6426
6427 return Changed | AAValueSimplify::manifest(A);
6428 }
6429
6430 /// See AbstractState::indicatePessimisticFixpoint(...).
6431 ChangeStatus indicatePessimisticFixpoint() override {
6432 SimplifiedAssociatedValue = &getAssociatedValue();
6433 return AAValueSimplify::indicatePessimisticFixpoint();
6434 }
6435};
6436
6437struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6438 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6439 : AAValueSimplifyImpl(IRP, A) {}
6440
6441 void initialize(Attributor &A) override {
6442 AAValueSimplifyImpl::initialize(A);
6443 if (A.hasAttr(getIRPosition(),
6444 {Attribute::InAlloca, Attribute::Preallocated,
6445 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6446 /* IgnoreSubsumingPositions */ true))
6447 indicatePessimisticFixpoint();
6448 }
6449
6450 /// See AbstractAttribute::updateImpl(...).
6451 ChangeStatus updateImpl(Attributor &A) override {
6452 // Byval is only replacable if it is readonly otherwise we would write into
6453 // the replaced value and not the copy that byval creates implicitly.
6454 Argument *Arg = getAssociatedArgument();
6455 if (Arg->hasByValAttr()) {
6456 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6457 // there is no race by not copying a constant byval.
6458 bool IsKnown;
6459 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6460 return indicatePessimisticFixpoint();
6461 }
6462
6463 auto Before = SimplifiedAssociatedValue;
6464
6465 auto PredForCallSite = [&](AbstractCallSite ACS) {
6466 const IRPosition &ACSArgPos =
6467 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6468 // Check if a coresponding argument was found or if it is on not
6469 // associated (which can happen for callback calls).
6470 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6471 return false;
6472
6473 // Simplify the argument operand explicitly and check if the result is
6474 // valid in the current scope. This avoids refering to simplified values
6475 // in other functions, e.g., we don't want to say a an argument in a
6476 // static function is actually an argument in a different function.
6477 bool UsedAssumedInformation = false;
6478 std::optional<Constant *> SimpleArgOp =
6479 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6480 if (!SimpleArgOp)
6481 return true;
6482 if (!*SimpleArgOp)
6483 return false;
6484 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6485 return false;
6486 return unionAssumed(*SimpleArgOp);
6487 };
6488
6489 // Generate a answer specific to a call site context.
6490 bool Success;
6491 bool UsedAssumedInformation = false;
6492 if (hasCallBaseContext() &&
6493 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6494 Success = PredForCallSite(
6495 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6496 else
6497 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6498 UsedAssumedInformation);
6499
6500 if (!Success)
6501 if (!askSimplifiedValueForOtherAAs(A))
6502 return indicatePessimisticFixpoint();
6503
6504 // If a candidate was found in this update, return CHANGED.
6505 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6506 : ChangeStatus ::CHANGED;
6507 }
6508
6509 /// See AbstractAttribute::trackStatistics()
6510 void trackStatistics() const override {
6511 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6512 }
6513};
6514
6515struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6516 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6517 : AAValueSimplifyImpl(IRP, A) {}
6518
6519 /// See AAValueSimplify::getAssumedSimplifiedValue()
6520 std::optional<Value *>
6521 getAssumedSimplifiedValue(Attributor &A) const override {
6522 if (!isValidState())
6523 return nullptr;
6524 return SimplifiedAssociatedValue;
6525 }
6526
6527 /// See AbstractAttribute::updateImpl(...).
6528 ChangeStatus updateImpl(Attributor &A) override {
6529 auto Before = SimplifiedAssociatedValue;
6530
6531 auto ReturnInstCB = [&](Instruction &I) {
6532 auto &RI = cast<ReturnInst>(I);
6533 return checkAndUpdate(
6534 A, *this,
6535 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6536 };
6537
6538 bool UsedAssumedInformation = false;
6539 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6540 UsedAssumedInformation))
6541 if (!askSimplifiedValueForOtherAAs(A))
6542 return indicatePessimisticFixpoint();
6543
6544 // If a candidate was found in this update, return CHANGED.
6545 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6546 : ChangeStatus ::CHANGED;
6547 }
6548
6549 ChangeStatus manifest(Attributor &A) override {
6550 // We queried AAValueSimplify for the returned values so they will be
6551 // replaced if a simplified form was found. Nothing to do here.
6552 return ChangeStatus::UNCHANGED;
6553 }
6554
6555 /// See AbstractAttribute::trackStatistics()
6556 void trackStatistics() const override {
6557 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6558 }
6559};
6560
6561struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6562 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6563 : AAValueSimplifyImpl(IRP, A) {}
6564
6565 /// See AbstractAttribute::initialize(...).
6566 void initialize(Attributor &A) override {
6567 AAValueSimplifyImpl::initialize(A);
6568 Value &V = getAnchorValue();
6569
6570 // TODO: add other stuffs
6571 if (isa<Constant>(V))
6572 indicatePessimisticFixpoint();
6573 }
6574
6575 /// See AbstractAttribute::updateImpl(...).
6576 ChangeStatus updateImpl(Attributor &A) override {
6577 auto Before = SimplifiedAssociatedValue;
6578 if (!askSimplifiedValueForOtherAAs(A))
6579 return indicatePessimisticFixpoint();
6580
6581 // If a candidate was found in this update, return CHANGED.
6582 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6583 : ChangeStatus ::CHANGED;
6584 }
6585
6586 /// See AbstractAttribute::trackStatistics()
6587 void trackStatistics() const override {
6588 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6589 }
6590};
6591
6592struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6593 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6594 : AAValueSimplifyImpl(IRP, A) {}
6595
6596 /// See AbstractAttribute::initialize(...).
6597 void initialize(Attributor &A) override {
6598 SimplifiedAssociatedValue = nullptr;
6599 indicateOptimisticFixpoint();
6600 }
6601 /// See AbstractAttribute::initialize(...).
6602 ChangeStatus updateImpl(Attributor &A) override {
6604 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6605 }
6606 /// See AbstractAttribute::trackStatistics()
6607 void trackStatistics() const override {
6608 STATS_DECLTRACK_FN_ATTR(value_simplify)
6609 }
6610};
6611
6612struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6613 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6614 : AAValueSimplifyFunction(IRP, A) {}
6615 /// See AbstractAttribute::trackStatistics()
6616 void trackStatistics() const override {
6617 STATS_DECLTRACK_CS_ATTR(value_simplify)
6618 }
6619};
6620
6621struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6622 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6623 : AAValueSimplifyImpl(IRP, A) {}
6624
6625 void initialize(Attributor &A) override {
6626 AAValueSimplifyImpl::initialize(A);
6627 Function *Fn = getAssociatedFunction();
6628 assert(Fn && "Did expect an associted function");
6629 for (Argument &Arg : Fn->args()) {
6630 if (Arg.hasReturnedAttr()) {
6631 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6632 Arg.getArgNo());
6634 checkAndUpdate(A, *this, IRP))
6635 indicateOptimisticFixpoint();
6636 else
6637 indicatePessimisticFixpoint();
6638 return;
6639 }
6640 }
6641 }
6642
6643 /// See AbstractAttribute::updateImpl(...).
6644 ChangeStatus updateImpl(Attributor &A) override {
6645 return indicatePessimisticFixpoint();
6646 }
6647
6648 void trackStatistics() const override {
6649 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6650 }
6651};
6652
6653struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6654 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6655 : AAValueSimplifyFloating(IRP, A) {}
6656
6657 /// See AbstractAttribute::manifest(...).
6658 ChangeStatus manifest(Attributor &A) override {
6659 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6660 // TODO: We should avoid simplification duplication to begin with.
6661 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6662 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6663 if (FloatAA && FloatAA->getState().isValidState())
6664 return Changed;
6665
6666 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6667 Use &U = cast<CallBase>(&getAnchorValue())
6668 ->getArgOperandUse(getCallSiteArgNo());
6669 if (A.changeUseAfterManifest(U, *NewV))
6670 Changed = ChangeStatus::CHANGED;
6671 }
6672
6673 return Changed | AAValueSimplify::manifest(A);
6674 }
6675
6676 void trackStatistics() const override {
6677 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6678 }
6679};
6680} // namespace
6681
6682/// ----------------------- Heap-To-Stack Conversion ---------------------------
6683namespace {
6684struct AAHeapToStackFunction final : public AAHeapToStack {
6685
6686 struct AllocationInfo {
6687 /// The call that allocates the memory.
6688 CallBase *const CB;
6689
6690 /// The library function id for the allocation.
6691 LibFunc LibraryFunctionId = NotLibFunc;
6692
6693 /// The status wrt. a rewrite.
6694 enum {
6695 STACK_DUE_TO_USE,
6696 STACK_DUE_TO_FREE,
6697 INVALID,
6698 } Status = STACK_DUE_TO_USE;
6699
6700 /// Flag to indicate if we encountered a use that might free this allocation
6701 /// but which is not in the deallocation infos.
6702 bool HasPotentiallyFreeingUnknownUses = false;
6703
6704 /// Flag to indicate that we should place the new alloca in the function
6705 /// entry block rather than where the call site (CB) is.
6706 bool MoveAllocaIntoEntry = true;
6707
6708 /// The set of free calls that use this allocation.
6709 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6710 };
6711
6712 struct DeallocationInfo {
6713 /// The call that deallocates the memory.
6714 CallBase *const CB;
6715 /// The value freed by the call.
6716 Value *FreedOp;
6717
6718 /// Flag to indicate if we don't know all objects this deallocation might
6719 /// free.
6720 bool MightFreeUnknownObjects = false;
6721
6722 /// The set of allocation calls that are potentially freed.
6723 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6724 };
6725
6726 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6727 : AAHeapToStack(IRP, A) {}
6728
6729 ~AAHeapToStackFunction() override {
6730 // Ensure we call the destructor so we release any memory allocated in the
6731 // sets.
6732 for (auto &It : AllocationInfos)
6733 It.second->~AllocationInfo();
6734 for (auto &It : DeallocationInfos)
6735 It.second->~DeallocationInfo();
6736 }
6737
6738 void initialize(Attributor &A) override {
6739 AAHeapToStack::initialize(A);
6740
6741 const Function *F = getAnchorScope();
6742 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6743
6744 auto AllocationIdentifierCB = [&](Instruction &I) {
6745 CallBase *CB = dyn_cast<CallBase>(&I);
6746 if (!CB)
6747 return true;
6748 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6749 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6750 return true;
6751 }
6752 // To do heap to stack, we need to know that the allocation itself is
6753 // removable once uses are rewritten, and that we can initialize the
6754 // alloca to the same pattern as the original allocation result.
6755 if (isRemovableAlloc(CB, TLI)) {
6756 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6757 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6758 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6759 AllocationInfos[CB] = AI;
6760 if (TLI)
6761 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6762 }
6763 }
6764 return true;
6765 };
6766
6767 bool UsedAssumedInformation = false;
6768 bool Success = A.checkForAllCallLikeInstructions(
6769 AllocationIdentifierCB, *this, UsedAssumedInformation,
6770 /* CheckBBLivenessOnly */ false,
6771 /* CheckPotentiallyDead */ true);
6772 (void)Success;
6773 assert(Success && "Did not expect the call base visit callback to fail!");
6774
6776 [](const IRPosition &, const AbstractAttribute *,
6777 bool &) -> std::optional<Value *> { return nullptr; };
6778 for (const auto &It : AllocationInfos)
6779 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6780 SCB);
6781 for (const auto &It : DeallocationInfos)
6782 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6783 SCB);
6784 }
6785
6786 const std::string getAsStr(Attributor *A) const override {
6787 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6788 for (const auto &It : AllocationInfos) {
6789 if (It.second->Status == AllocationInfo::INVALID)
6790 ++NumInvalidMallocs;
6791 else
6792 ++NumH2SMallocs;
6793 }
6794 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6795 std::to_string(NumInvalidMallocs);
6796 }
6797
6798 /// See AbstractAttribute::trackStatistics().
6799 void trackStatistics() const override {
6800 STATS_DECL(
6801 MallocCalls, Function,
6802 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6803 for (const auto &It : AllocationInfos)
6804 if (It.second->Status != AllocationInfo::INVALID)
6805 ++BUILD_STAT_NAME(MallocCalls, Function);
6806 }
6807
6808 bool isAssumedHeapToStack(const CallBase &CB) const override {
6809 if (isValidState())
6810 if (AllocationInfo *AI =
6811 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6812 return AI->Status != AllocationInfo::INVALID;
6813 return false;
6814 }
6815
6816 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6817 if (!isValidState())
6818 return false;
6819
6820 for (const auto &It : AllocationInfos) {
6821 AllocationInfo &AI = *It.second;
6822 if (AI.Status == AllocationInfo::INVALID)
6823 continue;
6824
6825 if (AI.PotentialFreeCalls.count(&CB))
6826 return true;
6827 }
6828
6829 return false;
6830 }
6831
6832 ChangeStatus manifest(Attributor &A) override {
6833 assert(getState().isValidState() &&
6834 "Attempted to manifest an invalid state!");
6835
6836 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6837 Function *F = getAnchorScope();
6838 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6839
6840 for (auto &It : AllocationInfos) {
6841 AllocationInfo &AI = *It.second;
6842 if (AI.Status == AllocationInfo::INVALID)
6843 continue;
6844
6845 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6846 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6847 A.deleteAfterManifest(*FreeCall);
6848 HasChanged = ChangeStatus::CHANGED;
6849 }
6850
6851 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6852 << "\n");
6853
6854 auto Remark = [&](OptimizationRemark OR) {
6855 LibFunc IsAllocShared;
6856 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6857 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6858 return OR << "Moving globalized variable to the stack.";
6859 return OR << "Moving memory allocation from the heap to the stack.";
6860 };
6861 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6862 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6863 else
6864 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6865
6866 const DataLayout &DL = A.getInfoCache().getDL();
6867 Value *Size;
6868 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6869 if (SizeAPI) {
6870 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6871 } else {
6872 LLVMContext &Ctx = AI.CB->getContext();
6873 ObjectSizeOpts Opts;
6874 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6875 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6876 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6877 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6878 Size = SizeOffsetPair.Size;
6879 }
6880
6881 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6882 ? F->getEntryBlock().begin()
6883 : AI.CB->getIterator();
6884
6885 Align Alignment(1);
6886 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6887 Alignment = std::max(Alignment, *RetAlign);
6888 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6889 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6890 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6891 "Expected an alignment during manifest!");
6892 Alignment =
6893 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6894 }
6895
6896 // TODO: Hoist the alloca towards the function entry.
6897 unsigned AS = DL.getAllocaAddrSpace();
6898 Instruction *Alloca =
6899 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6900 AI.CB->getName() + ".h2s", IP);
6901
6902 if (Alloca->getType() != AI.CB->getType())
6903 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6904 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6905
6906 auto *I8Ty = Type::getInt8Ty(F->getContext());
6907 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6908 assert(InitVal &&
6909 "Must be able to materialize initial memory state of allocation");
6910
6911 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6912
6913 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6914 auto *NBB = II->getNormalDest();
6915 BranchInst::Create(NBB, AI.CB->getParent());
6916 A.deleteAfterManifest(*AI.CB);
6917 } else {
6918 A.deleteAfterManifest(*AI.CB);
6919 }
6920
6921 // Initialize the alloca with the same value as used by the allocation
6922 // function. We can skip undef as the initial value of an alloc is
6923 // undef, and the memset would simply end up being DSEd.
6924 if (!isa<UndefValue>(InitVal)) {
6925 IRBuilder<> Builder(Alloca->getNextNode());
6926 // TODO: Use alignment above if align!=1
6927 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6928 }
6929 HasChanged = ChangeStatus::CHANGED;
6930 }
6931
6932 return HasChanged;
6933 }
6934
6935 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6936 Value &V) {
6937 bool UsedAssumedInformation = false;
6938 std::optional<Constant *> SimpleV =
6939 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6940 if (!SimpleV)
6941 return APInt(64, 0);
6942 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6943 return CI->getValue();
6944 return std::nullopt;
6945 }
6946
6947 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6948 AllocationInfo &AI) {
6949 auto Mapper = [&](const Value *V) -> const Value * {
6950 bool UsedAssumedInformation = false;
6951 if (std::optional<Constant *> SimpleV =
6952 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6953 if (*SimpleV)
6954 return *SimpleV;
6955 return V;
6956 };
6957
6958 const Function *F = getAnchorScope();
6959 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6960 return getAllocSize(AI.CB, TLI, Mapper);
6961 }
6962
6963 /// Collection of all malloc-like calls in a function with associated
6964 /// information.
6965 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6966
6967 /// Collection of all free-like calls in a function with associated
6968 /// information.
6969 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6970
6971 ChangeStatus updateImpl(Attributor &A) override;
6972};
6973
6974ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6976 const Function *F = getAnchorScope();
6977 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6978
6979 const auto *LivenessAA =
6980 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6981
6982 MustBeExecutedContextExplorer *Explorer =
6983 A.getInfoCache().getMustBeExecutedContextExplorer();
6984
6985 bool StackIsAccessibleByOtherThreads =
6986 A.getInfoCache().stackIsAccessibleByOtherThreads();
6987
6988 LoopInfo *LI =
6989 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6990 std::optional<bool> MayContainIrreducibleControl;
6991 auto IsInLoop = [&](BasicBlock &BB) {
6992 if (&F->getEntryBlock() == &BB)
6993 return false;
6994 if (!MayContainIrreducibleControl.has_value())
6995 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6996 if (*MayContainIrreducibleControl)
6997 return true;
6998 if (!LI)
6999 return true;
7000 return LI->getLoopFor(&BB) != nullptr;
7001 };
7002
7003 // Flag to ensure we update our deallocation information at most once per
7004 // updateImpl call and only if we use the free check reasoning.
7005 bool HasUpdatedFrees = false;
7006
7007 auto UpdateFrees = [&]() {
7008 HasUpdatedFrees = true;
7009
7010 for (auto &It : DeallocationInfos) {
7011 DeallocationInfo &DI = *It.second;
7012 // For now we cannot use deallocations that have unknown inputs, skip
7013 // them.
7014 if (DI.MightFreeUnknownObjects)
7015 continue;
7016
7017 // No need to analyze dead calls, ignore them instead.
7018 bool UsedAssumedInformation = false;
7019 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7020 /* CheckBBLivenessOnly */ true))
7021 continue;
7022
7023 // Use the non-optimistic version to get the freed object.
7024 Value *Obj = getUnderlyingObject(DI.FreedOp);
7025 if (!Obj) {
7026 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7027 DI.MightFreeUnknownObjects = true;
7028 continue;
7029 }
7030
7031 // Free of null and undef can be ignored as no-ops (or UB in the latter
7032 // case).
7034 continue;
7035
7036 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7037 if (!ObjCB) {
7038 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7039 << "\n");
7040 DI.MightFreeUnknownObjects = true;
7041 continue;
7042 }
7043
7044 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7045 if (!AI) {
7046 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7047 << "\n");
7048 DI.MightFreeUnknownObjects = true;
7049 continue;
7050 }
7051
7052 DI.PotentialAllocationCalls.insert(ObjCB);
7053 }
7054 };
7055
7056 auto FreeCheck = [&](AllocationInfo &AI) {
7057 // If the stack is not accessible by other threads, the "must-free" logic
7058 // doesn't apply as the pointer could be shared and needs to be places in
7059 // "shareable" memory.
7060 if (!StackIsAccessibleByOtherThreads) {
7061 bool IsKnownNoSycn;
7063 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7064 LLVM_DEBUG(
7065 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7066 "other threads and function is not nosync:\n");
7067 return false;
7068 }
7069 }
7070 if (!HasUpdatedFrees)
7071 UpdateFrees();
7072
7073 // TODO: Allow multi exit functions that have different free calls.
7074 if (AI.PotentialFreeCalls.size() != 1) {
7075 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7076 << AI.PotentialFreeCalls.size() << "\n");
7077 return false;
7078 }
7079 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7080 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7081 if (!DI) {
7082 LLVM_DEBUG(
7083 dbgs() << "[H2S] unique free call was not known as deallocation call "
7084 << *UniqueFree << "\n");
7085 return false;
7086 }
7087 if (DI->MightFreeUnknownObjects) {
7088 LLVM_DEBUG(
7089 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7090 return false;
7091 }
7092 if (DI->PotentialAllocationCalls.empty())
7093 return true;
7094 if (DI->PotentialAllocationCalls.size() > 1) {
7095 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7096 << DI->PotentialAllocationCalls.size()
7097 << " different allocations\n");
7098 return false;
7099 }
7100 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7101 LLVM_DEBUG(
7102 dbgs()
7103 << "[H2S] unique free call not known to free this allocation but "
7104 << **DI->PotentialAllocationCalls.begin() << "\n");
7105 return false;
7106 }
7107
7108 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
7109 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
7110 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7111 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7112 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7113 "with the allocation "
7114 << *UniqueFree << "\n");
7115 return false;
7116 }
7117 }
7118 return true;
7119 };
7120
7121 auto UsesCheck = [&](AllocationInfo &AI) {
7122 bool ValidUsesOnly = true;
7123
7124 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7125 Instruction *UserI = cast<Instruction>(U.getUser());
7126 if (isa<LoadInst>(UserI))
7127 return true;
7128 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7129 if (SI->getValueOperand() == U.get()) {
7131 << "[H2S] escaping store to memory: " << *UserI << "\n");
7132 ValidUsesOnly = false;
7133 } else {
7134 // A store into the malloc'ed memory is fine.
7135 }
7136 return true;
7137 }
7138 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7139 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7140 return true;
7141 if (DeallocationInfos.count(CB)) {
7142 AI.PotentialFreeCalls.insert(CB);
7143 return true;
7144 }
7145
7146 unsigned ArgNo = CB->getArgOperandNo(&U);
7147 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7148
7149 bool IsKnownNoCapture;
7150 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7151 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7152
7153 // If a call site argument use is nofree, we are fine.
7154 bool IsKnownNoFree;
7155 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7156 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7157
7158 if (!IsAssumedNoCapture ||
7159 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7160 !IsAssumedNoFree)) {
7161 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7162
7163 // Emit a missed remark if this is missed OpenMP globalization.
7164 auto Remark = [&](OptimizationRemarkMissed ORM) {
7165 return ORM
7166 << "Could not move globalized variable to the stack. "
7167 "Variable is potentially captured in call. Mark "
7168 "parameter as `__attribute__((noescape))` to override.";
7169 };
7170
7171 if (ValidUsesOnly &&
7172 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7173 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7174
7175 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7176 ValidUsesOnly = false;
7177 }
7178 return true;
7179 }
7180
7181 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7182 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7183 Follow = true;
7184 return true;
7185 }
7186 // Unknown user for which we can not track uses further (in a way that
7187 // makes sense).
7188 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7189 ValidUsesOnly = false;
7190 return true;
7191 };
7192 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7193 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7194 [&](const Use &OldU, const Use &NewU) {
7195 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7196 return !SI || StackIsAccessibleByOtherThreads ||
7197 AA::isAssumedThreadLocalObject(
7198 A, *SI->getPointerOperand(), *this);
7199 }))
7200 return false;
7201 return ValidUsesOnly;
7202 };
7203
7204 // The actual update starts here. We look at all allocations and depending on
7205 // their status perform the appropriate check(s).
7206 for (auto &It : AllocationInfos) {
7207 AllocationInfo &AI = *It.second;
7208 if (AI.Status == AllocationInfo::INVALID)
7209 continue;
7210
7211 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7212 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7213 if (!APAlign) {
7214 // Can't generate an alloca which respects the required alignment
7215 // on the allocation.
7216 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7217 << "\n");
7218 AI.Status = AllocationInfo::INVALID;
7220 continue;
7221 }
7222 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7223 !APAlign->isPowerOf2()) {
7224 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7225 << "\n");
7226 AI.Status = AllocationInfo::INVALID;
7228 continue;
7229 }
7230 }
7231
7232 std::optional<APInt> Size = getSize(A, *this, AI);
7233 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7234 MaxHeapToStackSize != -1) {
7235 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7236 LLVM_DEBUG({
7237 if (!Size)
7238 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7239 else
7240 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7241 << MaxHeapToStackSize << "\n";
7242 });
7243
7244 AI.Status = AllocationInfo::INVALID;
7246 continue;
7247 }
7248 }
7249
7250 switch (AI.Status) {
7251 case AllocationInfo::STACK_DUE_TO_USE:
7252 if (UsesCheck(AI))
7253 break;
7254 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7255 [[fallthrough]];
7256 case AllocationInfo::STACK_DUE_TO_FREE:
7257 if (FreeCheck(AI))
7258 break;
7259 AI.Status = AllocationInfo::INVALID;
7261 break;
7262 case AllocationInfo::INVALID:
7263 llvm_unreachable("Invalid allocations should never reach this point!");
7264 };
7265
7266 // Check if we still think we can move it into the entry block. If the
7267 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7268 // ignore the potential compilations associated with loops.
7269 bool IsGlobalizedLocal =
7270 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7271 if (AI.MoveAllocaIntoEntry &&
7272 (!Size.has_value() ||
7273 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7274 AI.MoveAllocaIntoEntry = false;
7275 }
7276
7277 return Changed;
7278}
7279} // namespace
7280
7281/// ----------------------- Privatizable Pointers ------------------------------
7282namespace {
7283struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7284 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7285 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7286
7287 ChangeStatus indicatePessimisticFixpoint() override {
7288 AAPrivatizablePtr::indicatePessimisticFixpoint();
7289 PrivatizableType = nullptr;
7290 return ChangeStatus::CHANGED;
7291 }
7292
7293 /// Identify the type we can chose for a private copy of the underlying
7294 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7295 /// none.
7296 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7297
7298 /// Return a privatizable type that encloses both T0 and T1.
7299 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7300 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7301 std::optional<Type *> T1) {
7302 if (!T0)
7303 return T1;
7304 if (!T1)
7305 return T0;
7306 if (T0 == T1)
7307 return T0;
7308 return nullptr;
7309 }
7310
7311 std::optional<Type *> getPrivatizableType() const override {
7312 return PrivatizableType;
7313 }
7314
7315 const std::string getAsStr(Attributor *A) const override {
7316 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7317 }
7318
7319protected:
7320 std::optional<Type *> PrivatizableType;
7321};
7322
7323// TODO: Do this for call site arguments (probably also other values) as well.
7324
7325struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7326 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7327 : AAPrivatizablePtrImpl(IRP, A) {}
7328
7329 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7330 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7331 // If this is a byval argument and we know all the call sites (so we can
7332 // rewrite them), there is no need to check them explicitly.
7333 bool UsedAssumedInformation = false;
7335 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7336 /* IgnoreSubsumingPositions */ true);
7337 if (!Attrs.empty() &&
7338 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7339 true, UsedAssumedInformation))
7340 return Attrs[0].getValueAsType();
7341
7342 std::optional<Type *> Ty;
7343 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7344
7345 // Make sure the associated call site argument has the same type at all call
7346 // sites and it is an allocation we know is safe to privatize, for now that
7347 // means we only allow alloca instructions.
7348 // TODO: We can additionally analyze the accesses in the callee to create
7349 // the type from that information instead. That is a little more
7350 // involved and will be done in a follow up patch.
7351 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7352 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7353 // Check if a coresponding argument was found or if it is one not
7354 // associated (which can happen for callback calls).
7355 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7356 return false;
7357
7358 // Check that all call sites agree on a type.
7359 auto *PrivCSArgAA =
7360 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7361 if (!PrivCSArgAA)
7362 return false;
7363 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7364
7365 LLVM_DEBUG({
7366 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7367 if (CSTy && *CSTy)
7368 (*CSTy)->print(dbgs());
7369 else if (CSTy)
7370 dbgs() << "<nullptr>";
7371 else
7372 dbgs() << "<none>";
7373 });
7374
7375 Ty = combineTypes(Ty, CSTy);
7376
7377 LLVM_DEBUG({
7378 dbgs() << " : New Type: ";
7379 if (Ty && *Ty)
7380 (*Ty)->print(dbgs());
7381 else if (Ty)
7382 dbgs() << "<nullptr>";
7383 else
7384 dbgs() << "<none>";
7385 dbgs() << "\n";
7386 });
7387
7388 return !Ty || *Ty;
7389 };
7390
7391 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7392 UsedAssumedInformation))
7393 return nullptr;
7394 return Ty;
7395 }
7396
7397 /// See AbstractAttribute::updateImpl(...).
7398 ChangeStatus updateImpl(Attributor &A) override {
7399 PrivatizableType = identifyPrivatizableType(A);
7400 if (!PrivatizableType)
7401 return ChangeStatus::UNCHANGED;
7402 if (!*PrivatizableType)
7403 return indicatePessimisticFixpoint();
7404
7405 // The dependence is optional so we don't give up once we give up on the
7406 // alignment.
7407 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7408 DepClassTy::OPTIONAL);
7409
7410 // Avoid arguments with padding for now.
7411 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7412 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7413 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7414 return indicatePessimisticFixpoint();
7415 }
7416
7417 // Collect the types that will replace the privatizable type in the function
7418 // signature.
7419 SmallVector<Type *, 16> ReplacementTypes;
7420 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7421
7422 // Verify callee and caller agree on how the promoted argument would be
7423 // passed.
7424 Function &Fn = *getIRPosition().getAnchorScope();
7425 const auto *TTI =
7426 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7427 if (!TTI) {
7428 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7429 << Fn.getName() << "\n");
7430 return indicatePessimisticFixpoint();
7431 }
7432
7433 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7434 CallBase *CB = ACS.getInstruction();
7435 return TTI->areTypesABICompatible(
7436 CB->getCaller(),
7438 ReplacementTypes);
7439 };
7440 bool UsedAssumedInformation = false;
7441 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7442 UsedAssumedInformation)) {
7443 LLVM_DEBUG(
7444 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7445 << Fn.getName() << "\n");
7446 return indicatePessimisticFixpoint();
7447 }
7448
7449 // Register a rewrite of the argument.
7450 Argument *Arg = getAssociatedArgument();
7451 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7452 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7453 return indicatePessimisticFixpoint();
7454 }
7455
7456 unsigned ArgNo = Arg->getArgNo();
7457
7458 // Helper to check if for the given call site the associated argument is
7459 // passed to a callback where the privatization would be different.
7460 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7461 SmallVector<const Use *, 4> CallbackUses;
7462 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7463 for (const Use *U : CallbackUses) {
7464 AbstractCallSite CBACS(U);
7465 assert(CBACS && CBACS.isCallbackCall());
7466 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7467 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7468
7469 LLVM_DEBUG({
7470 dbgs()
7471 << "[AAPrivatizablePtr] Argument " << *Arg
7472 << "check if can be privatized in the context of its parent ("
7473 << Arg->getParent()->getName()
7474 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7475 "callback ("
7476 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7477 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7478 << CBACS.getCallArgOperand(CBArg) << " vs "
7479 << CB.getArgOperand(ArgNo) << "\n"
7480 << "[AAPrivatizablePtr] " << CBArg << " : "
7481 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7482 });
7483
7484 if (CBArgNo != int(ArgNo))
7485 continue;
7486 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7487 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7488 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7489 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7490 if (!CBArgPrivTy)
7491 continue;
7492 if (*CBArgPrivTy == PrivatizableType)
7493 continue;
7494 }
7495
7496 LLVM_DEBUG({
7497 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7498 << " cannot be privatized in the context of its parent ("
7499 << Arg->getParent()->getName()
7500 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7501 "callback ("
7502 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7503 << ").\n[AAPrivatizablePtr] for which the argument "
7504 "privatization is not compatible.\n";
7505 });
7506 return false;
7507 }
7508 }
7509 return true;
7510 };
7511
7512 // Helper to check if for the given call site the associated argument is
7513 // passed to a direct call where the privatization would be different.
7514 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7515 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7516 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7517 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7518 "Expected a direct call operand for callback call operand");
7519
7520 Function *DCCallee =
7522 LLVM_DEBUG({
7523 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7524 << " check if be privatized in the context of its parent ("
7525 << Arg->getParent()->getName()
7526 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7527 "direct call of ("
7528 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7529 });
7530
7531 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7532 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7533 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7534 DepClassTy::REQUIRED);
7535 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7536 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7537 if (!DCArgPrivTy)
7538 return true;
7539 if (*DCArgPrivTy == PrivatizableType)
7540 return true;
7541 }
7542 }
7543
7544 LLVM_DEBUG({
7545 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7546 << " cannot be privatized in the context of its parent ("
7547 << Arg->getParent()->getName()
7548 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7549 "direct call of ("
7551 << ").\n[AAPrivatizablePtr] for which the argument "
7552 "privatization is not compatible.\n";
7553 });
7554 return false;
7555 };
7556
7557 // Helper to check if the associated argument is used at the given abstract
7558 // call site in a way that is incompatible with the privatization assumed
7559 // here.
7560 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7561 if (ACS.isDirectCall())
7562 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7563 if (ACS.isCallbackCall())
7564 return IsCompatiblePrivArgOfDirectCS(ACS);
7565 return false;
7566 };
7567
7568 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7569 UsedAssumedInformation))
7570 return indicatePessimisticFixpoint();
7571
7572 return ChangeStatus::UNCHANGED;
7573 }
7574
7575 /// Given a type to private \p PrivType, collect the constituates (which are
7576 /// used) in \p ReplacementTypes.
7577 static void
7578 identifyReplacementTypes(Type *PrivType,
7579 SmallVectorImpl<Type *> &ReplacementTypes) {
7580 // TODO: For now we expand the privatization type to the fullest which can
7581 // lead to dead arguments that need to be removed later.
7582 assert(PrivType && "Expected privatizable type!");
7583
7584 // Traverse the type, extract constituate types on the outermost level.
7585 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7586 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7587 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7588 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7589 ReplacementTypes.append(PrivArrayType->getNumElements(),
7590 PrivArrayType->getElementType());
7591 } else {
7592 ReplacementTypes.push_back(PrivType);
7593 }
7594 }
7595
7596 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7597 /// The values needed are taken from the arguments of \p F starting at
7598 /// position \p ArgNo.
7599 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7600 unsigned ArgNo, BasicBlock::iterator IP) {
7601 assert(PrivType && "Expected privatizable type!");
7602
7603 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7604 const DataLayout &DL = F.getDataLayout();
7605
7606 // Traverse the type, build GEPs and stores.
7607 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7608 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7609 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7610 Value *Ptr =
7611 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7612 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7613 }
7614 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7615 Type *PointeeTy = PrivArrayType->getElementType();
7616 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7617 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7618 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7619 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7620 }
7621 } else {
7622 new StoreInst(F.getArg(ArgNo), &Base, IP);
7623 }
7624 }
7625
7626 /// Extract values from \p Base according to the type \p PrivType at the
7627 /// call position \p ACS. The values are appended to \p ReplacementValues.
7628 void createReplacementValues(Align Alignment, Type *PrivType,
7629 AbstractCallSite ACS, Value *Base,
7630 SmallVectorImpl<Value *> &ReplacementValues) {
7631 assert(Base && "Expected base value!");
7632 assert(PrivType && "Expected privatizable type!");
7633 Instruction *IP = ACS.getInstruction();
7634
7635 IRBuilder<NoFolder> IRB(IP);
7636 const DataLayout &DL = IP->getDataLayout();
7637
7638 // Traverse the type, build GEPs and loads.
7639 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7640 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7641 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7642 Type *PointeeTy = PrivStructType->getElementType(u);
7643 Value *Ptr =
7644 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7645 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7646 L->setAlignment(Alignment);
7647 ReplacementValues.push_back(L);
7648 }
7649 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7650 Type *PointeeTy = PrivArrayType->getElementType();
7651 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7652 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7653 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7654 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7655 L->setAlignment(Alignment);
7656 ReplacementValues.push_back(L);
7657 }
7658 } else {
7659 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7660 L->setAlignment(Alignment);
7661 ReplacementValues.push_back(L);
7662 }
7663 }
7664
7665 /// See AbstractAttribute::manifest(...)
7666 ChangeStatus manifest(Attributor &A) override {
7667 if (!PrivatizableType)
7668 return ChangeStatus::UNCHANGED;
7669 assert(*PrivatizableType && "Expected privatizable type!");
7670
7671 // Collect all tail calls in the function as we cannot allow new allocas to
7672 // escape into tail recursion.
7673 // TODO: Be smarter about new allocas escaping into tail calls.
7675 bool UsedAssumedInformation = false;
7676 if (!A.checkForAllInstructions(
7677 [&](Instruction &I) {
7678 CallInst &CI = cast<CallInst>(I);
7679 if (CI.isTailCall())
7680 TailCalls.push_back(&CI);
7681 return true;
7682 },
7683 *this, {Instruction::Call}, UsedAssumedInformation))
7684 return ChangeStatus::UNCHANGED;
7685
7686 Argument *Arg = getAssociatedArgument();
7687 // Query AAAlign attribute for alignment of associated argument to
7688 // determine the best alignment of loads.
7689 const auto *AlignAA =
7690 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7691
7692 // Callback to repair the associated function. A new alloca is placed at the
7693 // beginning and initialized with the values passed through arguments. The
7694 // new alloca replaces the use of the old pointer argument.
7696 [=](const Attributor::ArgumentReplacementInfo &ARI,
7697 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7698 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7700 const DataLayout &DL = IP->getDataLayout();
7701 unsigned AS = DL.getAllocaAddrSpace();
7702 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7703 Arg->getName() + ".priv", IP);
7704 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7705 ArgIt->getArgNo(), IP);
7706
7707 if (AI->getType() != Arg->getType())
7708 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7709 AI, Arg->getType(), "", IP);
7710 Arg->replaceAllUsesWith(AI);
7711
7712 for (CallInst *CI : TailCalls)
7713 CI->setTailCall(false);
7714 };
7715
7716 // Callback to repair a call site of the associated function. The elements
7717 // of the privatizable type are loaded prior to the call and passed to the
7718 // new function version.
7720 [=](const Attributor::ArgumentReplacementInfo &ARI,
7721 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7722 // When no alignment is specified for the load instruction,
7723 // natural alignment is assumed.
7724 createReplacementValues(
7725 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7726 *PrivatizableType, ACS,
7727 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7728 NewArgOperands);
7729 };
7730
7731 // Collect the types that will replace the privatizable type in the function
7732 // signature.
7733 SmallVector<Type *, 16> ReplacementTypes;
7734 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7735
7736 // Register a rewrite of the argument.
7737 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7738 std::move(FnRepairCB),
7739 std::move(ACSRepairCB)))
7740 return ChangeStatus::CHANGED;
7741 return ChangeStatus::UNCHANGED;
7742 }
7743
7744 /// See AbstractAttribute::trackStatistics()
7745 void trackStatistics() const override {
7746 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7747 }
7748};
7749
7750struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7751 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7752 : AAPrivatizablePtrImpl(IRP, A) {}
7753
7754 /// See AbstractAttribute::initialize(...).
7755 void initialize(Attributor &A) override {
7756 // TODO: We can privatize more than arguments.
7757 indicatePessimisticFixpoint();
7758 }
7759
7760 ChangeStatus updateImpl(Attributor &A) override {
7761 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7762 "updateImpl will not be called");
7763 }
7764
7765 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7766 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7767 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7768 if (!Obj) {
7769 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7770 return nullptr;
7771 }
7772
7773 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7774 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7775 if (CI->isOne())
7776 return AI->getAllocatedType();
7777 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7778 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7779 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7780 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7781 return PrivArgAA->getPrivatizableType();
7782 }
7783
7784 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7785 "alloca nor privatizable argument: "
7786 << *Obj << "!\n");
7787 return nullptr;
7788 }
7789
7790 /// See AbstractAttribute::trackStatistics()
7791 void trackStatistics() const override {
7792 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7793 }
7794};
7795
7796struct AAPrivatizablePtrCallSiteArgument final
7797 : public AAPrivatizablePtrFloating {
7798 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7799 : AAPrivatizablePtrFloating(IRP, A) {}
7800
7801 /// See AbstractAttribute::initialize(...).
7802 void initialize(Attributor &A) override {
7803 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7804 indicateOptimisticFixpoint();
7805 }
7806
7807 /// See AbstractAttribute::updateImpl(...).
7808 ChangeStatus updateImpl(Attributor &A) override {
7809 PrivatizableType = identifyPrivatizableType(A);
7810 if (!PrivatizableType)
7811 return ChangeStatus::UNCHANGED;
7812 if (!*PrivatizableType)
7813 return indicatePessimisticFixpoint();
7814
7815 const IRPosition &IRP = getIRPosition();
7816 bool IsKnownNoCapture;
7817 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7818 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7819 if (!IsAssumedNoCapture) {
7820 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7821 return indicatePessimisticFixpoint();
7822 }
7823
7824 bool IsKnownNoAlias;
7826 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7827 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7828 return indicatePessimisticFixpoint();
7829 }
7830
7831 bool IsKnown;
7832 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7833 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7834 return indicatePessimisticFixpoint();
7835 }
7836
7837 return ChangeStatus::UNCHANGED;
7838 }
7839
7840 /// See AbstractAttribute::trackStatistics()
7841 void trackStatistics() const override {
7842 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7843 }
7844};
7845
7846struct AAPrivatizablePtrCallSiteReturned final
7847 : public AAPrivatizablePtrFloating {
7848 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7849 : AAPrivatizablePtrFloating(IRP, A) {}
7850
7851 /// See AbstractAttribute::initialize(...).
7852 void initialize(Attributor &A) override {
7853 // TODO: We can privatize more than arguments.
7854 indicatePessimisticFixpoint();
7855 }
7856
7857 /// See AbstractAttribute::trackStatistics()
7858 void trackStatistics() const override {
7859 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7860 }
7861};
7862
7863struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7864 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7865 : AAPrivatizablePtrFloating(IRP, A) {}
7866
7867 /// See AbstractAttribute::initialize(...).
7868 void initialize(Attributor &A) override {
7869 // TODO: We can privatize more than arguments.
7870 indicatePessimisticFixpoint();
7871 }
7872
7873 /// See AbstractAttribute::trackStatistics()
7874 void trackStatistics() const override {
7875 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7876 }
7877};
7878} // namespace
7879
7880/// -------------------- Memory Behavior Attributes ----------------------------
7881/// Includes read-none, read-only, and write-only.
7882/// ----------------------------------------------------------------------------
7883namespace {
7884struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7885 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7886 : AAMemoryBehavior(IRP, A) {}
7887
7888 /// See AbstractAttribute::initialize(...).
7889 void initialize(Attributor &A) override {
7890 intersectAssumedBits(BEST_STATE);
7891 getKnownStateFromValue(A, getIRPosition(), getState());
7892 AAMemoryBehavior::initialize(A);
7893 }
7894
7895 /// Return the memory behavior information encoded in the IR for \p IRP.
7896 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7897 BitIntegerState &State,
7898 bool IgnoreSubsumingPositions = false) {
7900 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7901 for (const Attribute &Attr : Attrs) {
7902 switch (Attr.getKindAsEnum()) {
7903 case Attribute::ReadNone:
7904 State.addKnownBits(NO_ACCESSES);
7905 break;
7906 case Attribute::ReadOnly:
7907 State.addKnownBits(NO_WRITES);
7908 break;
7909 case Attribute::WriteOnly:
7910 State.addKnownBits(NO_READS);
7911 break;
7912 default:
7913 llvm_unreachable("Unexpected attribute!");
7914 }
7915 }
7916
7917 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7918 if (!I->mayReadFromMemory())
7919 State.addKnownBits(NO_READS);
7920 if (!I->mayWriteToMemory())
7921 State.addKnownBits(NO_WRITES);
7922 }
7923 }
7924
7925 /// See AbstractAttribute::getDeducedAttributes(...).
7926 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7927 SmallVectorImpl<Attribute> &Attrs) const override {
7928 assert(Attrs.size() == 0);
7929 if (isAssumedReadNone())
7930 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7931 else if (isAssumedReadOnly())
7932 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7933 else if (isAssumedWriteOnly())
7934 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7935 assert(Attrs.size() <= 1);
7936 }
7937
7938 /// See AbstractAttribute::manifest(...).
7939 ChangeStatus manifest(Attributor &A) override {
7940 const IRPosition &IRP = getIRPosition();
7941
7942 if (A.hasAttr(IRP, Attribute::ReadNone,
7943 /* IgnoreSubsumingPositions */ true))
7944 return ChangeStatus::UNCHANGED;
7945
7946 // Check if we would improve the existing attributes first.
7947 SmallVector<Attribute, 4> DeducedAttrs;
7948 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7949 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7950 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7951 /* IgnoreSubsumingPositions */ true);
7952 }))
7953 return ChangeStatus::UNCHANGED;
7954
7955 // Clear existing attributes.
7956 A.removeAttrs(IRP, AttrKinds);
7957 // Clear conflicting writable attribute.
7958 if (isAssumedReadOnly())
7959 A.removeAttrs(IRP, Attribute::Writable);
7960
7961 // Use the generic manifest method.
7962 return IRAttribute::manifest(A);
7963 }
7964
7965 /// See AbstractState::getAsStr().
7966 const std::string getAsStr(Attributor *A) const override {
7967 if (isAssumedReadNone())
7968 return "readnone";
7969 if (isAssumedReadOnly())
7970 return "readonly";
7971 if (isAssumedWriteOnly())
7972 return "writeonly";
7973 return "may-read/write";
7974 }
7975
7976 /// The set of IR attributes AAMemoryBehavior deals with.
7977 static const Attribute::AttrKind AttrKinds[3];
7978};
7979
7980const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7981 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7982
7983/// Memory behavior attribute for a floating value.
7984struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7985 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7986 : AAMemoryBehaviorImpl(IRP, A) {}
7987
7988 /// See AbstractAttribute::updateImpl(...).
7989 ChangeStatus updateImpl(Attributor &A) override;
7990
7991 /// See AbstractAttribute::trackStatistics()
7992 void trackStatistics() const override {
7993 if (isAssumedReadNone())
7995 else if (isAssumedReadOnly())
7997 else if (isAssumedWriteOnly())
7999 }
8000
8001private:
8002 /// Return true if users of \p UserI might access the underlying
8003 /// variable/location described by \p U and should therefore be analyzed.
8004 bool followUsersOfUseIn(Attributor &A, const Use &U,
8005 const Instruction *UserI);
8006
8007 /// Update the state according to the effect of use \p U in \p UserI.
8008 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8009};
8010
8011/// Memory behavior attribute for function argument.
8012struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8013 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8014 : AAMemoryBehaviorFloating(IRP, A) {}
8015
8016 /// See AbstractAttribute::initialize(...).
8017 void initialize(Attributor &A) override {
8018 intersectAssumedBits(BEST_STATE);
8019 const IRPosition &IRP = getIRPosition();
8020 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8021 // can query it when we use has/getAttr. That would allow us to reuse the
8022 // initialize of the base class here.
8023 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8024 /* IgnoreSubsumingPositions */ true);
8025 getKnownStateFromValue(A, IRP, getState(),
8026 /* IgnoreSubsumingPositions */ HasByVal);
8027 }
8028
8029 ChangeStatus manifest(Attributor &A) override {
8030 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8031 if (!getAssociatedValue().getType()->isPointerTy())
8032 return ChangeStatus::UNCHANGED;
8033
8034 // TODO: From readattrs.ll: "inalloca parameters are always
8035 // considered written"
8036 if (A.hasAttr(getIRPosition(),
8037 {Attribute::InAlloca, Attribute::Preallocated})) {
8038 removeKnownBits(NO_WRITES);
8039 removeAssumedBits(NO_WRITES);
8040 }
8041 A.removeAttrs(getIRPosition(), AttrKinds);
8042 return AAMemoryBehaviorFloating::manifest(A);
8043 }
8044
8045 /// See AbstractAttribute::trackStatistics()
8046 void trackStatistics() const override {
8047 if (isAssumedReadNone())
8048 STATS_DECLTRACK_ARG_ATTR(readnone)
8049 else if (isAssumedReadOnly())
8050 STATS_DECLTRACK_ARG_ATTR(readonly)
8051 else if (isAssumedWriteOnly())
8052 STATS_DECLTRACK_ARG_ATTR(writeonly)
8053 }
8054};
8055
8056struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8057 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8058 : AAMemoryBehaviorArgument(IRP, A) {}
8059
8060 /// See AbstractAttribute::initialize(...).
8061 void initialize(Attributor &A) override {
8062 // If we don't have an associated attribute this is either a variadic call
8063 // or an indirect call, either way, nothing to do here.
8064 Argument *Arg = getAssociatedArgument();
8065 if (!Arg) {
8066 indicatePessimisticFixpoint();
8067 return;
8068 }
8069 if (Arg->hasByValAttr()) {
8070 addKnownBits(NO_WRITES);
8071 removeKnownBits(NO_READS);
8072 removeAssumedBits(NO_READS);
8073 }
8074 AAMemoryBehaviorArgument::initialize(A);
8075 if (getAssociatedFunction()->isDeclaration())
8076 indicatePessimisticFixpoint();
8077 }
8078
8079 /// See AbstractAttribute::updateImpl(...).
8080 ChangeStatus updateImpl(Attributor &A) override {
8081 // TODO: Once we have call site specific value information we can provide
8082 // call site specific liveness liveness information and then it makes
8083 // sense to specialize attributes for call sites arguments instead of
8084 // redirecting requests to the callee argument.
8085 Argument *Arg = getAssociatedArgument();
8086 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8087 auto *ArgAA =
8088 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8089 if (!ArgAA)
8090 return indicatePessimisticFixpoint();
8091 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8092 }
8093
8094 /// See AbstractAttribute::trackStatistics()
8095 void trackStatistics() const override {
8096 if (isAssumedReadNone())
8098 else if (isAssumedReadOnly())
8100 else if (isAssumedWriteOnly())
8102 }
8103};
8104
8105/// Memory behavior attribute for a call site return position.
8106struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8107 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8108 : AAMemoryBehaviorFloating(IRP, A) {}
8109
8110 /// See AbstractAttribute::initialize(...).
8111 void initialize(Attributor &A) override {
8112 AAMemoryBehaviorImpl::initialize(A);
8113 }
8114 /// See AbstractAttribute::manifest(...).
8115 ChangeStatus manifest(Attributor &A) override {
8116 // We do not annotate returned values.
8117 return ChangeStatus::UNCHANGED;
8118 }
8119
8120 /// See AbstractAttribute::trackStatistics()
8121 void trackStatistics() const override {}
8122};
8123
8124/// An AA to represent the memory behavior function attributes.
8125struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8126 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8127 : AAMemoryBehaviorImpl(IRP, A) {}
8128
8129 /// See AbstractAttribute::updateImpl(Attributor &A).
8130 ChangeStatus updateImpl(Attributor &A) override;
8131
8132 /// See AbstractAttribute::manifest(...).
8133 ChangeStatus manifest(Attributor &A) override {
8134 // TODO: It would be better to merge this with AAMemoryLocation, so that
8135 // we could determine read/write per location. This would also have the
8136 // benefit of only one place trying to manifest the memory attribute.
8137 Function &F = cast<Function>(getAnchorValue());
8139 if (isAssumedReadNone())
8140 ME = MemoryEffects::none();
8141 else if (isAssumedReadOnly())
8143 else if (isAssumedWriteOnly())
8145
8146 A.removeAttrs(getIRPosition(), AttrKinds);
8147 // Clear conflicting writable attribute.
8148 if (ME.onlyReadsMemory())
8149 for (Argument &Arg : F.args())
8150 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8151 return A.manifestAttrs(getIRPosition(),
8152 Attribute::getWithMemoryEffects(F.getContext(), ME));
8153 }
8154
8155 /// See AbstractAttribute::trackStatistics()
8156 void trackStatistics() const override {
8157 if (isAssumedReadNone())
8158 STATS_DECLTRACK_FN_ATTR(readnone)
8159 else if (isAssumedReadOnly())
8160 STATS_DECLTRACK_FN_ATTR(readonly)
8161 else if (isAssumedWriteOnly())
8162 STATS_DECLTRACK_FN_ATTR(writeonly)
8163 }
8164};
8165
8166/// AAMemoryBehavior attribute for call sites.
8167struct AAMemoryBehaviorCallSite final
8168 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8169 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8170 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8171
8172 /// See AbstractAttribute::manifest(...).
8173 ChangeStatus manifest(Attributor &A) override {
8174 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8175 CallBase &CB = cast<CallBase>(getAnchorValue());
8177 if (isAssumedReadNone())
8178 ME = MemoryEffects::none();
8179 else if (isAssumedReadOnly())
8181 else if (isAssumedWriteOnly())
8183
8184 A.removeAttrs(getIRPosition(), AttrKinds);
8185 // Clear conflicting writable attribute.
8186 if (ME.onlyReadsMemory())
8187 for (Use &U : CB.args())
8188 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8189 Attribute::Writable);
8190 return A.manifestAttrs(
8191 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8192 }
8193
8194 /// See AbstractAttribute::trackStatistics()
8195 void trackStatistics() const override {
8196 if (isAssumedReadNone())
8197 STATS_DECLTRACK_CS_ATTR(readnone)
8198 else if (isAssumedReadOnly())
8199 STATS_DECLTRACK_CS_ATTR(readonly)
8200 else if (isAssumedWriteOnly())
8201 STATS_DECLTRACK_CS_ATTR(writeonly)
8202 }
8203};
8204
8205ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8206
8207 // The current assumed state used to determine a change.
8208 auto AssumedState = getAssumed();
8209
8210 auto CheckRWInst = [&](Instruction &I) {
8211 // If the instruction has an own memory behavior state, use it to restrict
8212 // the local state. No further analysis is required as the other memory
8213 // state is as optimistic as it gets.
8214 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8215 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8217 if (MemBehaviorAA) {
8218 intersectAssumedBits(MemBehaviorAA->getAssumed());
8219 return !isAtFixpoint();
8220 }
8221 }
8222
8223 // Remove access kind modifiers if necessary.
8224 if (I.mayReadFromMemory())
8225 removeAssumedBits(NO_READS);
8226 if (I.mayWriteToMemory())
8227 removeAssumedBits(NO_WRITES);
8228 return !isAtFixpoint();
8229 };
8230
8231 bool UsedAssumedInformation = false;
8232 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8233 UsedAssumedInformation))
8234 return indicatePessimisticFixpoint();
8235
8236 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8238}
8239
8240ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8241
8242 const IRPosition &IRP = getIRPosition();
8243 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8244 AAMemoryBehavior::StateType &S = getState();
8245
8246 // First, check the function scope. We take the known information and we avoid
8247 // work if the assumed information implies the current assumed information for
8248 // this attribute. This is a valid for all but byval arguments.
8249 Argument *Arg = IRP.getAssociatedArgument();
8250 AAMemoryBehavior::base_t FnMemAssumedState =
8252 if (!Arg || !Arg->hasByValAttr()) {
8253 const auto *FnMemAA =
8254 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8255 if (FnMemAA) {
8256 FnMemAssumedState = FnMemAA->getAssumed();
8257 S.addKnownBits(FnMemAA->getKnown());
8258 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8260 }
8261 }
8262
8263 // The current assumed state used to determine a change.
8264 auto AssumedState = S.getAssumed();
8265
8266 // Make sure the value is not captured (except through "return"), if
8267 // it is, any information derived would be irrelevant anyway as we cannot
8268 // check the potential aliases introduced by the capture. However, no need
8269 // to fall back to anythign less optimistic than the function state.
8270 bool IsKnownNoCapture;
8271 const AANoCapture *ArgNoCaptureAA = nullptr;
8272 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8273 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8274 &ArgNoCaptureAA);
8275
8276 if (!IsAssumedNoCapture &&
8277 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8278 S.intersectAssumedBits(FnMemAssumedState);
8279 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8281 }
8282
8283 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8284 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8285 Instruction *UserI = cast<Instruction>(U.getUser());
8286 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8287 << " \n");
8288
8289 // Droppable users, e.g., llvm::assume does not actually perform any action.
8290 if (UserI->isDroppable())
8291 return true;
8292
8293 // Check if the users of UserI should also be visited.
8294 Follow = followUsersOfUseIn(A, U, UserI);
8295
8296 // If UserI might touch memory we analyze the use in detail.
8297 if (UserI->mayReadOrWriteMemory())
8298 analyzeUseIn(A, U, UserI);
8299
8300 return !isAtFixpoint();
8301 };
8302
8303 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8304 return indicatePessimisticFixpoint();
8305
8306 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8308}
8309
8310bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8311 const Instruction *UserI) {
8312 // The loaded value is unrelated to the pointer argument, no need to
8313 // follow the users of the load.
8314 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8315 return false;
8316
8317 // By default we follow all uses assuming UserI might leak information on U,
8318 // we have special handling for call sites operands though.
8319 const auto *CB = dyn_cast<CallBase>(UserI);
8320 if (!CB || !CB->isArgOperand(&U))
8321 return true;
8322
8323 // If the use is a call argument known not to be captured, the users of
8324 // the call do not need to be visited because they have to be unrelated to
8325 // the input. Note that this check is not trivial even though we disallow
8326 // general capturing of the underlying argument. The reason is that the
8327 // call might the argument "through return", which we allow and for which we
8328 // need to check call users.
8329 if (U.get()->getType()->isPointerTy()) {
8330 unsigned ArgNo = CB->getArgOperandNo(&U);
8331 bool IsKnownNoCapture;
8333 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8334 DepClassTy::OPTIONAL, IsKnownNoCapture);
8335 }
8336
8337 return true;
8338}
8339
8340void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8341 const Instruction *UserI) {
8342 assert(UserI->mayReadOrWriteMemory());
8343
8344 switch (UserI->getOpcode()) {
8345 default:
8346 // TODO: Handle all atomics and other side-effect operations we know of.
8347 break;
8348 case Instruction::Load:
8349 // Loads cause the NO_READS property to disappear.
8350 removeAssumedBits(NO_READS);
8351 return;
8352
8353 case Instruction::Store:
8354 // Stores cause the NO_WRITES property to disappear if the use is the
8355 // pointer operand. Note that while capturing was taken care of somewhere
8356 // else we need to deal with stores of the value that is not looked through.
8357 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8358 removeAssumedBits(NO_WRITES);
8359 else
8360 indicatePessimisticFixpoint();
8361 return;
8362
8363 case Instruction::Call:
8364 case Instruction::CallBr:
8365 case Instruction::Invoke: {
8366 // For call sites we look at the argument memory behavior attribute (this
8367 // could be recursive!) in order to restrict our own state.
8368 const auto *CB = cast<CallBase>(UserI);
8369
8370 // Give up on operand bundles.
8371 if (CB->isBundleOperand(&U)) {
8372 indicatePessimisticFixpoint();
8373 return;
8374 }
8375
8376 // Calling a function does read the function pointer, maybe write it if the
8377 // function is self-modifying.
8378 if (CB->isCallee(&U)) {
8379 removeAssumedBits(NO_READS);
8380 break;
8381 }
8382
8383 // Adjust the possible access behavior based on the information on the
8384 // argument.
8385 IRPosition Pos;
8386 if (U.get()->getType()->isPointerTy())
8388 else
8390 const auto *MemBehaviorAA =
8391 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8392 if (!MemBehaviorAA)
8393 break;
8394 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8395 // and at least "known".
8396 intersectAssumedBits(MemBehaviorAA->getAssumed());
8397 return;
8398 }
8399 };
8400
8401 // Generally, look at the "may-properties" and adjust the assumed state if we
8402 // did not trigger special handling before.
8403 if (UserI->mayReadFromMemory())
8404 removeAssumedBits(NO_READS);
8405 if (UserI->mayWriteToMemory())
8406 removeAssumedBits(NO_WRITES);
8407}
8408} // namespace
8409
8410/// -------------------- Memory Locations Attributes ---------------------------
8411/// Includes read-none, argmemonly, inaccessiblememonly,
8412/// inaccessiblememorargmemonly
8413/// ----------------------------------------------------------------------------
8414
8417 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8418 return "all memory";
8420 return "no memory";
8421 std::string S = "memory:";
8422 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8423 S += "stack,";
8424 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8425 S += "constant,";
8427 S += "internal global,";
8429 S += "external global,";
8430 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8431 S += "argument,";
8433 S += "inaccessible,";
8434 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8435 S += "malloced,";
8436 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8437 S += "unknown,";
8438 S.pop_back();
8439 return S;
8440}
8441
8442namespace {
8443struct AAMemoryLocationImpl : public AAMemoryLocation {
8444
8445 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8446 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8447 AccessKind2Accesses.fill(nullptr);
8448 }
8449
8450 ~AAMemoryLocationImpl() override {
8451 // The AccessSets are allocated via a BumpPtrAllocator, we call
8452 // the destructor manually.
8453 for (AccessSet *AS : AccessKind2Accesses)
8454 if (AS)
8455 AS->~AccessSet();
8456 }
8457
8458 /// See AbstractAttribute::initialize(...).
8459 void initialize(Attributor &A) override {
8460 intersectAssumedBits(BEST_STATE);
8461 getKnownStateFromValue(A, getIRPosition(), getState());
8462 AAMemoryLocation::initialize(A);
8463 }
8464
8465 /// Return the memory behavior information encoded in the IR for \p IRP.
8466 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8467 BitIntegerState &State,
8468 bool IgnoreSubsumingPositions = false) {
8469 // For internal functions we ignore `argmemonly` and
8470 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8471 // constant propagation. It is unclear if this is the best way but it is
8472 // unlikely this will cause real performance problems. If we are deriving
8473 // attributes for the anchor function we even remove the attribute in
8474 // addition to ignoring it.
8475 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8476 // MemoryEffects::Other as a possible location.
8477 bool UseArgMemOnly = true;
8478 Function *AnchorFn = IRP.getAnchorScope();
8479 if (AnchorFn && A.isRunOn(*AnchorFn))
8480 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8481
8483 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8484 for (const Attribute &Attr : Attrs) {
8485 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8486 MemoryEffects ME = Attr.getMemoryEffects();
8487 if (ME.doesNotAccessMemory()) {
8488 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8489 continue;
8490 }
8491 if (ME.onlyAccessesInaccessibleMem()) {
8492 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8493 continue;
8494 }
8495 if (ME.onlyAccessesArgPointees()) {
8496 if (UseArgMemOnly)
8497 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8498 else {
8499 // Remove location information, only keep read/write info.
8500 ME = MemoryEffects(ME.getModRef());
8501 A.manifestAttrs(IRP,
8502 Attribute::getWithMemoryEffects(
8503 IRP.getAnchorValue().getContext(), ME),
8504 /*ForceReplace*/ true);
8505 }
8506 continue;
8507 }
8509 if (UseArgMemOnly)
8510 State.addKnownBits(inverseLocation(
8511 NO_INACCESSIBLE_MEM | 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 }
8522 }
8523 }
8524
8525 /// See AbstractAttribute::getDeducedAttributes(...).
8526 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8527 SmallVectorImpl<Attribute> &Attrs) const override {
8528 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8529 assert(Attrs.size() == 0);
8530 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8531 if (isAssumedReadNone())
8532 Attrs.push_back(
8533 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8534 else if (isAssumedInaccessibleMemOnly())
8535 Attrs.push_back(Attribute::getWithMemoryEffects(
8537 else if (isAssumedArgMemOnly())
8538 Attrs.push_back(
8539 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8540 else if (isAssumedInaccessibleOrArgMemOnly())
8541 Attrs.push_back(Attribute::getWithMemoryEffects(
8543 }
8544 assert(Attrs.size() <= 1);
8545 }
8546
8547 /// See AbstractAttribute::manifest(...).
8548 ChangeStatus manifest(Attributor &A) override {
8549 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8550 // provide per-location modref information here.
8551 const IRPosition &IRP = getIRPosition();
8552
8553 SmallVector<Attribute, 1> DeducedAttrs;
8554 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8555 if (DeducedAttrs.size() != 1)
8556 return ChangeStatus::UNCHANGED;
8557 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8558
8559 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8560 IRP.getAnchorValue().getContext(), ME));
8561 }
8562
8563 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8564 bool checkForAllAccessesToMemoryKind(
8565 function_ref<bool(const Instruction *, const Value *, AccessKind,
8566 MemoryLocationsKind)>
8567 Pred,
8568 MemoryLocationsKind RequestedMLK) const override {
8569 if (!isValidState())
8570 return false;
8571
8572 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8573 if (AssumedMLK == NO_LOCATIONS)
8574 return true;
8575
8576 unsigned Idx = 0;
8577 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8578 CurMLK *= 2, ++Idx) {
8579 if (CurMLK & RequestedMLK)
8580 continue;
8581
8582 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8583 for (const AccessInfo &AI : *Accesses)
8584 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8585 return false;
8586 }
8587
8588 return true;
8589 }
8590
8591 ChangeStatus indicatePessimisticFixpoint() override {
8592 // If we give up and indicate a pessimistic fixpoint this instruction will
8593 // become an access for all potential access kinds:
8594 // TODO: Add pointers for argmemonly and globals to improve the results of
8595 // checkForAllAccessesToMemoryKind.
8596 bool Changed = false;
8597 MemoryLocationsKind KnownMLK = getKnown();
8598 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8599 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8600 if (!(CurMLK & KnownMLK))
8601 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8602 getAccessKindFromInst(I));
8603 return AAMemoryLocation::indicatePessimisticFixpoint();
8604 }
8605
8606protected:
8607 /// Helper struct to tie together an instruction that has a read or write
8608 /// effect with the pointer it accesses (if any).
8609 struct AccessInfo {
8610
8611 /// The instruction that caused the access.
8612 const Instruction *I;
8613
8614 /// The base pointer that is accessed, or null if unknown.
8615 const Value *Ptr;
8616
8617 /// The kind of access (read/write/read+write).
8619
8620 bool operator==(const AccessInfo &RHS) const {
8621 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8622 }
8623 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8624 if (LHS.I != RHS.I)
8625 return LHS.I < RHS.I;
8626 if (LHS.Ptr != RHS.Ptr)
8627 return LHS.Ptr < RHS.Ptr;
8628 if (LHS.Kind != RHS.Kind)
8629 return LHS.Kind < RHS.Kind;
8630 return false;
8631 }
8632 };
8633
8634 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8635 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8636 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8637 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8638 AccessKind2Accesses;
8639
8640 /// Categorize the pointer arguments of CB that might access memory in
8641 /// AccessedLoc and update the state and access map accordingly.
8642 void
8643 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8644 AAMemoryLocation::StateType &AccessedLocs,
8645 bool &Changed);
8646
8647 /// Return the kind(s) of location that may be accessed by \p V.
8649 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8650
8651 /// Return the access kind as determined by \p I.
8652 AccessKind getAccessKindFromInst(const Instruction *I) {
8653 AccessKind AK = READ_WRITE;
8654 if (I) {
8655 AK = I->mayReadFromMemory() ? READ : NONE;
8656 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8657 }
8658 return AK;
8659 }
8660
8661 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8662 /// an access of kind \p AK to a \p MLK memory location with the access
8663 /// pointer \p Ptr.
8664 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8665 MemoryLocationsKind MLK, const Instruction *I,
8666 const Value *Ptr, bool &Changed,
8667 AccessKind AK = READ_WRITE) {
8668
8669 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8670 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8671 if (!Accesses)
8672 Accesses = new (Allocator) AccessSet();
8673 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8674 if (MLK == NO_UNKOWN_MEM)
8675 MLK = NO_LOCATIONS;
8676 State.removeAssumedBits(MLK);
8677 }
8678
8679 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8680 /// arguments, and update the state and access map accordingly.
8681 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8682 AAMemoryLocation::StateType &State, bool &Changed,
8683 unsigned AccessAS = 0);
8684
8685 /// Used to allocate access sets.
8687};
8688
8689void AAMemoryLocationImpl::categorizePtrValue(
8690 Attributor &A, const Instruction &I, const Value &Ptr,
8691 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8692 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8693 << Ptr << " ["
8694 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8695
8696 auto Pred = [&](Value &Obj) {
8697 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8698 // TODO: recognize the TBAA used for constant accesses.
8699 MemoryLocationsKind MLK = NO_LOCATIONS;
8700
8701 // Filter accesses to constant (GPU) memory if we have an AS at the access
8702 // site or the object is known to actually have the associated AS.
8703 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8704 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8705 isIdentifiedObject(&Obj))) &&
8706 AA::isGPU(*I.getModule()))
8707 return true;
8708
8709 if (isa<UndefValue>(&Obj))
8710 return true;
8711 if (isa<Argument>(&Obj)) {
8712 // TODO: For now we do not treat byval arguments as local copies performed
8713 // on the call edge, though, we should. To make that happen we need to
8714 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8715 // would also allow us to mark functions only accessing byval arguments as
8716 // readnone again, arguably their accesses have no effect outside of the
8717 // function, like accesses to allocas.
8718 MLK = NO_ARGUMENT_MEM;
8719 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8720 // Reading constant memory is not treated as a read "effect" by the
8721 // function attr pass so we won't neither. Constants defined by TBAA are
8722 // similar. (We know we do not write it because it is constant.)
8723 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8724 if (GVar->isConstant())
8725 return true;
8726
8727 if (GV->hasLocalLinkage())
8728 MLK = NO_GLOBAL_INTERNAL_MEM;
8729 else
8730 MLK = NO_GLOBAL_EXTERNAL_MEM;
8731 } else if (isa<ConstantPointerNull>(&Obj) &&
8732 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8733 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8734 return true;
8735 } else if (isa<AllocaInst>(&Obj)) {
8736 MLK = NO_LOCAL_MEM;
8737 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8738 bool IsKnownNoAlias;
8741 IsKnownNoAlias))
8742 MLK = NO_MALLOCED_MEM;
8743 else
8744 MLK = NO_UNKOWN_MEM;
8745 } else {
8746 MLK = NO_UNKOWN_MEM;
8747 }
8748
8749 assert(MLK != NO_LOCATIONS && "No location specified!");
8750 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8751 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8752 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8753 getAccessKindFromInst(&I));
8754
8755 return true;
8756 };
8757
8758 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8760 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8761 LLVM_DEBUG(
8762 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8763 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8764 getAccessKindFromInst(&I));
8765 return;
8766 }
8767
8768 LLVM_DEBUG(
8769 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8770 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8771}
8772
8773void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8774 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8775 bool &Changed) {
8776 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8777
8778 // Skip non-pointer arguments.
8779 const Value *ArgOp = CB.getArgOperand(ArgNo);
8780 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8781 continue;
8782
8783 // Skip readnone arguments.
8784 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8785 const auto *ArgOpMemLocationAA =
8786 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8787
8788 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8789 continue;
8790
8791 // Categorize potentially accessed pointer arguments as if there was an
8792 // access instruction with them as pointer.
8793 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8794 }
8795}
8796
8798AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8799 bool &Changed) {
8800 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8801 << I << "\n");
8802
8803 AAMemoryLocation::StateType AccessedLocs;
8804 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8805
8806 if (auto *CB = dyn_cast<CallBase>(&I)) {
8807
8808 // First check if we assume any memory is access is visible.
8809 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8811 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8812 << " [" << CBMemLocationAA << "]\n");
8813 if (!CBMemLocationAA) {
8814 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8815 Changed, getAccessKindFromInst(&I));
8816 return NO_UNKOWN_MEM;
8817 }
8818
8819 if (CBMemLocationAA->isAssumedReadNone())
8820 return NO_LOCATIONS;
8821
8822 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8823 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8824 Changed, getAccessKindFromInst(&I));
8825 return AccessedLocs.getAssumed();
8826 }
8827
8828 uint32_t CBAssumedNotAccessedLocs =
8829 CBMemLocationAA->getAssumedNotAccessedLocation();
8830
8831 // Set the argmemonly and global bit as we handle them separately below.
8832 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8833 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8834
8835 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8836 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8837 continue;
8838 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8839 getAccessKindFromInst(&I));
8840 }
8841
8842 // Now handle global memory if it might be accessed. This is slightly tricky
8843 // as NO_GLOBAL_MEM has multiple bits set.
8844 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8845 if (HasGlobalAccesses) {
8846 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8847 AccessKind Kind, MemoryLocationsKind MLK) {
8848 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8849 getAccessKindFromInst(&I));
8850 return true;
8851 };
8852 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8853 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8854 return AccessedLocs.getWorstState();
8855 }
8856
8857 LLVM_DEBUG(
8858 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8859 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8860
8861 // Now handle argument memory if it might be accessed.
8862 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8863 if (HasArgAccesses)
8864 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8865
8866 LLVM_DEBUG(
8867 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8868 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8869
8870 return AccessedLocs.getAssumed();
8871 }
8872
8873 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8874 LLVM_DEBUG(
8875 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8876 << I << " [" << *Ptr << "]\n");
8877 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8878 Ptr->getType()->getPointerAddressSpace());
8879 return AccessedLocs.getAssumed();
8880 }
8881
8882 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8883 << I << "\n");
8884 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8885 getAccessKindFromInst(&I));
8886 return AccessedLocs.getAssumed();
8887}
8888
8889/// An AA to represent the memory behavior function attributes.
8890struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8891 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8892 : AAMemoryLocationImpl(IRP, A) {}
8893
8894 /// See AbstractAttribute::updateImpl(Attributor &A).
8895 ChangeStatus updateImpl(Attributor &A) override {
8896
8897 const auto *MemBehaviorAA =
8898 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8899 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8900 if (MemBehaviorAA->isKnownReadNone())
8901 return indicateOptimisticFixpoint();
8903 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8904 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8905 return ChangeStatus::UNCHANGED;
8906 }
8907
8908 // The current assumed state used to determine a change.
8909 auto AssumedState = getAssumed();
8910 bool Changed = false;
8911
8912 auto CheckRWInst = [&](Instruction &I) {
8913 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8914 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8915 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8916 removeAssumedBits(inverseLocation(MLK, false, false));
8917 // Stop once only the valid bit set in the *not assumed location*, thus
8918 // once we don't actually exclude any memory locations in the state.
8919 return getAssumedNotAccessedLocation() != VALID_STATE;
8920 };
8921
8922 bool UsedAssumedInformation = false;
8923 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8924 UsedAssumedInformation))
8925 return indicatePessimisticFixpoint();
8926
8927 Changed |= AssumedState != getAssumed();
8928 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8929 }
8930
8931 /// See AbstractAttribute::trackStatistics()
8932 void trackStatistics() const override {
8933 if (isAssumedReadNone())
8934 STATS_DECLTRACK_FN_ATTR(readnone)
8935 else if (isAssumedArgMemOnly())
8936 STATS_DECLTRACK_FN_ATTR(argmemonly)
8937 else if (isAssumedInaccessibleMemOnly())
8938 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8939 else if (isAssumedInaccessibleOrArgMemOnly())
8940 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8941 }
8942};
8943
8944/// AAMemoryLocation attribute for call sites.
8945struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8946 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8947 : AAMemoryLocationImpl(IRP, A) {}
8948
8949 /// See AbstractAttribute::updateImpl(...).
8950 ChangeStatus updateImpl(Attributor &A) override {
8951 // TODO: Once we have call site specific value information we can provide
8952 // call site specific liveness liveness information and then it makes
8953 // sense to specialize attributes for call sites arguments instead of
8954 // redirecting requests to the callee argument.
8955 Function *F = getAssociatedFunction();
8956 const IRPosition &FnPos = IRPosition::function(*F);
8957 auto *FnAA =
8958 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8959 if (!FnAA)
8960 return indicatePessimisticFixpoint();
8961 bool Changed = false;
8962 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8963 AccessKind Kind, MemoryLocationsKind MLK) {
8964 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8965 getAccessKindFromInst(I));
8966 return true;
8967 };
8968 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8969 return indicatePessimisticFixpoint();
8970 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8971 }
8972
8973 /// See AbstractAttribute::trackStatistics()
8974 void trackStatistics() const override {
8975 if (isAssumedReadNone())
8976 STATS_DECLTRACK_CS_ATTR(readnone)
8977 }
8978};
8979} // namespace
8980
8981/// ------------------ denormal-fp-math Attribute -------------------------
8982
8983namespace {
8984struct AADenormalFPMathImpl : public AADenormalFPMath {
8985 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8986 : AADenormalFPMath(IRP, A) {}
8987
8988 const std::string getAsStr(Attributor *A) const override {
8989 std::string Str("AADenormalFPMath[");
8990 raw_string_ostream OS(Str);
8991
8992 DenormalState Known = getKnown();
8993 if (Known.Mode.isValid())
8994 OS << "denormal-fp-math=" << Known.Mode;
8995 else
8996 OS << "invalid";
8997
8998 if (Known.ModeF32.isValid())
8999 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9000 OS << ']';
9001 return Str;
9002 }
9003};
9004
9005struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9006 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9007 : AADenormalFPMathImpl(IRP, A) {}
9008
9009 void initialize(Attributor &A) override {
9010 const Function *F = getAnchorScope();
9011 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9012
9013 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9014 if (isModeFixed())
9015 indicateFixpoint();
9016 }
9017
9018 ChangeStatus updateImpl(Attributor &A) override {
9019 ChangeStatus Change = ChangeStatus::UNCHANGED;
9020
9021 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9022 Function *Caller = CS.getInstruction()->getFunction();
9023 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9024 << "->" << getAssociatedFunction()->getName() << '\n');
9025
9026 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9027 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9028 if (!CallerInfo)
9029 return false;
9030
9031 Change = Change | clampStateAndIndicateChange(this->getState(),
9032 CallerInfo->getState());
9033 return true;
9034 };
9035
9036 bool AllCallSitesKnown = true;
9037 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9038 return indicatePessimisticFixpoint();
9039
9040 if (Change == ChangeStatus::CHANGED && isModeFixed())
9041 indicateFixpoint();
9042 return Change;
9043 }
9044
9045 ChangeStatus manifest(Attributor &A) override {
9046 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9047
9048 SmallVector<Attribute, 2> AttrToAdd;
9050
9051 // TODO: Change to use DenormalFPEnv everywhere.
9052 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9053
9054 if (KnownEnv == DenormalFPEnv::getDefault()) {
9055 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9056 } else {
9057 AttrToAdd.push_back(Attribute::get(
9058 Ctx, Attribute::DenormalFPEnv,
9059 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9060 }
9061
9062 auto &IRP = getIRPosition();
9063
9064 // TODO: There should be a combined add and remove API.
9065 return A.removeAttrs(IRP, AttrToRemove) |
9066 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9067 }
9068
9069 void trackStatistics() const override {
9070 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9071 }
9072};
9073} // namespace
9074
9075/// ------------------ Value Constant Range Attribute -------------------------
9076
9077namespace {
9078struct AAValueConstantRangeImpl : AAValueConstantRange {
9079 using StateType = IntegerRangeState;
9080 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9081 : AAValueConstantRange(IRP, A) {}
9082
9083 /// See AbstractAttribute::initialize(..).
9084 void initialize(Attributor &A) override {
9085 if (A.hasSimplificationCallback(getIRPosition())) {
9086 indicatePessimisticFixpoint();
9087 return;
9088 }
9089
9090 // Intersect a range given by SCEV.
9091 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9092
9093 // Intersect a range given by LVI.
9094 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9095 }
9096
9097 /// See AbstractAttribute::getAsStr().
9098 const std::string getAsStr(Attributor *A) const override {
9099 std::string Str;
9100 llvm::raw_string_ostream OS(Str);
9101 OS << "range(" << getBitWidth() << ")<";
9102 getKnown().print(OS);
9103 OS << " / ";
9104 getAssumed().print(OS);
9105 OS << ">";
9106 return Str;
9107 }
9108
9109 /// Helper function to get a SCEV expr for the associated value at program
9110 /// point \p I.
9111 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9112 if (!getAnchorScope())
9113 return nullptr;
9114
9115 ScalarEvolution *SE =
9116 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9117 *getAnchorScope());
9118
9119 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9120 *getAnchorScope());
9121
9122 if (!SE || !LI)
9123 return nullptr;
9124
9125 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9126 if (!I)
9127 return S;
9128
9129 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9130 }
9131
9132 /// Helper function to get a range from SCEV for the associated value at
9133 /// program point \p I.
9134 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9135 const Instruction *I = nullptr) const {
9136 if (!getAnchorScope())
9137 return getWorstState(getBitWidth());
9138
9139 ScalarEvolution *SE =
9140 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9141 *getAnchorScope());
9142
9143 const SCEV *S = getSCEV(A, I);
9144 if (!SE || !S)
9145 return getWorstState(getBitWidth());
9146
9147 return SE->getUnsignedRange(S);
9148 }
9149
9150 /// Helper function to get a range from LVI for the associated value at
9151 /// program point \p I.
9152 ConstantRange
9153 getConstantRangeFromLVI(Attributor &A,
9154 const Instruction *CtxI = nullptr) const {
9155 if (!getAnchorScope())
9156 return getWorstState(getBitWidth());
9157
9158 LazyValueInfo *LVI =
9159 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9160 *getAnchorScope());
9161
9162 if (!LVI || !CtxI)
9163 return getWorstState(getBitWidth());
9164 return LVI->getConstantRange(&getAssociatedValue(),
9165 const_cast<Instruction *>(CtxI),
9166 /*UndefAllowed*/ false);
9167 }
9168
9169 /// Return true if \p CtxI is valid for querying outside analyses.
9170 /// This basically makes sure we do not ask intra-procedural analysis
9171 /// about a context in the wrong function or a context that violates
9172 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9173 /// if the original context of this AA is OK or should be considered invalid.
9174 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9175 const Instruction *CtxI,
9176 bool AllowAACtxI) const {
9177 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9178 return false;
9179
9180 // Our context might be in a different function, neither intra-procedural
9181 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9182 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9183 return false;
9184
9185 // If the context is not dominated by the value there are paths to the
9186 // context that do not define the value. This cannot be handled by
9187 // LazyValueInfo so we need to bail.
9188 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9189 InformationCache &InfoCache = A.getInfoCache();
9190 const DominatorTree *DT =
9191 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9192 *I->getFunction());
9193 return DT && DT->dominates(I, CtxI);
9194 }
9195
9196 return true;
9197 }
9198
9199 /// See AAValueConstantRange::getKnownConstantRange(..).
9200 ConstantRange
9201 getKnownConstantRange(Attributor &A,
9202 const Instruction *CtxI = nullptr) const override {
9203 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9204 /* AllowAACtxI */ false))
9205 return getKnown();
9206
9207 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9208 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9209 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9210 }
9211
9212 /// See AAValueConstantRange::getAssumedConstantRange(..).
9213 ConstantRange
9214 getAssumedConstantRange(Attributor &A,
9215 const Instruction *CtxI = nullptr) const override {
9216 // TODO: Make SCEV use Attributor assumption.
9217 // We may be able to bound a variable range via assumptions in
9218 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9219 // evolve to x^2 + x, then we can say that y is in [2, 12].
9220 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9221 /* AllowAACtxI */ false))
9222 return getAssumed();
9223
9224 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9225 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9226 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9227 }
9228
9229 /// Helper function to create MDNode for range metadata.
9230 static MDNode *
9231 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9232 const ConstantRange &AssumedConstantRange) {
9233 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9234 Ty, AssumedConstantRange.getLower())),
9235 ConstantAsMetadata::get(ConstantInt::get(
9236 Ty, AssumedConstantRange.getUpper()))};
9237 return MDNode::get(Ctx, LowAndHigh);
9238 }
9239
9240 /// Return true if \p Assumed is included in ranges from instruction \p I.
9241 static bool isBetterRange(const ConstantRange &Assumed,
9242 const Instruction &I) {
9243 if (Assumed.isFullSet())
9244 return false;
9245
9246 std::optional<ConstantRange> Known;
9247
9248 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9249 Known = CB->getRange();
9250 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9251 // If multiple ranges are annotated in IR, we give up to annotate assumed
9252 // range for now.
9253
9254 // TODO: If there exists a known range which containts assumed range, we
9255 // can say assumed range is better.
9256 if (KnownRanges->getNumOperands() > 2)
9257 return false;
9258
9259 ConstantInt *Lower =
9260 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9261 ConstantInt *Upper =
9262 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9263
9264 Known.emplace(Lower->getValue(), Upper->getValue());
9265 }
9266 return !Known || (*Known != Assumed && Known->contains(Assumed));
9267 }
9268
9269 /// Helper function to set range metadata.
9270 static bool
9271 setRangeMetadataIfisBetterRange(Instruction *I,
9272 const ConstantRange &AssumedConstantRange) {
9273 if (isBetterRange(AssumedConstantRange, *I)) {
9274 I->setMetadata(LLVMContext::MD_range,
9275 getMDNodeForConstantRange(I->getType(), I->getContext(),
9276 AssumedConstantRange));
9277 return true;
9278 }
9279 return false;
9280 }
9281 /// Helper function to set range return attribute.
9282 static bool
9283 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9284 Instruction *I,
9285 const ConstantRange &AssumedConstantRange) {
9286 if (isBetterRange(AssumedConstantRange, *I)) {
9287 A.manifestAttrs(IRP,
9288 Attribute::get(I->getContext(), Attribute::Range,
9289 AssumedConstantRange),
9290 /*ForceReplace*/ true);
9291 return true;
9292 }
9293 return false;
9294 }
9295
9296 /// See AbstractAttribute::manifest()
9297 ChangeStatus manifest(Attributor &A) override {
9298 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9299 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9300 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9301
9302 auto &V = getAssociatedValue();
9303 if (!AssumedConstantRange.isEmptySet() &&
9304 !AssumedConstantRange.isSingleElement()) {
9305 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9306 assert(I == getCtxI() && "Should not annotate an instruction which is "
9307 "not the context instruction");
9308 if (isa<LoadInst>(I))
9309 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9310 Changed = ChangeStatus::CHANGED;
9311 if (isa<CallInst>(I))
9312 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9313 AssumedConstantRange))
9314 Changed = ChangeStatus::CHANGED;
9315 }
9316 }
9317
9318 return Changed;
9319 }
9320};
9321
9322struct AAValueConstantRangeArgument final
9323 : AAArgumentFromCallSiteArguments<
9324 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9325 true /* BridgeCallBaseContext */> {
9326 using Base = AAArgumentFromCallSiteArguments<
9327 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9328 true /* BridgeCallBaseContext */>;
9329 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9330 : Base(IRP, A) {}
9331
9332 /// See AbstractAttribute::trackStatistics()
9333 void trackStatistics() const override {
9334 STATS_DECLTRACK_ARG_ATTR(value_range)
9335 }
9336};
9337
9338struct AAValueConstantRangeReturned
9339 : AAReturnedFromReturnedValues<AAValueConstantRange,
9340 AAValueConstantRangeImpl,
9341 AAValueConstantRangeImpl::StateType,
9342 /* PropagateCallBaseContext */ true> {
9343 using Base =
9344 AAReturnedFromReturnedValues<AAValueConstantRange,
9345 AAValueConstantRangeImpl,
9346 AAValueConstantRangeImpl::StateType,
9347 /* PropagateCallBaseContext */ true>;
9348 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9349 : Base(IRP, A) {}
9350
9351 /// See AbstractAttribute::initialize(...).
9352 void initialize(Attributor &A) override {
9353 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9354 indicatePessimisticFixpoint();
9355 }
9356
9357 /// See AbstractAttribute::trackStatistics()
9358 void trackStatistics() const override {
9359 STATS_DECLTRACK_FNRET_ATTR(value_range)
9360 }
9361};
9362
9363struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9364 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9365 : AAValueConstantRangeImpl(IRP, A) {}
9366
9367 /// See AbstractAttribute::initialize(...).
9368 void initialize(Attributor &A) override {
9369 AAValueConstantRangeImpl::initialize(A);
9370 if (isAtFixpoint())
9371 return;
9372
9373 Value &V = getAssociatedValue();
9374
9375 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9376 unionAssumed(ConstantRange(C->getValue()));
9377 indicateOptimisticFixpoint();
9378 return;
9379 }
9380
9381 if (isa<UndefValue>(&V)) {
9382 // Collapse the undef state to 0.
9383 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9384 indicateOptimisticFixpoint();
9385 return;
9386 }
9387
9388 if (isa<CallBase>(&V))
9389 return;
9390
9391 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9392 return;
9393
9394 // If it is a load instruction with range metadata, use it.
9395 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9396 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9397 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9398 return;
9399 }
9400
9401 // We can work with PHI and select instruction as we traverse their operands
9402 // during update.
9403 if (isa<SelectInst>(V) || isa<PHINode>(V))
9404 return;
9405
9406 // Otherwise we give up.
9407 indicatePessimisticFixpoint();
9408
9409 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9410 << getAssociatedValue() << "\n");
9411 }
9412
9413 bool calculateBinaryOperator(
9414 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9415 const Instruction *CtxI,
9416 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9417 Value *LHS = BinOp->getOperand(0);
9418 Value *RHS = BinOp->getOperand(1);
9419
9420 // Simplify the operands first.
9421 bool UsedAssumedInformation = false;
9422 const auto &SimplifiedLHS = A.getAssumedSimplified(
9423 IRPosition::value(*LHS, getCallBaseContext()), *this,
9424 UsedAssumedInformation, AA::Interprocedural);
9425 if (!SimplifiedLHS.has_value())
9426 return true;
9427 if (!*SimplifiedLHS)
9428 return false;
9429 LHS = *SimplifiedLHS;
9430
9431 const auto &SimplifiedRHS = A.getAssumedSimplified(
9432 IRPosition::value(*RHS, getCallBaseContext()), *this,
9433 UsedAssumedInformation, AA::Interprocedural);
9434 if (!SimplifiedRHS.has_value())
9435 return true;
9436 if (!*SimplifiedRHS)
9437 return false;
9438 RHS = *SimplifiedRHS;
9439
9440 // TODO: Allow non integers as well.
9441 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9442 return false;
9443
9444 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9445 *this, IRPosition::value(*LHS, getCallBaseContext()),
9446 DepClassTy::REQUIRED);
9447 if (!LHSAA)
9448 return false;
9449 QuerriedAAs.push_back(LHSAA);
9450 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9451
9452 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9453 *this, IRPosition::value(*RHS, getCallBaseContext()),
9454 DepClassTy::REQUIRED);
9455 if (!RHSAA)
9456 return false;
9457 QuerriedAAs.push_back(RHSAA);
9458 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9459
9460 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9461
9462 T.unionAssumed(AssumedRange);
9463
9464 // TODO: Track a known state too.
9465
9466 return T.isValidState();
9467 }
9468
9469 bool calculateCastInst(
9470 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9471 const Instruction *CtxI,
9472 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9473 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9474 // TODO: Allow non integers as well.
9475 Value *OpV = CastI->getOperand(0);
9476
9477 // Simplify the operand first.
9478 bool UsedAssumedInformation = false;
9479 const auto &SimplifiedOpV = A.getAssumedSimplified(
9480 IRPosition::value(*OpV, getCallBaseContext()), *this,
9481 UsedAssumedInformation, AA::Interprocedural);
9482 if (!SimplifiedOpV.has_value())
9483 return true;
9484 if (!*SimplifiedOpV)
9485 return false;
9486 OpV = *SimplifiedOpV;
9487
9488 if (!OpV->getType()->isIntegerTy())
9489 return false;
9490
9491 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9492 *this, IRPosition::value(*OpV, getCallBaseContext()),
9493 DepClassTy::REQUIRED);
9494 if (!OpAA)
9495 return false;
9496 QuerriedAAs.push_back(OpAA);
9497 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9498 getState().getBitWidth()));
9499 return T.isValidState();
9500 }
9501
9502 bool
9503 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9504 const Instruction *CtxI,
9505 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9506 Value *LHS = CmpI->getOperand(0);
9507 Value *RHS = CmpI->getOperand(1);
9508
9509 // Simplify the operands first.
9510 bool UsedAssumedInformation = false;
9511 const auto &SimplifiedLHS = A.getAssumedSimplified(
9512 IRPosition::value(*LHS, getCallBaseContext()), *this,
9513 UsedAssumedInformation, AA::Interprocedural);
9514 if (!SimplifiedLHS.has_value())
9515 return true;
9516 if (!*SimplifiedLHS)
9517 return false;
9518 LHS = *SimplifiedLHS;
9519
9520 const auto &SimplifiedRHS = A.getAssumedSimplified(
9521 IRPosition::value(*RHS, getCallBaseContext()), *this,
9522 UsedAssumedInformation, AA::Interprocedural);
9523 if (!SimplifiedRHS.has_value())
9524 return true;
9525 if (!*SimplifiedRHS)
9526 return false;
9527 RHS = *SimplifiedRHS;
9528
9529 // TODO: Allow non integers as well.
9530 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9531 return false;
9532
9533 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9534 *this, IRPosition::value(*LHS, getCallBaseContext()),
9535 DepClassTy::REQUIRED);
9536 if (!LHSAA)
9537 return false;
9538 QuerriedAAs.push_back(LHSAA);
9539 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9540 *this, IRPosition::value(*RHS, getCallBaseContext()),
9541 DepClassTy::REQUIRED);
9542 if (!RHSAA)
9543 return false;
9544 QuerriedAAs.push_back(RHSAA);
9545 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9546 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9547
9548 // If one of them is empty set, we can't decide.
9549 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9550 return true;
9551
9552 bool MustTrue = false, MustFalse = false;
9553
9554 auto AllowedRegion =
9556
9557 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9558 MustFalse = true;
9559
9560 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9561 MustTrue = true;
9562
9563 assert((!MustTrue || !MustFalse) &&
9564 "Either MustTrue or MustFalse should be false!");
9565
9566 if (MustTrue)
9567 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9568 else if (MustFalse)
9569 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9570 else
9571 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9572
9573 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9574 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9575 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9576 << *RHSAA);
9577
9578 // TODO: Track a known state too.
9579 return T.isValidState();
9580 }
9581
9582 /// See AbstractAttribute::updateImpl(...).
9583 ChangeStatus updateImpl(Attributor &A) override {
9584
9585 IntegerRangeState T(getBitWidth());
9586 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9588 if (!I || isa<CallBase>(I)) {
9589
9590 // Simplify the operand first.
9591 bool UsedAssumedInformation = false;
9592 const auto &SimplifiedOpV = A.getAssumedSimplified(
9593 IRPosition::value(V, getCallBaseContext()), *this,
9594 UsedAssumedInformation, AA::Interprocedural);
9595 if (!SimplifiedOpV.has_value())
9596 return true;
9597 if (!*SimplifiedOpV)
9598 return false;
9599 Value *VPtr = *SimplifiedOpV;
9600
9601 // If the value is not instruction, we query AA to Attributor.
9602 const auto *AA = A.getAAFor<AAValueConstantRange>(
9603 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9604 DepClassTy::REQUIRED);
9605
9606 // Clamp operator is not used to utilize a program point CtxI.
9607 if (AA)
9608 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9609 else
9610 return false;
9611
9612 return T.isValidState();
9613 }
9614
9616 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9617 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9618 return false;
9619 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9620 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9621 return false;
9622 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9623 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9624 return false;
9625 } else {
9626 // Give up with other instructions.
9627 // TODO: Add other instructions
9628
9629 T.indicatePessimisticFixpoint();
9630 return false;
9631 }
9632
9633 // Catch circular reasoning in a pessimistic way for now.
9634 // TODO: Check how the range evolves and if we stripped anything, see also
9635 // AADereferenceable or AAAlign for similar situations.
9636 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9637 if (QueriedAA != this)
9638 continue;
9639 // If we are in a stady state we do not need to worry.
9640 if (T.getAssumed() == getState().getAssumed())
9641 continue;
9642 T.indicatePessimisticFixpoint();
9643 }
9644
9645 return T.isValidState();
9646 };
9647
9648 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9649 return indicatePessimisticFixpoint();
9650
9651 // Ensure that long def-use chains can't cause circular reasoning either by
9652 // introducing a cutoff below.
9653 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9654 return ChangeStatus::UNCHANGED;
9655 if (++NumChanges > MaxNumChanges) {
9656 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9657 << " but only " << MaxNumChanges
9658 << " are allowed to avoid cyclic reasoning.");
9659 return indicatePessimisticFixpoint();
9660 }
9661 return ChangeStatus::CHANGED;
9662 }
9663
9664 /// See AbstractAttribute::trackStatistics()
9665 void trackStatistics() const override {
9667 }
9668
9669 /// Tracker to bail after too many widening steps of the constant range.
9670 int NumChanges = 0;
9671
9672 /// Upper bound for the number of allowed changes (=widening steps) for the
9673 /// constant range before we give up.
9674 static constexpr int MaxNumChanges = 5;
9675};
9676
9677struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9678 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9679 : AAValueConstantRangeImpl(IRP, A) {}
9680
9681 /// See AbstractAttribute::initialize(...).
9682 ChangeStatus updateImpl(Attributor &A) override {
9683 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9684 "not be called");
9685 }
9686
9687 /// See AbstractAttribute::trackStatistics()
9688 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9689};
9690
9691struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9692 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9693 : AAValueConstantRangeFunction(IRP, A) {}
9694
9695 /// See AbstractAttribute::trackStatistics()
9696 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9697};
9698
9699struct AAValueConstantRangeCallSiteReturned
9700 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9701 AAValueConstantRangeImpl::StateType,
9702 /* IntroduceCallBaseContext */ true> {
9703 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9704 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9705 AAValueConstantRangeImpl::StateType,
9706 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9707
9708 /// See AbstractAttribute::initialize(...).
9709 void initialize(Attributor &A) override {
9710 // If it is a call instruction with range attribute, use the range.
9711 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9712 if (std::optional<ConstantRange> Range = CI->getRange())
9713 intersectKnown(*Range);
9714 }
9715
9716 AAValueConstantRangeImpl::initialize(A);
9717 }
9718
9719 /// See AbstractAttribute::trackStatistics()
9720 void trackStatistics() const override {
9721 STATS_DECLTRACK_CSRET_ATTR(value_range)
9722 }
9723};
9724struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9725 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9726 : AAValueConstantRangeFloating(IRP, A) {}
9727
9728 /// See AbstractAttribute::manifest()
9729 ChangeStatus manifest(Attributor &A) override {
9730 return ChangeStatus::UNCHANGED;
9731 }
9732
9733 /// See AbstractAttribute::trackStatistics()
9734 void trackStatistics() const override {
9735 STATS_DECLTRACK_CSARG_ATTR(value_range)
9736 }
9737};
9738} // namespace
9739
9740/// ------------------ Potential Values Attribute -------------------------
9741
9742namespace {
9743struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9744 using StateType = PotentialConstantIntValuesState;
9745
9746 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9747 : AAPotentialConstantValues(IRP, A) {}
9748
9749 /// See AbstractAttribute::initialize(..).
9750 void initialize(Attributor &A) override {
9751 if (A.hasSimplificationCallback(getIRPosition()))
9752 indicatePessimisticFixpoint();
9753 else
9754 AAPotentialConstantValues::initialize(A);
9755 }
9756
9757 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9758 bool &ContainsUndef, bool ForSelf) {
9760 bool UsedAssumedInformation = false;
9761 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9762 UsedAssumedInformation)) {
9763 // Avoid recursion when the caller is computing constant values for this
9764 // IRP itself.
9765 if (ForSelf)
9766 return false;
9767 if (!IRP.getAssociatedType()->isIntegerTy())
9768 return false;
9769 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9770 *this, IRP, DepClassTy::REQUIRED);
9771 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9772 return false;
9773 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9774 S = PotentialValuesAA->getState().getAssumedSet();
9775 return true;
9776 }
9777
9778 // Copy all the constant values, except UndefValue. ContainsUndef is true
9779 // iff Values contains only UndefValue instances. If there are other known
9780 // constants, then UndefValue is dropped.
9781 ContainsUndef = false;
9782 for (auto &It : Values) {
9783 if (isa<UndefValue>(It.getValue())) {
9784 ContainsUndef = true;
9785 continue;
9786 }
9787 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9788 if (!CI)
9789 return false;
9790 S.insert(CI->getValue());
9791 }
9792 ContainsUndef &= S.empty();
9793
9794 return true;
9795 }
9796
9797 /// See AbstractAttribute::getAsStr().
9798 const std::string getAsStr(Attributor *A) const override {
9799 std::string Str;
9800 llvm::raw_string_ostream OS(Str);
9801 OS << getState();
9802 return Str;
9803 }
9804
9805 /// See AbstractAttribute::updateImpl(...).
9806 ChangeStatus updateImpl(Attributor &A) override {
9807 return indicatePessimisticFixpoint();
9808 }
9809};
9810
9811struct AAPotentialConstantValuesArgument final
9812 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9813 AAPotentialConstantValuesImpl,
9814 PotentialConstantIntValuesState> {
9815 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9816 AAPotentialConstantValuesImpl,
9818 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9819 : Base(IRP, A) {}
9820
9821 /// See AbstractAttribute::trackStatistics()
9822 void trackStatistics() const override {
9823 STATS_DECLTRACK_ARG_ATTR(potential_values)
9824 }
9825};
9826
9827struct AAPotentialConstantValuesReturned
9828 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9829 AAPotentialConstantValuesImpl> {
9830 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9831 AAPotentialConstantValuesImpl>;
9832 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9833 : Base(IRP, A) {}
9834
9835 void initialize(Attributor &A) override {
9836 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9837 indicatePessimisticFixpoint();
9838 Base::initialize(A);
9839 }
9840
9841 /// See AbstractAttribute::trackStatistics()
9842 void trackStatistics() const override {
9843 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9844 }
9845};
9846
9847struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9848 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9849 : AAPotentialConstantValuesImpl(IRP, A) {}
9850
9851 /// See AbstractAttribute::initialize(..).
9852 void initialize(Attributor &A) override {
9853 AAPotentialConstantValuesImpl::initialize(A);
9854 if (isAtFixpoint())
9855 return;
9856
9857 Value &V = getAssociatedValue();
9858
9859 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9860 unionAssumed(C->getValue());
9861 indicateOptimisticFixpoint();
9862 return;
9863 }
9864
9865 if (isa<UndefValue>(&V)) {
9866 unionAssumedWithUndef();
9867 indicateOptimisticFixpoint();
9868 return;
9869 }
9870
9871 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9872 return;
9873
9874 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9875 return;
9876
9877 indicatePessimisticFixpoint();
9878
9879 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9880 << getAssociatedValue() << "\n");
9881 }
9882
9883 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9884 const APInt &RHS) {
9885 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9886 }
9887
9888 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9889 uint32_t ResultBitWidth) {
9890 Instruction::CastOps CastOp = CI->getOpcode();
9891 switch (CastOp) {
9892 default:
9893 llvm_unreachable("unsupported or not integer cast");
9894 case Instruction::Trunc:
9895 return Src.trunc(ResultBitWidth);
9896 case Instruction::SExt:
9897 return Src.sext(ResultBitWidth);
9898 case Instruction::ZExt:
9899 return Src.zext(ResultBitWidth);
9900 case Instruction::BitCast:
9901 return Src;
9902 }
9903 }
9904
9905 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9906 const APInt &LHS, const APInt &RHS,
9907 bool &SkipOperation, bool &Unsupported) {
9908 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9909 // Unsupported is set to true when the binary operator is not supported.
9910 // SkipOperation is set to true when UB occur with the given operand pair
9911 // (LHS, RHS).
9912 // TODO: we should look at nsw and nuw keywords to handle operations
9913 // that create poison or undef value.
9914 switch (BinOpcode) {
9915 default:
9916 Unsupported = true;
9917 return LHS;
9918 case Instruction::Add:
9919 return LHS + RHS;
9920 case Instruction::Sub:
9921 return LHS - RHS;
9922 case Instruction::Mul:
9923 return LHS * RHS;
9924 case Instruction::UDiv:
9925 if (RHS.isZero()) {
9926 SkipOperation = true;
9927 return LHS;
9928 }
9929 return LHS.udiv(RHS);
9930 case Instruction::SDiv:
9931 if (RHS.isZero()) {
9932 SkipOperation = true;
9933 return LHS;
9934 }
9935 return LHS.sdiv(RHS);
9936 case Instruction::URem:
9937 if (RHS.isZero()) {
9938 SkipOperation = true;
9939 return LHS;
9940 }
9941 return LHS.urem(RHS);
9942 case Instruction::SRem:
9943 if (RHS.isZero()) {
9944 SkipOperation = true;
9945 return LHS;
9946 }
9947 return LHS.srem(RHS);
9948 case Instruction::Shl:
9949 return LHS.shl(RHS);
9950 case Instruction::LShr:
9951 return LHS.lshr(RHS);
9952 case Instruction::AShr:
9953 return LHS.ashr(RHS);
9954 case Instruction::And:
9955 return LHS & RHS;
9956 case Instruction::Or:
9957 return LHS | RHS;
9958 case Instruction::Xor:
9959 return LHS ^ RHS;
9960 }
9961 }
9962
9963 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9964 const APInt &LHS, const APInt &RHS) {
9965 bool SkipOperation = false;
9966 bool Unsupported = false;
9967 APInt Result =
9968 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9969 if (Unsupported)
9970 return false;
9971 // If SkipOperation is true, we can ignore this operand pair (L, R).
9972 if (!SkipOperation)
9973 unionAssumed(Result);
9974 return isValidState();
9975 }
9976
9977 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9978 auto AssumedBefore = getAssumed();
9979 Value *LHS = ICI->getOperand(0);
9980 Value *RHS = ICI->getOperand(1);
9981
9982 bool LHSContainsUndef = false, RHSContainsUndef = false;
9983 SetTy LHSAAPVS, RHSAAPVS;
9984 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9985 LHSContainsUndef, /* ForSelf */ false) ||
9986 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9987 RHSContainsUndef, /* ForSelf */ false))
9988 return indicatePessimisticFixpoint();
9989
9990 // TODO: make use of undef flag to limit potential values aggressively.
9991 bool MaybeTrue = false, MaybeFalse = false;
9992 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9993 if (LHSContainsUndef && RHSContainsUndef) {
9994 // The result of any comparison between undefs can be soundly replaced
9995 // with undef.
9996 unionAssumedWithUndef();
9997 } else if (LHSContainsUndef) {
9998 for (const APInt &R : RHSAAPVS) {
9999 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10000 MaybeTrue |= CmpResult;
10001 MaybeFalse |= !CmpResult;
10002 if (MaybeTrue & MaybeFalse)
10003 return indicatePessimisticFixpoint();
10004 }
10005 } else if (RHSContainsUndef) {
10006 for (const APInt &L : LHSAAPVS) {
10007 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10008 MaybeTrue |= CmpResult;
10009 MaybeFalse |= !CmpResult;
10010 if (MaybeTrue & MaybeFalse)
10011 return indicatePessimisticFixpoint();
10012 }
10013 } else {
10014 for (const APInt &L : LHSAAPVS) {
10015 for (const APInt &R : RHSAAPVS) {
10016 bool CmpResult = calculateICmpInst(ICI, L, R);
10017 MaybeTrue |= CmpResult;
10018 MaybeFalse |= !CmpResult;
10019 if (MaybeTrue & MaybeFalse)
10020 return indicatePessimisticFixpoint();
10021 }
10022 }
10023 }
10024 if (MaybeTrue)
10025 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10026 if (MaybeFalse)
10027 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10028 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10029 : ChangeStatus::CHANGED;
10030 }
10031
10032 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10033 auto AssumedBefore = getAssumed();
10034 Value *LHS = SI->getTrueValue();
10035 Value *RHS = SI->getFalseValue();
10036
10037 bool UsedAssumedInformation = false;
10038 std::optional<Constant *> C = A.getAssumedConstant(
10039 *SI->getCondition(), *this, UsedAssumedInformation);
10040
10041 // Check if we only need one operand.
10042 bool OnlyLeft = false, OnlyRight = false;
10043 if (C && *C && (*C)->isOneValue())
10044 OnlyLeft = true;
10045 else if (C && *C && (*C)->isNullValue())
10046 OnlyRight = true;
10047
10048 bool LHSContainsUndef = false, RHSContainsUndef = false;
10049 SetTy LHSAAPVS, RHSAAPVS;
10050 if (!OnlyRight &&
10051 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10052 LHSContainsUndef, /* ForSelf */ false))
10053 return indicatePessimisticFixpoint();
10054
10055 if (!OnlyLeft &&
10056 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10057 RHSContainsUndef, /* ForSelf */ false))
10058 return indicatePessimisticFixpoint();
10059
10060 if (OnlyLeft || OnlyRight) {
10061 // select (true/false), lhs, rhs
10062 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10063 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10064
10065 if (Undef)
10066 unionAssumedWithUndef();
10067 else {
10068 for (const auto &It : *OpAA)
10069 unionAssumed(It);
10070 }
10071
10072 } else if (LHSContainsUndef && RHSContainsUndef) {
10073 // select i1 *, undef , undef => undef
10074 unionAssumedWithUndef();
10075 } else {
10076 for (const auto &It : LHSAAPVS)
10077 unionAssumed(It);
10078 for (const auto &It : RHSAAPVS)
10079 unionAssumed(It);
10080 }
10081 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10082 : ChangeStatus::CHANGED;
10083 }
10084
10085 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10086 auto AssumedBefore = getAssumed();
10087 if (!CI->isIntegerCast())
10088 return indicatePessimisticFixpoint();
10089 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10090 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10091 Value *Src = CI->getOperand(0);
10092
10093 bool SrcContainsUndef = false;
10094 SetTy SrcPVS;
10095 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10096 SrcContainsUndef, /* ForSelf */ false))
10097 return indicatePessimisticFixpoint();
10098
10099 if (SrcContainsUndef)
10100 unionAssumedWithUndef();
10101 else {
10102 for (const APInt &S : SrcPVS) {
10103 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10104 unionAssumed(T);
10105 }
10106 }
10107 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10108 : ChangeStatus::CHANGED;
10109 }
10110
10111 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10112 auto AssumedBefore = getAssumed();
10113 Value *LHS = BinOp->getOperand(0);
10114 Value *RHS = BinOp->getOperand(1);
10115
10116 bool LHSContainsUndef = false, RHSContainsUndef = false;
10117 SetTy LHSAAPVS, RHSAAPVS;
10118 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10119 LHSContainsUndef, /* ForSelf */ false) ||
10120 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10121 RHSContainsUndef, /* ForSelf */ false))
10122 return indicatePessimisticFixpoint();
10123
10124 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10125
10126 // TODO: make use of undef flag to limit potential values aggressively.
10127 if (LHSContainsUndef && RHSContainsUndef) {
10128 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10129 return indicatePessimisticFixpoint();
10130 } else if (LHSContainsUndef) {
10131 for (const APInt &R : RHSAAPVS) {
10132 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10133 return indicatePessimisticFixpoint();
10134 }
10135 } else if (RHSContainsUndef) {
10136 for (const APInt &L : LHSAAPVS) {
10137 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10138 return indicatePessimisticFixpoint();
10139 }
10140 } else {
10141 for (const APInt &L : LHSAAPVS) {
10142 for (const APInt &R : RHSAAPVS) {
10143 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10144 return indicatePessimisticFixpoint();
10145 }
10146 }
10147 }
10148 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10149 : ChangeStatus::CHANGED;
10150 }
10151
10152 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10153 auto AssumedBefore = getAssumed();
10154 SetTy Incoming;
10155 bool ContainsUndef;
10156 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10157 ContainsUndef, /* ForSelf */ true))
10158 return indicatePessimisticFixpoint();
10159 if (ContainsUndef) {
10160 unionAssumedWithUndef();
10161 } else {
10162 for (const auto &It : Incoming)
10163 unionAssumed(It);
10164 }
10165 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10166 : ChangeStatus::CHANGED;
10167 }
10168
10169 /// See AbstractAttribute::updateImpl(...).
10170 ChangeStatus updateImpl(Attributor &A) override {
10171 Value &V = getAssociatedValue();
10173
10174 if (auto *ICI = dyn_cast<ICmpInst>(I))
10175 return updateWithICmpInst(A, ICI);
10176
10177 if (auto *SI = dyn_cast<SelectInst>(I))
10178 return updateWithSelectInst(A, SI);
10179
10180 if (auto *CI = dyn_cast<CastInst>(I))
10181 return updateWithCastInst(A, CI);
10182
10183 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10184 return updateWithBinaryOperator(A, BinOp);
10185
10186 if (isa<PHINode>(I) || isa<LoadInst>(I))
10187 return updateWithInstruction(A, I);
10188
10189 return indicatePessimisticFixpoint();
10190 }
10191
10192 /// See AbstractAttribute::trackStatistics()
10193 void trackStatistics() const override {
10194 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10195 }
10196};
10197
10198struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10199 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10200 : AAPotentialConstantValuesImpl(IRP, A) {}
10201
10202 /// See AbstractAttribute::initialize(...).
10203 ChangeStatus updateImpl(Attributor &A) override {
10205 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10206 "not be called");
10207 }
10208
10209 /// See AbstractAttribute::trackStatistics()
10210 void trackStatistics() const override {
10211 STATS_DECLTRACK_FN_ATTR(potential_values)
10212 }
10213};
10214
10215struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10216 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10217 : AAPotentialConstantValuesFunction(IRP, A) {}
10218
10219 /// See AbstractAttribute::trackStatistics()
10220 void trackStatistics() const override {
10221 STATS_DECLTRACK_CS_ATTR(potential_values)
10222 }
10223};
10224
10225struct AAPotentialConstantValuesCallSiteReturned
10226 : AACalleeToCallSite<AAPotentialConstantValues,
10227 AAPotentialConstantValuesImpl> {
10228 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10229 Attributor &A)
10230 : AACalleeToCallSite<AAPotentialConstantValues,
10231 AAPotentialConstantValuesImpl>(IRP, A) {}
10232
10233 /// See AbstractAttribute::trackStatistics()
10234 void trackStatistics() const override {
10235 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10236 }
10237};
10238
10239struct AAPotentialConstantValuesCallSiteArgument
10240 : AAPotentialConstantValuesFloating {
10241 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10242 Attributor &A)
10243 : AAPotentialConstantValuesFloating(IRP, A) {}
10244
10245 /// See AbstractAttribute::initialize(..).
10246 void initialize(Attributor &A) override {
10247 AAPotentialConstantValuesImpl::initialize(A);
10248 if (isAtFixpoint())
10249 return;
10250
10251 Value &V = getAssociatedValue();
10252
10253 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10254 unionAssumed(C->getValue());
10255 indicateOptimisticFixpoint();
10256 return;
10257 }
10258
10259 if (isa<UndefValue>(&V)) {
10260 unionAssumedWithUndef();
10261 indicateOptimisticFixpoint();
10262 return;
10263 }
10264 }
10265
10266 /// See AbstractAttribute::updateImpl(...).
10267 ChangeStatus updateImpl(Attributor &A) override {
10268 Value &V = getAssociatedValue();
10269 auto AssumedBefore = getAssumed();
10270 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10271 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10272 if (!AA)
10273 return indicatePessimisticFixpoint();
10274 const auto &S = AA->getAssumed();
10275 unionAssumed(S);
10276 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10277 : ChangeStatus::CHANGED;
10278 }
10279
10280 /// See AbstractAttribute::trackStatistics()
10281 void trackStatistics() const override {
10282 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10283 }
10284};
10285} // namespace
10286
10287/// ------------------------ NoUndef Attribute ---------------------------------
10289 Attribute::AttrKind ImpliedAttributeKind,
10290 bool IgnoreSubsumingPositions) {
10291 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10292 "Unexpected attribute kind");
10293 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10294 Attribute::NoUndef))
10295 return true;
10296
10297 Value &Val = IRP.getAssociatedValue();
10300 LLVMContext &Ctx = Val.getContext();
10301 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10302 return true;
10303 }
10304
10305 return false;
10306}
10307
10308namespace {
10309struct AANoUndefImpl : AANoUndef {
10310 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10311
10312 /// See AbstractAttribute::initialize(...).
10313 void initialize(Attributor &A) override {
10314 Value &V = getAssociatedValue();
10315 if (isa<UndefValue>(V))
10316 indicatePessimisticFixpoint();
10317 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10318 }
10319
10320 /// See followUsesInMBEC
10321 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10322 AANoUndef::StateType &State) {
10323 const Value *UseV = U->get();
10324 const DominatorTree *DT = nullptr;
10325 AssumptionCache *AC = nullptr;
10326 InformationCache &InfoCache = A.getInfoCache();
10327 if (Function *F = getAnchorScope()) {
10328 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10329 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10330 }
10331 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10332 bool TrackUse = false;
10333 // Track use for instructions which must produce undef or poison bits when
10334 // at least one operand contains such bits.
10336 TrackUse = true;
10337 return TrackUse;
10338 }
10339
10340 /// See AbstractAttribute::getAsStr().
10341 const std::string getAsStr(Attributor *A) const override {
10342 return getAssumed() ? "noundef" : "may-undef-or-poison";
10343 }
10344
10345 ChangeStatus manifest(Attributor &A) override {
10346 // We don't manifest noundef attribute for dead positions because the
10347 // associated values with dead positions would be replaced with undef
10348 // values.
10349 bool UsedAssumedInformation = false;
10350 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10351 UsedAssumedInformation))
10352 return ChangeStatus::UNCHANGED;
10353 // A position whose simplified value does not have any value is
10354 // considered to be dead. We don't manifest noundef in such positions for
10355 // the same reason above.
10356 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10358 .has_value())
10359 return ChangeStatus::UNCHANGED;
10360 return AANoUndef::manifest(A);
10361 }
10362};
10363
10364struct AANoUndefFloating : public AANoUndefImpl {
10365 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10366 : AANoUndefImpl(IRP, A) {}
10367
10368 /// See AbstractAttribute::initialize(...).
10369 void initialize(Attributor &A) override {
10370 AANoUndefImpl::initialize(A);
10371 if (!getState().isAtFixpoint() && getAnchorScope() &&
10372 !getAnchorScope()->isDeclaration())
10373 if (Instruction *CtxI = getCtxI())
10374 followUsesInMBEC(*this, A, getState(), *CtxI);
10375 }
10376
10377 /// See AbstractAttribute::updateImpl(...).
10378 ChangeStatus updateImpl(Attributor &A) override {
10379 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10380 bool IsKnownNoUndef;
10382 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10383 };
10384
10385 bool Stripped;
10386 bool UsedAssumedInformation = false;
10387 Value *AssociatedValue = &getAssociatedValue();
10389 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10390 AA::AnyScope, UsedAssumedInformation))
10391 Stripped = false;
10392 else
10393 Stripped =
10394 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10395
10396 if (!Stripped) {
10397 // If we haven't stripped anything we might still be able to use a
10398 // different AA, but only if the IRP changes. Effectively when we
10399 // interpret this not as a call site value but as a floating/argument
10400 // value.
10401 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10402 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10403 return indicatePessimisticFixpoint();
10404 return ChangeStatus::UNCHANGED;
10405 }
10406
10407 for (const auto &VAC : Values)
10408 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10409 return indicatePessimisticFixpoint();
10410
10411 return ChangeStatus::UNCHANGED;
10412 }
10413
10414 /// See AbstractAttribute::trackStatistics()
10415 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10416};
10417
10418struct AANoUndefReturned final
10419 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10420 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10421 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10422
10423 /// See AbstractAttribute::trackStatistics()
10424 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10425};
10426
10427struct AANoUndefArgument final
10428 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10429 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10430 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10431
10432 /// See AbstractAttribute::trackStatistics()
10433 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10434};
10435
10436struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10437 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10438 : AANoUndefFloating(IRP, A) {}
10439
10440 /// See AbstractAttribute::trackStatistics()
10441 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10442};
10443
10444struct AANoUndefCallSiteReturned final
10445 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10446 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10447 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10448
10449 /// See AbstractAttribute::trackStatistics()
10450 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10451};
10452
10453/// ------------------------ NoFPClass Attribute -------------------------------
10454
10455struct AANoFPClassImpl : AANoFPClass {
10456 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10457
10458 void initialize(Attributor &A) override {
10459 const IRPosition &IRP = getIRPosition();
10460
10461 Value &V = IRP.getAssociatedValue();
10462 if (isa<UndefValue>(V)) {
10463 indicateOptimisticFixpoint();
10464 return;
10465 }
10466
10468 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10469 for (const auto &Attr : Attrs) {
10470 addKnownBits(Attr.getNoFPClass());
10471 }
10472
10473 Instruction *CtxI = getCtxI();
10474
10475 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10476 const DataLayout &DL = A.getDataLayout();
10477 InformationCache &InfoCache = A.getInfoCache();
10478
10479 const DominatorTree *DT = nullptr;
10480 AssumptionCache *AC = nullptr;
10481 const TargetLibraryInfo *TLI = nullptr;
10482 Function *F = getAnchorScope();
10483 if (F) {
10484 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10485 if (!F->isDeclaration()) {
10486 DT =
10487 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10488 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10489 }
10490 }
10491
10492 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10493
10494 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10495 addKnownBits(~KnownFPClass.KnownFPClasses);
10496 }
10497
10498 if (CtxI)
10499 followUsesInMBEC(*this, A, getState(), *CtxI);
10500 }
10501
10502 /// See followUsesInMBEC
10503 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10504 AANoFPClass::StateType &State) {
10505 // TODO: Determine what instructions can be looked through.
10506 auto *CB = dyn_cast<CallBase>(I);
10507 if (!CB)
10508 return false;
10509
10510 if (!CB->isArgOperand(U))
10511 return false;
10512
10513 unsigned ArgNo = CB->getArgOperandNo(U);
10514 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10515 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10516 State.addKnownBits(NoFPAA->getState().getKnown());
10517 return false;
10518 }
10519
10520 const std::string getAsStr(Attributor *A) const override {
10521 std::string Result = "nofpclass";
10522 raw_string_ostream OS(Result);
10523 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10524 return Result;
10525 }
10526
10527 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10528 SmallVectorImpl<Attribute> &Attrs) const override {
10529 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10530 }
10531};
10532
10533struct AANoFPClassFloating : public AANoFPClassImpl {
10534 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10535 : AANoFPClassImpl(IRP, A) {}
10536
10537 /// See AbstractAttribute::updateImpl(...).
10538 ChangeStatus updateImpl(Attributor &A) override {
10540 bool UsedAssumedInformation = false;
10541 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10542 AA::AnyScope, UsedAssumedInformation)) {
10543 Values.push_back({getAssociatedValue(), getCtxI()});
10544 }
10545
10546 StateType T;
10547 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10548 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10549 DepClassTy::REQUIRED);
10550 if (!AA || this == AA) {
10551 T.indicatePessimisticFixpoint();
10552 } else {
10553 const AANoFPClass::StateType &S =
10554 static_cast<const AANoFPClass::StateType &>(AA->getState());
10555 T ^= S;
10556 }
10557 return T.isValidState();
10558 };
10559
10560 for (const auto &VAC : Values)
10561 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10562 return indicatePessimisticFixpoint();
10563
10564 return clampStateAndIndicateChange(getState(), T);
10565 }
10566
10567 /// See AbstractAttribute::trackStatistics()
10568 void trackStatistics() const override {
10570 }
10571};
10572
10573struct AANoFPClassReturned final
10574 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10575 AANoFPClassImpl::StateType, false,
10576 Attribute::None, false> {
10577 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10578 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10579 AANoFPClassImpl::StateType, false,
10580 Attribute::None, false>(IRP, A) {}
10581
10582 /// See AbstractAttribute::trackStatistics()
10583 void trackStatistics() const override {
10585 }
10586};
10587
10588struct AANoFPClassArgument final
10589 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10590 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10591 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10592
10593 /// See AbstractAttribute::trackStatistics()
10594 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10595};
10596
10597struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10598 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10599 : AANoFPClassFloating(IRP, A) {}
10600
10601 /// See AbstractAttribute::trackStatistics()
10602 void trackStatistics() const override {
10604 }
10605};
10606
10607struct AANoFPClassCallSiteReturned final
10608 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10609 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10610 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10611
10612 /// See AbstractAttribute::trackStatistics()
10613 void trackStatistics() const override {
10615 }
10616};
10617
10618struct AACallEdgesImpl : public AACallEdges {
10619 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10620
10621 const SetVector<Function *> &getOptimisticEdges() const override {
10622 return CalledFunctions;
10623 }
10624
10625 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10626
10627 bool hasNonAsmUnknownCallee() const override {
10628 return HasUnknownCalleeNonAsm;
10629 }
10630
10631 const std::string getAsStr(Attributor *A) const override {
10632 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10633 std::to_string(CalledFunctions.size()) + "]";
10634 }
10635
10636 void trackStatistics() const override {}
10637
10638protected:
10639 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10640 if (CalledFunctions.insert(Fn)) {
10641 Change = ChangeStatus::CHANGED;
10642 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10643 << "\n");
10644 }
10645 }
10646
10647 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10648 if (!HasUnknownCallee)
10649 Change = ChangeStatus::CHANGED;
10650 if (NonAsm && !HasUnknownCalleeNonAsm)
10651 Change = ChangeStatus::CHANGED;
10652 HasUnknownCalleeNonAsm |= NonAsm;
10653 HasUnknownCallee = true;
10654 }
10655
10656private:
10657 /// Optimistic set of functions that might be called by this position.
10658 SetVector<Function *> CalledFunctions;
10659
10660 /// Is there any call with a unknown callee.
10661 bool HasUnknownCallee = false;
10662
10663 /// Is there any call with a unknown callee, excluding any inline asm.
10664 bool HasUnknownCalleeNonAsm = false;
10665};
10666
10667struct AACallEdgesCallSite : public AACallEdgesImpl {
10668 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10669 : AACallEdgesImpl(IRP, A) {}
10670 /// See AbstractAttribute::updateImpl(...).
10671 ChangeStatus updateImpl(Attributor &A) override {
10672 ChangeStatus Change = ChangeStatus::UNCHANGED;
10673
10674 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10675 if (Function *Fn = dyn_cast<Function>(&V)) {
10676 addCalledFunction(Fn, Change);
10677 } else {
10678 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10679 setHasUnknownCallee(true, Change);
10680 }
10681
10682 // Explore all values.
10683 return true;
10684 };
10685
10687 // Process any value that we might call.
10688 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10689 if (isa<Constant>(V)) {
10690 VisitValue(*V, CtxI);
10691 return;
10692 }
10693
10694 bool UsedAssumedInformation = false;
10695 Values.clear();
10696 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10697 AA::AnyScope, UsedAssumedInformation)) {
10698 Values.push_back({*V, CtxI});
10699 }
10700 for (auto &VAC : Values)
10701 VisitValue(*VAC.getValue(), VAC.getCtxI());
10702 };
10703
10704 CallBase *CB = cast<CallBase>(getCtxI());
10705
10706 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10707 if (IA->hasSideEffects() &&
10708 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10709 !hasAssumption(*CB, "ompx_no_call_asm")) {
10710 setHasUnknownCallee(false, Change);
10711 }
10712 return Change;
10713 }
10714
10715 if (CB->isIndirectCall())
10716 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10717 *this, getIRPosition(), DepClassTy::OPTIONAL))
10718 if (IndirectCallAA->foreachCallee(
10719 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10720 return Change;
10721
10722 // The most simple case.
10723 ProcessCalledOperand(CB->getCalledOperand(), CB);
10724
10725 // Process callback functions.
10726 SmallVector<const Use *, 4u> CallbackUses;
10727 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10728 for (const Use *U : CallbackUses)
10729 ProcessCalledOperand(U->get(), CB);
10730
10731 return Change;
10732 }
10733};
10734
10735struct AACallEdgesFunction : public AACallEdgesImpl {
10736 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10737 : AACallEdgesImpl(IRP, A) {}
10738
10739 /// See AbstractAttribute::updateImpl(...).
10740 ChangeStatus updateImpl(Attributor &A) override {
10741 ChangeStatus Change = ChangeStatus::UNCHANGED;
10742
10743 auto ProcessCallInst = [&](Instruction &Inst) {
10744 CallBase &CB = cast<CallBase>(Inst);
10745
10746 auto *CBEdges = A.getAAFor<AACallEdges>(
10747 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10748 if (!CBEdges)
10749 return false;
10750 if (CBEdges->hasNonAsmUnknownCallee())
10751 setHasUnknownCallee(true, Change);
10752 if (CBEdges->hasUnknownCallee())
10753 setHasUnknownCallee(false, Change);
10754
10755 for (Function *F : CBEdges->getOptimisticEdges())
10756 addCalledFunction(F, Change);
10757
10758 return true;
10759 };
10760
10761 // Visit all callable instructions.
10762 bool UsedAssumedInformation = false;
10763 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10764 UsedAssumedInformation,
10765 /* CheckBBLivenessOnly */ true)) {
10766 // If we haven't looked at all call like instructions, assume that there
10767 // are unknown callees.
10768 setHasUnknownCallee(true, Change);
10769 }
10770
10771 return Change;
10772 }
10773};
10774
10775/// -------------------AAInterFnReachability Attribute--------------------------
10776
10777struct AAInterFnReachabilityFunction
10778 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10779 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10780 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10781 : Base(IRP, A) {}
10782
10783 bool instructionCanReach(
10784 Attributor &A, const Instruction &From, const Function &To,
10785 const AA::InstExclusionSetTy *ExclusionSet) const override {
10786 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10787 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10788
10789 RQITy StackRQI(A, From, To, ExclusionSet, false);
10790 RQITy::Reachable Result;
10791 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10792 return NonConstThis->isReachableImpl(A, StackRQI,
10793 /*IsTemporaryRQI=*/true);
10794 return Result == RQITy::Reachable::Yes;
10795 }
10796
10797 bool isReachableImpl(Attributor &A, RQITy &RQI,
10798 bool IsTemporaryRQI) override {
10799 const Instruction *EntryI =
10800 &RQI.From->getFunction()->getEntryBlock().front();
10801 if (EntryI != RQI.From &&
10802 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10803 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10804 IsTemporaryRQI);
10805
10806 auto CheckReachableCallBase = [&](CallBase *CB) {
10807 auto *CBEdges = A.getAAFor<AACallEdges>(
10808 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10809 if (!CBEdges || !CBEdges->getState().isValidState())
10810 return false;
10811 // TODO Check To backwards in this case.
10812 if (CBEdges->hasUnknownCallee())
10813 return false;
10814
10815 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10816 if (Fn == RQI.To)
10817 return false;
10818
10819 if (Fn->isDeclaration()) {
10820 if (Fn->hasFnAttribute(Attribute::NoCallback))
10821 continue;
10822 // TODO Check To backwards in this case.
10823 return false;
10824 }
10825
10826 if (Fn == getAnchorScope()) {
10827 if (EntryI == RQI.From)
10828 continue;
10829 return false;
10830 }
10831
10832 const AAInterFnReachability *InterFnReachability =
10833 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10834 DepClassTy::OPTIONAL);
10835
10836 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10837 if (!InterFnReachability ||
10838 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10839 RQI.ExclusionSet))
10840 return false;
10841 }
10842 return true;
10843 };
10844
10845 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10846 *this, IRPosition::function(*RQI.From->getFunction()),
10847 DepClassTy::OPTIONAL);
10848
10849 // Determine call like instructions that we can reach from the inst.
10850 auto CheckCallBase = [&](Instruction &CBInst) {
10851 // There are usually less nodes in the call graph, check inter function
10852 // reachability first.
10853 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10854 return true;
10855 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10856 A, *RQI.From, CBInst, RQI.ExclusionSet);
10857 };
10858
10859 bool UsedExclusionSet = /* conservative */ true;
10860 bool UsedAssumedInformation = false;
10861 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10862 UsedAssumedInformation,
10863 /* CheckBBLivenessOnly */ true))
10864 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10865 IsTemporaryRQI);
10866
10867 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10868 IsTemporaryRQI);
10869 }
10870
10871 void trackStatistics() const override {}
10872};
10873} // namespace
10874
10875template <typename AAType>
10876static std::optional<Constant *>
10878 const IRPosition &IRP, Type &Ty) {
10879 if (!Ty.isIntegerTy())
10880 return nullptr;
10881
10882 // This will also pass the call base context.
10883 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10884 if (!AA)
10885 return nullptr;
10886
10887 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10888
10889 if (!COpt.has_value()) {
10890 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10891 return std::nullopt;
10892 }
10893 if (auto *C = *COpt) {
10894 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10895 return C;
10896 }
10897 return nullptr;
10898}
10899
10901 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10903 Type &Ty = *IRP.getAssociatedType();
10904 std::optional<Value *> V;
10905 for (auto &It : Values) {
10906 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10907 if (V.has_value() && !*V)
10908 break;
10909 }
10910 if (!V.has_value())
10911 return UndefValue::get(&Ty);
10912 return *V;
10913}
10914
10915namespace {
10916struct AAPotentialValuesImpl : AAPotentialValues {
10917 using StateType = PotentialLLVMValuesState;
10918
10919 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10920 : AAPotentialValues(IRP, A) {}
10921
10922 /// See AbstractAttribute::initialize(..).
10923 void initialize(Attributor &A) override {
10924 if (A.hasSimplificationCallback(getIRPosition())) {
10925 indicatePessimisticFixpoint();
10926 return;
10927 }
10928 Value *Stripped = getAssociatedValue().stripPointerCasts();
10929 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10930 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10931 getAnchorScope());
10932 indicateOptimisticFixpoint();
10933 return;
10934 }
10935 AAPotentialValues::initialize(A);
10936 }
10937
10938 /// See AbstractAttribute::getAsStr().
10939 const std::string getAsStr(Attributor *A) const override {
10940 std::string Str;
10941 llvm::raw_string_ostream OS(Str);
10942 OS << getState();
10943 return Str;
10944 }
10945
10946 template <typename AAType>
10947 static std::optional<Value *> askOtherAA(Attributor &A,
10948 const AbstractAttribute &AA,
10949 const IRPosition &IRP, Type &Ty) {
10951 return &IRP.getAssociatedValue();
10952 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10953 if (!C)
10954 return std::nullopt;
10955 if (*C)
10956 if (auto *CC = AA::getWithType(**C, Ty))
10957 return CC;
10958 return nullptr;
10959 }
10960
10961 virtual void addValue(Attributor &A, StateType &State, Value &V,
10962 const Instruction *CtxI, AA::ValueScope S,
10963 Function *AnchorScope) const {
10964
10965 IRPosition ValIRP = IRPosition::value(V);
10966 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10967 for (const auto &U : CB->args()) {
10968 if (U.get() != &V)
10969 continue;
10970 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10971 break;
10972 }
10973 }
10974
10975 Value *VPtr = &V;
10976 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10977 Type &Ty = *getAssociatedType();
10978 std::optional<Value *> SimpleV =
10979 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10980 if (SimpleV.has_value() && !*SimpleV) {
10981 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10982 *this, ValIRP, DepClassTy::OPTIONAL);
10983 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10984 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10985 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10986 if (PotentialConstantsAA->undefIsContained())
10987 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10988 return;
10989 }
10990 }
10991 if (!SimpleV.has_value())
10992 return;
10993
10994 if (*SimpleV)
10995 VPtr = *SimpleV;
10996 }
10997
10998 if (isa<ConstantInt>(VPtr))
10999 CtxI = nullptr;
11000 if (!AA::isValidInScope(*VPtr, AnchorScope))
11002
11003 State.unionAssumed({{*VPtr, CtxI}, S});
11004 }
11005
11006 /// Helper struct to tie a value+context pair together with the scope for
11007 /// which this is the simplified version.
11008 struct ItemInfo {
11009 AA::ValueAndContext I;
11011
11012 bool operator==(const ItemInfo &II) const {
11013 return II.I == I && II.S == S;
11014 };
11015 bool operator<(const ItemInfo &II) const {
11016 return std::tie(I, S) < std::tie(II.I, II.S);
11017 };
11018 };
11019
11020 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11021 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11022 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11023 if (!(CS & S))
11024 continue;
11025
11026 bool UsedAssumedInformation = false;
11028 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11029 UsedAssumedInformation))
11030 return false;
11031
11032 for (auto &It : Values)
11033 ValueScopeMap[It] += CS;
11034 }
11035 for (auto &It : ValueScopeMap)
11036 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11037 AA::ValueScope(It.second), getAnchorScope());
11038
11039 return true;
11040 }
11041
11042 void giveUpOnIntraprocedural(Attributor &A) {
11043 auto NewS = StateType::getBestState(getState());
11044 for (const auto &It : getAssumedSet()) {
11045 if (It.second == AA::Intraprocedural)
11046 continue;
11047 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11048 AA::Interprocedural, getAnchorScope());
11049 }
11050 assert(!undefIsContained() && "Undef should be an explicit value!");
11051 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11052 getAnchorScope());
11053 getState() = NewS;
11054 }
11055
11056 /// See AbstractState::indicatePessimisticFixpoint(...).
11057 ChangeStatus indicatePessimisticFixpoint() override {
11058 getState() = StateType::getBestState(getState());
11059 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11060 AAPotentialValues::indicateOptimisticFixpoint();
11061 return ChangeStatus::CHANGED;
11062 }
11063
11064 /// See AbstractAttribute::updateImpl(...).
11065 ChangeStatus updateImpl(Attributor &A) override {
11066 return indicatePessimisticFixpoint();
11067 }
11068
11069 /// See AbstractAttribute::manifest(...).
11070 ChangeStatus manifest(Attributor &A) override {
11073 Values.clear();
11074 if (!getAssumedSimplifiedValues(A, Values, S))
11075 continue;
11076 Value &OldV = getAssociatedValue();
11077 if (isa<UndefValue>(OldV))
11078 continue;
11079 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11080 if (!NewV || NewV == &OldV)
11081 continue;
11082 if (getCtxI() &&
11083 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11084 continue;
11085 if (A.changeAfterManifest(getIRPosition(), *NewV))
11086 return ChangeStatus::CHANGED;
11087 }
11088 return ChangeStatus::UNCHANGED;
11089 }
11090
11091 bool getAssumedSimplifiedValues(
11092 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11093 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11094 if (!isValidState())
11095 return false;
11096 bool UsedAssumedInformation = false;
11097 for (const auto &It : getAssumedSet())
11098 if (It.second & S) {
11099 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11100 isa<SelectInst>(It.first.getValue()))) {
11101 if (A.getAssumedSimplifiedValues(
11102 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11103 this, Values, S, UsedAssumedInformation))
11104 continue;
11105 }
11106 Values.push_back(It.first);
11107 }
11108 assert(!undefIsContained() && "Undef should be an explicit value!");
11109 return true;
11110 }
11111};
11112
11113struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11114 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11115 : AAPotentialValuesImpl(IRP, A) {}
11116
11117 /// See AbstractAttribute::updateImpl(...).
11118 ChangeStatus updateImpl(Attributor &A) override {
11119 auto AssumedBefore = getAssumed();
11120
11121 genericValueTraversal(A, &getAssociatedValue());
11122
11123 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11124 : ChangeStatus::CHANGED;
11125 }
11126
11127 /// Helper struct to remember which AAIsDead instances we actually used.
11128 struct LivenessInfo {
11129 const AAIsDead *LivenessAA = nullptr;
11130 bool AnyDead = false;
11131 };
11132
11133 /// Check if \p Cmp is a comparison we can simplify.
11134 ///
11135 /// We handle multiple cases, one in which at least one operand is an
11136 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11137 /// operand. Return true if successful, in that case Worklist will be updated.
11138 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11139 CmpInst::Predicate Pred, ItemInfo II,
11140 SmallVectorImpl<ItemInfo> &Worklist) {
11141
11142 // Simplify the operands first.
11143 bool UsedAssumedInformation = false;
11144 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11145 auto GetSimplifiedValues = [&](Value &V,
11147 if (!A.getAssumedSimplifiedValues(
11148 IRPosition::value(V, getCallBaseContext()), this, Values,
11149 AA::Intraprocedural, UsedAssumedInformation)) {
11150 Values.clear();
11151 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11152 }
11153 return Values.empty();
11154 };
11155 if (GetSimplifiedValues(*LHS, LHSValues))
11156 return true;
11157 if (GetSimplifiedValues(*RHS, RHSValues))
11158 return true;
11159
11160 LLVMContext &Ctx = LHS->getContext();
11161
11162 InformationCache &InfoCache = A.getInfoCache();
11163 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11164 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11165 const auto *DT =
11166 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11167 : nullptr;
11168 const auto *TLI =
11169 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11170 auto *AC =
11171 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11172 : nullptr;
11173
11174 const DataLayout &DL = A.getDataLayout();
11175 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11176
11177 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11178 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11179 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11180 /* CtxI */ nullptr, II.S, getAnchorScope());
11181 return true;
11182 }
11183
11184 // Handle the trivial case first in which we don't even need to think
11185 // about null or non-null.
11186 if (&LHSV == &RHSV &&
11188 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11190 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11191 getAnchorScope());
11192 return true;
11193 }
11194
11195 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11196 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11197 if (TypedLHS && TypedRHS) {
11198 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11199 if (NewV && NewV != &Cmp) {
11200 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11201 getAnchorScope());
11202 return true;
11203 }
11204 }
11205
11206 // From now on we only handle equalities (==, !=).
11207 if (!CmpInst::isEquality(Pred))
11208 return false;
11209
11210 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11211 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11212 if (!LHSIsNull && !RHSIsNull)
11213 return false;
11214
11215 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11216 // non-nullptr operand and if we assume it's non-null we can conclude the
11217 // result of the comparison.
11218 assert((LHSIsNull || RHSIsNull) &&
11219 "Expected nullptr versus non-nullptr comparison at this point");
11220
11221 // The index is the operand that we assume is not null.
11222 unsigned PtrIdx = LHSIsNull;
11223 bool IsKnownNonNull;
11224 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11225 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11226 DepClassTy::REQUIRED, IsKnownNonNull);
11227 if (!IsAssumedNonNull)
11228 return false;
11229
11230 // The new value depends on the predicate, true for != and false for ==.
11231 Constant *NewV =
11232 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11233 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11234 getAnchorScope());
11235 return true;
11236 };
11237
11238 for (auto &LHSValue : LHSValues)
11239 for (auto &RHSValue : RHSValues)
11240 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11241 return false;
11242 return true;
11243 }
11244
11245 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11246 SmallVectorImpl<ItemInfo> &Worklist) {
11247 const Instruction *CtxI = II.I.getCtxI();
11248 bool UsedAssumedInformation = false;
11249
11250 std::optional<Constant *> C =
11251 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11252 bool NoValueYet = !C.has_value();
11253 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11254 return true;
11255 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11256 if (CI->isZero())
11257 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11258 else
11259 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11260 } else if (&SI == &getAssociatedValue()) {
11261 // We could not simplify the condition, assume both values.
11262 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11263 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11264 } else {
11265 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11266 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11267 if (!SimpleV.has_value())
11268 return true;
11269 if (*SimpleV) {
11270 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11271 return true;
11272 }
11273 return false;
11274 }
11275 return true;
11276 }
11277
11278 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11279 SmallVectorImpl<ItemInfo> &Worklist) {
11280 SmallSetVector<Value *, 4> PotentialCopies;
11281 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11282 bool UsedAssumedInformation = false;
11283 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11284 PotentialValueOrigins, *this,
11285 UsedAssumedInformation,
11286 /* OnlyExact */ true)) {
11287 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11288 "loaded values for load instruction "
11289 << LI << "\n");
11290 return false;
11291 }
11292
11293 // Do not simplify loads that are only used in llvm.assume if we cannot also
11294 // remove all stores that may feed into the load. The reason is that the
11295 // assume is probably worth something as long as the stores are around.
11296 InformationCache &InfoCache = A.getInfoCache();
11297 if (InfoCache.isOnlyUsedByAssume(LI)) {
11298 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11299 if (!I || isa<AssumeInst>(I))
11300 return true;
11301 if (auto *SI = dyn_cast<StoreInst>(I))
11302 return A.isAssumedDead(SI->getOperandUse(0), this,
11303 /* LivenessAA */ nullptr,
11304 UsedAssumedInformation,
11305 /* CheckBBLivenessOnly */ false);
11306 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11307 UsedAssumedInformation,
11308 /* CheckBBLivenessOnly */ false);
11309 })) {
11310 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11311 "and we cannot delete all the stores: "
11312 << LI << "\n");
11313 return false;
11314 }
11315 }
11316
11317 // Values have to be dynamically unique or we loose the fact that a
11318 // single llvm::Value might represent two runtime values (e.g.,
11319 // stack locations in different recursive calls).
11320 const Instruction *CtxI = II.I.getCtxI();
11321 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11322 bool AllLocal = ScopeIsLocal;
11323 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11324 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11325 return AA::isDynamicallyUnique(A, *this, *PC);
11326 });
11327 if (!DynamicallyUnique) {
11328 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11329 "values are dynamically unique: "
11330 << LI << "\n");
11331 return false;
11332 }
11333
11334 for (auto *PotentialCopy : PotentialCopies) {
11335 if (AllLocal) {
11336 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11337 } else {
11338 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11339 }
11340 }
11341 if (!AllLocal && ScopeIsLocal)
11342 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11343 return true;
11344 }
11345
11346 bool handlePHINode(
11347 Attributor &A, PHINode &PHI, ItemInfo II,
11348 SmallVectorImpl<ItemInfo> &Worklist,
11349 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11350 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11351 LivenessInfo &LI = LivenessAAs[&F];
11352 if (!LI.LivenessAA)
11353 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11354 DepClassTy::NONE);
11355 return LI;
11356 };
11357
11358 if (&PHI == &getAssociatedValue()) {
11359 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11360 const auto *CI =
11361 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11362 *PHI.getFunction());
11363
11364 Cycle *C = nullptr;
11365 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11366 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11367 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11368 if (LI.LivenessAA &&
11369 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11370 LI.AnyDead = true;
11371 continue;
11372 }
11373 Value *V = PHI.getIncomingValue(u);
11374 if (V == &PHI)
11375 continue;
11376
11377 // If the incoming value is not the PHI but an instruction in the same
11378 // cycle we might have multiple versions of it flying around.
11379 if (CyclePHI && isa<Instruction>(V) &&
11380 (!C || C->contains(cast<Instruction>(V)->getParent())))
11381 return false;
11382
11383 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11384 }
11385 return true;
11386 }
11387
11388 bool UsedAssumedInformation = false;
11389 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11390 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11391 if (!SimpleV.has_value())
11392 return true;
11393 if (!(*SimpleV))
11394 return false;
11395 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11396 return true;
11397 }
11398
11399 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11400 /// simplify any operand of the instruction \p I. Return true if successful,
11401 /// in that case Worklist will be updated.
11402 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11403 SmallVectorImpl<ItemInfo> &Worklist) {
11404 bool SomeSimplified = false;
11405 bool UsedAssumedInformation = false;
11406
11407 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11408 int Idx = 0;
11409 for (Value *Op : I.operands()) {
11410 const auto &SimplifiedOp = A.getAssumedSimplified(
11411 IRPosition::value(*Op, getCallBaseContext()), *this,
11412 UsedAssumedInformation, AA::Intraprocedural);
11413 // If we are not sure about any operand we are not sure about the entire
11414 // instruction, we'll wait.
11415 if (!SimplifiedOp.has_value())
11416 return true;
11417
11418 if (*SimplifiedOp)
11419 NewOps[Idx] = *SimplifiedOp;
11420 else
11421 NewOps[Idx] = Op;
11422
11423 SomeSimplified |= (NewOps[Idx] != Op);
11424 ++Idx;
11425 }
11426
11427 // We won't bother with the InstSimplify interface if we didn't simplify any
11428 // operand ourselves.
11429 if (!SomeSimplified)
11430 return false;
11431
11432 InformationCache &InfoCache = A.getInfoCache();
11433 Function *F = I.getFunction();
11434 const auto *DT =
11435 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11436 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11437 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11438
11439 const DataLayout &DL = I.getDataLayout();
11440 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11441 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11442 if (!NewV || NewV == &I)
11443 return false;
11444
11445 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11446 << *NewV << "\n");
11447 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11448 return true;
11449 }
11450
11452 Attributor &A, Instruction &I, ItemInfo II,
11453 SmallVectorImpl<ItemInfo> &Worklist,
11454 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11455 if (auto *CI = dyn_cast<CmpInst>(&I))
11456 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11457 CI->getPredicate(), II, Worklist);
11458
11459 switch (I.getOpcode()) {
11460 case Instruction::Select:
11461 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11462 case Instruction::PHI:
11463 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11464 case Instruction::Load:
11465 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11466 default:
11467 return handleGenericInst(A, I, II, Worklist);
11468 };
11469 return false;
11470 }
11471
11472 void genericValueTraversal(Attributor &A, Value *InitialV) {
11473 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11474
11475 SmallSet<ItemInfo, 16> Visited;
11477 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11478
11479 int Iteration = 0;
11480 do {
11481 ItemInfo II = Worklist.pop_back_val();
11482 Value *V = II.I.getValue();
11483 assert(V);
11484 const Instruction *CtxI = II.I.getCtxI();
11485 AA::ValueScope S = II.S;
11486
11487 // Check if we should process the current value. To prevent endless
11488 // recursion keep a record of the values we followed!
11489 if (!Visited.insert(II).second)
11490 continue;
11491
11492 // Make sure we limit the compile time for complex expressions.
11493 if (Iteration++ >= MaxPotentialValuesIterations) {
11494 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11495 << Iteration << "!\n");
11496 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11497 continue;
11498 }
11499
11500 // Explicitly look through calls with a "returned" attribute if we do
11501 // not have a pointer as stripPointerCasts only works on them.
11502 Value *NewV = nullptr;
11503 if (V->getType()->isPointerTy()) {
11504 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11505 } else {
11506 if (auto *CB = dyn_cast<CallBase>(V))
11507 if (auto *Callee =
11509 for (Argument &Arg : Callee->args())
11510 if (Arg.hasReturnedAttr()) {
11511 NewV = CB->getArgOperand(Arg.getArgNo());
11512 break;
11513 }
11514 }
11515 }
11516 if (NewV && NewV != V) {
11517 Worklist.push_back({{*NewV, CtxI}, S});
11518 continue;
11519 }
11520
11521 if (auto *I = dyn_cast<Instruction>(V)) {
11522 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11523 continue;
11524 }
11525
11526 if (V != InitialV || isa<Argument>(V))
11527 if (recurseForValue(A, IRPosition::value(*V), II.S))
11528 continue;
11529
11530 // If we haven't stripped anything we give up.
11531 if (V == InitialV && CtxI == getCtxI()) {
11532 indicatePessimisticFixpoint();
11533 return;
11534 }
11535
11536 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11537 } while (!Worklist.empty());
11538
11539 // If we actually used liveness information so we have to record a
11540 // dependence.
11541 for (auto &It : LivenessAAs)
11542 if (It.second.AnyDead)
11543 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11544 }
11545
11546 /// See AbstractAttribute::trackStatistics()
11547 void trackStatistics() const override {
11548 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11549 }
11550};
11551
11552struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11553 using Base = AAPotentialValuesImpl;
11554 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11555 : Base(IRP, A) {}
11556
11557 /// See AbstractAttribute::initialize(..).
11558 void initialize(Attributor &A) override {
11559 auto &Arg = cast<Argument>(getAssociatedValue());
11561 indicatePessimisticFixpoint();
11562 }
11563
11564 /// See AbstractAttribute::updateImpl(...).
11565 ChangeStatus updateImpl(Attributor &A) override {
11566 auto AssumedBefore = getAssumed();
11567
11568 unsigned ArgNo = getCalleeArgNo();
11569
11570 bool UsedAssumedInformation = false;
11572 auto CallSitePred = [&](AbstractCallSite ACS) {
11573 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11574 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11575 return false;
11576
11577 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11579 UsedAssumedInformation))
11580 return false;
11581
11582 return isValidState();
11583 };
11584
11585 if (!A.checkForAllCallSites(CallSitePred, *this,
11586 /* RequireAllCallSites */ true,
11587 UsedAssumedInformation))
11588 return indicatePessimisticFixpoint();
11589
11590 Function *Fn = getAssociatedFunction();
11591 bool AnyNonLocal = false;
11592 for (auto &It : Values) {
11593 if (isa<Constant>(It.getValue())) {
11594 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11595 getAnchorScope());
11596 continue;
11597 }
11598 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11599 return indicatePessimisticFixpoint();
11600
11601 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11602 if (Arg->getParent() == Fn) {
11603 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11604 getAnchorScope());
11605 continue;
11606 }
11607 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11608 getAnchorScope());
11609 AnyNonLocal = true;
11610 }
11611 assert(!undefIsContained() && "Undef should be an explicit value!");
11612 if (AnyNonLocal)
11613 giveUpOnIntraprocedural(A);
11614
11615 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11616 : ChangeStatus::CHANGED;
11617 }
11618
11619 /// See AbstractAttribute::trackStatistics()
11620 void trackStatistics() const override {
11621 STATS_DECLTRACK_ARG_ATTR(potential_values)
11622 }
11623};
11624
11625struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11626 using Base = AAPotentialValuesFloating;
11627 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11628 : Base(IRP, A) {}
11629
11630 /// See AbstractAttribute::initialize(..).
11631 void initialize(Attributor &A) override {
11632 Function *F = getAssociatedFunction();
11633 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11634 indicatePessimisticFixpoint();
11635 return;
11636 }
11637
11638 for (Argument &Arg : F->args())
11639 if (Arg.hasReturnedAttr()) {
11640 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11641 ReturnedArg = &Arg;
11642 break;
11643 }
11644 if (!A.isFunctionIPOAmendable(*F) ||
11645 A.hasSimplificationCallback(getIRPosition())) {
11646 if (!ReturnedArg)
11647 indicatePessimisticFixpoint();
11648 else
11649 indicateOptimisticFixpoint();
11650 }
11651 }
11652
11653 /// See AbstractAttribute::updateImpl(...).
11654 ChangeStatus updateImpl(Attributor &A) override {
11655 auto AssumedBefore = getAssumed();
11656 bool UsedAssumedInformation = false;
11657
11659 Function *AnchorScope = getAnchorScope();
11660 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11661 bool AddValues) {
11663 Values.clear();
11664 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11665 UsedAssumedInformation,
11666 /* RecurseForSelectAndPHI */ true))
11667 return false;
11668 if (!AddValues)
11669 continue;
11670
11671 bool AllInterAreIntra = false;
11672 if (S == AA::Interprocedural)
11673 AllInterAreIntra =
11674 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11675 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11676 });
11677
11678 for (const AA::ValueAndContext &VAC : Values) {
11679 addValue(A, getState(), *VAC.getValue(),
11680 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11681 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11682 }
11683 if (AllInterAreIntra)
11684 break;
11685 }
11686 return true;
11687 };
11688
11689 if (ReturnedArg) {
11690 HandleReturnedValue(*ReturnedArg, nullptr, true);
11691 } else {
11692 auto RetInstPred = [&](Instruction &RetI) {
11693 bool AddValues = true;
11694 if (isa<PHINode>(RetI.getOperand(0)) ||
11695 isa<SelectInst>(RetI.getOperand(0))) {
11696 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11697 AnchorScope);
11698 AddValues = false;
11699 }
11700 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11701 };
11702
11703 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11704 UsedAssumedInformation,
11705 /* CheckBBLivenessOnly */ true))
11706 return indicatePessimisticFixpoint();
11707 }
11708
11709 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11710 : ChangeStatus::CHANGED;
11711 }
11712
11713 ChangeStatus manifest(Attributor &A) override {
11714 if (ReturnedArg)
11715 return ChangeStatus::UNCHANGED;
11717 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11718 /* RecurseForSelectAndPHI */ true))
11719 return ChangeStatus::UNCHANGED;
11720 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11721 if (!NewVal)
11722 return ChangeStatus::UNCHANGED;
11723
11724 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11725 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11726 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11727 "Number of function with unique return");
11728 Changed |= A.manifestAttrs(
11730 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11731 STATS_DECLTRACK_ARG_ATTR(returned);
11732 }
11733
11734 auto RetInstPred = [&](Instruction &RetI) {
11735 Value *RetOp = RetI.getOperand(0);
11736 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11737 return true;
11738 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11739 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11740 Changed = ChangeStatus::CHANGED;
11741 return true;
11742 };
11743 bool UsedAssumedInformation = false;
11744 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11745 UsedAssumedInformation,
11746 /* CheckBBLivenessOnly */ true);
11747 return Changed;
11748 }
11749
11750 ChangeStatus indicatePessimisticFixpoint() override {
11751 return AAPotentialValues::indicatePessimisticFixpoint();
11752 }
11753
11754 /// See AbstractAttribute::trackStatistics()
11755 void trackStatistics() const override{
11756 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11757
11758 /// The argumented with an existing `returned` attribute.
11759 Argument *ReturnedArg = nullptr;
11760};
11761
11762struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11763 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11764 : AAPotentialValuesImpl(IRP, A) {}
11765
11766 /// See AbstractAttribute::updateImpl(...).
11767 ChangeStatus updateImpl(Attributor &A) override {
11768 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11769 "not be called");
11770 }
11771
11772 /// See AbstractAttribute::trackStatistics()
11773 void trackStatistics() const override {
11774 STATS_DECLTRACK_FN_ATTR(potential_values)
11775 }
11776};
11777
11778struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11779 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11780 : AAPotentialValuesFunction(IRP, A) {}
11781
11782 /// See AbstractAttribute::trackStatistics()
11783 void trackStatistics() const override {
11784 STATS_DECLTRACK_CS_ATTR(potential_values)
11785 }
11786};
11787
11788struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11789 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11790 : AAPotentialValuesImpl(IRP, A) {}
11791
11792 /// See AbstractAttribute::updateImpl(...).
11793 ChangeStatus updateImpl(Attributor &A) override {
11794 auto AssumedBefore = getAssumed();
11795
11796 Function *Callee = getAssociatedFunction();
11797 if (!Callee)
11798 return indicatePessimisticFixpoint();
11799
11800 bool UsedAssumedInformation = false;
11801 auto *CB = cast<CallBase>(getCtxI());
11802 if (CB->isMustTailCall() &&
11803 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11804 UsedAssumedInformation))
11805 return indicatePessimisticFixpoint();
11806
11807 Function *Caller = CB->getCaller();
11808
11809 auto AddScope = [&](AA::ValueScope S) {
11811 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11812 Values, S, UsedAssumedInformation))
11813 return false;
11814
11815 for (auto &It : Values) {
11816 Value *V = It.getValue();
11817 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11818 V, *CB, *this, UsedAssumedInformation);
11819 if (!CallerV.has_value()) {
11820 // Nothing to do as long as no value was determined.
11821 continue;
11822 }
11823 V = *CallerV ? *CallerV : V;
11824 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11825 if (recurseForValue(A, IRPosition::value(*V), S))
11826 continue;
11827 }
11828 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11829 giveUpOnIntraprocedural(A);
11830 return true;
11831 }
11832 addValue(A, getState(), *V, CB, S, getAnchorScope());
11833 }
11834 return true;
11835 };
11836 if (!AddScope(AA::Intraprocedural))
11837 return indicatePessimisticFixpoint();
11838 if (!AddScope(AA::Interprocedural))
11839 return indicatePessimisticFixpoint();
11840 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11841 : ChangeStatus::CHANGED;
11842 }
11843
11844 ChangeStatus indicatePessimisticFixpoint() override {
11845 return AAPotentialValues::indicatePessimisticFixpoint();
11846 }
11847
11848 /// See AbstractAttribute::trackStatistics()
11849 void trackStatistics() const override {
11850 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11851 }
11852};
11853
11854struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11855 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11856 : AAPotentialValuesFloating(IRP, A) {}
11857
11858 /// See AbstractAttribute::trackStatistics()
11859 void trackStatistics() const override {
11860 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11861 }
11862};
11863} // namespace
11864
11865/// ---------------------- Assumption Propagation ------------------------------
11866namespace {
11867struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11868 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11869 const DenseSet<StringRef> &Known)
11870 : AAAssumptionInfo(IRP, A, Known) {}
11871
11872 /// See AbstractAttribute::manifest(...).
11873 ChangeStatus manifest(Attributor &A) override {
11874 // Don't manifest a universal set if it somehow made it here.
11875 if (getKnown().isUniversal())
11876 return ChangeStatus::UNCHANGED;
11877
11878 const IRPosition &IRP = getIRPosition();
11879 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11880 getAssumed().getSet().end());
11881 llvm::sort(Set);
11882 return A.manifestAttrs(IRP,
11883 Attribute::get(IRP.getAnchorValue().getContext(),
11885 llvm::join(Set, ",")),
11886 /*ForceReplace=*/true);
11887 }
11888
11889 bool hasAssumption(const StringRef Assumption) const override {
11890 return isValidState() && setContains(Assumption);
11891 }
11892
11893 /// See AbstractAttribute::getAsStr()
11894 const std::string getAsStr(Attributor *A) const override {
11895 const SetContents &Known = getKnown();
11896 const SetContents &Assumed = getAssumed();
11897
11898 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11899 llvm::sort(Set);
11900 const std::string KnownStr = llvm::join(Set, ",");
11901
11902 std::string AssumedStr = "Universal";
11903 if (!Assumed.isUniversal()) {
11904 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11905 AssumedStr = llvm::join(Set, ",");
11906 }
11907 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11908 }
11909};
11910
11911/// Propagates assumption information from parent functions to all of their
11912/// successors. An assumption can be propagated if the containing function
11913/// dominates the called function.
11914///
11915/// We start with a "known" set of assumptions already valid for the associated
11916/// function and an "assumed" set that initially contains all possible
11917/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11918/// contents as concrete values are known. The concrete values are seeded by the
11919/// first nodes that are either entries into the call graph, or contains no
11920/// assumptions. Each node is updated as the intersection of the assumed state
11921/// with all of its predecessors.
11922struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11923 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11924 : AAAssumptionInfoImpl(IRP, A,
11925 getAssumptions(*IRP.getAssociatedFunction())) {}
11926
11927 /// See AbstractAttribute::updateImpl(...).
11928 ChangeStatus updateImpl(Attributor &A) override {
11929 bool Changed = false;
11930
11931 auto CallSitePred = [&](AbstractCallSite ACS) {
11932 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11933 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11934 DepClassTy::REQUIRED);
11935 if (!AssumptionAA)
11936 return false;
11937 // Get the set of assumptions shared by all of this function's callers.
11938 Changed |= getIntersection(AssumptionAA->getAssumed());
11939 return !getAssumed().empty() || !getKnown().empty();
11940 };
11941
11942 bool UsedAssumedInformation = false;
11943 // Get the intersection of all assumptions held by this node's predecessors.
11944 // If we don't know all the call sites then this is either an entry into the
11945 // call graph or an empty node. This node is known to only contain its own
11946 // assumptions and can be propagated to its successors.
11947 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11948 UsedAssumedInformation))
11949 return indicatePessimisticFixpoint();
11950
11951 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11952 }
11953
11954 void trackStatistics() const override {}
11955};
11956
11957/// Assumption Info defined for call sites.
11958struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11959
11960 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11961 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11962
11963 /// See AbstractAttribute::initialize(...).
11964 void initialize(Attributor &A) override {
11965 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11966 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11967 }
11968
11969 /// See AbstractAttribute::updateImpl(...).
11970 ChangeStatus updateImpl(Attributor &A) override {
11971 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11972 auto *AssumptionAA =
11973 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11974 if (!AssumptionAA)
11975 return indicatePessimisticFixpoint();
11976 bool Changed = getIntersection(AssumptionAA->getAssumed());
11977 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11978 }
11979
11980 /// See AbstractAttribute::trackStatistics()
11981 void trackStatistics() const override {}
11982
11983private:
11984 /// Helper to initialized the known set as all the assumptions this call and
11985 /// the callee contain.
11986 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11987 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11988 auto Assumptions = getAssumptions(CB);
11989 if (const Function *F = CB.getCaller())
11990 set_union(Assumptions, getAssumptions(*F));
11991 if (Function *F = IRP.getAssociatedFunction())
11992 set_union(Assumptions, getAssumptions(*F));
11993 return Assumptions;
11994 }
11995};
11996} // namespace
11997
11999 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12000 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12001}
12002
12004
12005/// ------------------------ UnderlyingObjects ---------------------------------
12006
12007namespace {
12008struct AAUnderlyingObjectsImpl
12009 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12011 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12012
12013 /// See AbstractAttribute::getAsStr().
12014 const std::string getAsStr(Attributor *A) const override {
12015 if (!isValidState())
12016 return "<invalid>";
12017 std::string Str;
12019 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12020 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12021 << " objects.\n";
12022 if (!InterAssumedUnderlyingObjects.empty()) {
12023 OS << "inter objects:\n";
12024 for (auto *Obj : InterAssumedUnderlyingObjects)
12025 OS << *Obj << '\n';
12026 }
12027 if (!IntraAssumedUnderlyingObjects.empty()) {
12028 OS << "intra objects:\n";
12029 for (auto *Obj : IntraAssumedUnderlyingObjects)
12030 OS << *Obj << '\n';
12031 }
12032 return Str;
12033 }
12034
12035 /// See AbstractAttribute::trackStatistics()
12036 void trackStatistics() const override {}
12037
12038 /// See AbstractAttribute::updateImpl(...).
12039 ChangeStatus updateImpl(Attributor &A) override {
12040 auto &Ptr = getAssociatedValue();
12041
12042 bool UsedAssumedInformation = false;
12043 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12045 SmallPtrSet<Value *, 8> SeenObjects;
12047
12048 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12049 Scope, UsedAssumedInformation))
12050 return UnderlyingObjects.insert(&Ptr);
12051
12052 bool Changed = false;
12053
12054 for (unsigned I = 0; I < Values.size(); ++I) {
12055 auto &VAC = Values[I];
12056 auto *Obj = VAC.getValue();
12057 Value *UO = getUnderlyingObject(Obj);
12058 if (!SeenObjects.insert(UO ? UO : Obj).second)
12059 continue;
12060 if (UO && UO != Obj) {
12061 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12062 Changed |= UnderlyingObjects.insert(UO);
12063 continue;
12064 }
12065
12066 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12067 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12068 auto Pred = [&](Value &V) {
12069 if (&V == UO)
12070 Changed |= UnderlyingObjects.insert(UO);
12071 else
12072 Values.emplace_back(V, nullptr);
12073 return true;
12074 };
12075
12076 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12078 "The forall call should not return false at this position");
12079 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12080 continue;
12081 }
12082
12083 if (isa<SelectInst>(Obj)) {
12084 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12085 UsedAssumedInformation);
12086 continue;
12087 }
12088 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12089 // Explicitly look through PHIs as we do not care about dynamically
12090 // uniqueness.
12091 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12092 Changed |=
12093 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12094 Scope, UsedAssumedInformation);
12095 }
12096 continue;
12097 }
12098
12099 Changed |= UnderlyingObjects.insert(Obj);
12100 }
12101
12102 return Changed;
12103 };
12104
12105 bool Changed = false;
12106 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12107 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12108 if (!UsedAssumedInformation)
12109 indicateOptimisticFixpoint();
12110 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12111 }
12112
12113 bool forallUnderlyingObjects(
12114 function_ref<bool(Value &)> Pred,
12115 AA::ValueScope Scope = AA::Interprocedural) const override {
12116 if (!isValidState())
12117 return Pred(getAssociatedValue());
12118
12119 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12120 ? IntraAssumedUnderlyingObjects
12121 : InterAssumedUnderlyingObjects;
12122 for (Value *Obj : AssumedUnderlyingObjects)
12123 if (!Pred(*Obj))
12124 return false;
12125
12126 return true;
12127 }
12128
12129private:
12130 /// Handle the case where the value is not the actual underlying value, such
12131 /// as a phi node or a select instruction.
12132 bool handleIndirect(Attributor &A, Value &V,
12133 SmallSetVector<Value *, 8> &UnderlyingObjects,
12134 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12135 bool Changed = false;
12136 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12137 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12138 auto Pred = [&](Value &V) {
12139 Changed |= UnderlyingObjects.insert(&V);
12140 return true;
12141 };
12142 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12144 "The forall call should not return false at this position");
12145 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12146 return Changed;
12147 }
12148
12149 /// All the underlying objects collected so far via intra procedural scope.
12150 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12151 /// All the underlying objects collected so far via inter procedural scope.
12152 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12153};
12154
12155struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12156 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12157 : AAUnderlyingObjectsImpl(IRP, A) {}
12158};
12159
12160struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12161 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12162 : AAUnderlyingObjectsImpl(IRP, A) {}
12163};
12164
12165struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12166 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12167 : AAUnderlyingObjectsImpl(IRP, A) {}
12168};
12169
12170struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12171 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12172 : AAUnderlyingObjectsImpl(IRP, A) {}
12173};
12174
12175struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12176 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12177 : AAUnderlyingObjectsImpl(IRP, A) {}
12178};
12179
12180struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12181 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12182 : AAUnderlyingObjectsImpl(IRP, A) {}
12183};
12184
12185struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12186 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12187 : AAUnderlyingObjectsImpl(IRP, A) {}
12188};
12189} // namespace
12190
12191/// ------------------------ Global Value Info -------------------------------
12192namespace {
12193struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12194 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12195 : AAGlobalValueInfo(IRP, A) {}
12196
12197 /// See AbstractAttribute::initialize(...).
12198 void initialize(Attributor &A) override {}
12199
12200 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12201 SmallVectorImpl<const Value *> &Worklist) {
12202 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12203 if (!UInst) {
12204 Follow = true;
12205 return true;
12206 }
12207
12208 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12209 << *UInst << "\n");
12210
12211 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12212 int Idx = &Cmp->getOperandUse(0) == &U;
12213 if (isa<Constant>(Cmp->getOperand(Idx)))
12214 return true;
12215 return U == &getAnchorValue();
12216 }
12217
12218 // Explicitly catch return instructions.
12219 if (isa<ReturnInst>(UInst)) {
12220 auto CallSitePred = [&](AbstractCallSite ACS) {
12221 Worklist.push_back(ACS.getInstruction());
12222 return true;
12223 };
12224 bool UsedAssumedInformation = false;
12225 // TODO: We should traverse the uses or add a "non-call-site" CB.
12226 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12227 /*RequireAllCallSites=*/true, this,
12228 UsedAssumedInformation))
12229 return false;
12230 return true;
12231 }
12232
12233 // For now we only use special logic for call sites. However, the tracker
12234 // itself knows about a lot of other non-capturing cases already.
12235 auto *CB = dyn_cast<CallBase>(UInst);
12236 if (!CB)
12237 return false;
12238 // Direct calls are OK uses.
12239 if (CB->isCallee(&U))
12240 return true;
12241 // Non-argument uses are scary.
12242 if (!CB->isArgOperand(&U))
12243 return false;
12244 // TODO: Iterate callees.
12245 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12246 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12247 return false;
12248
12249 unsigned ArgNo = CB->getArgOperandNo(&U);
12250 Worklist.push_back(Fn->getArg(ArgNo));
12251 return true;
12252 }
12253
12254 ChangeStatus updateImpl(Attributor &A) override {
12255 unsigned NumUsesBefore = Uses.size();
12256
12257 SmallPtrSet<const Value *, 8> Visited;
12259 Worklist.push_back(&getAnchorValue());
12260
12261 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12262 Uses.insert(&U);
12263 // TODO(captures): Make this more precise.
12264 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12265 if (CI.isPassthrough()) {
12266 Follow = true;
12267 return true;
12268 }
12269 return checkUse(A, U, Follow, Worklist);
12270 };
12271 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12272 Uses.insert(&OldU);
12273 return true;
12274 };
12275
12276 while (!Worklist.empty()) {
12277 const Value *V = Worklist.pop_back_val();
12278 if (!Visited.insert(V).second)
12279 continue;
12280 if (!A.checkForAllUses(UsePred, *this, *V,
12281 /* CheckBBLivenessOnly */ true,
12282 DepClassTy::OPTIONAL,
12283 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12284 return indicatePessimisticFixpoint();
12285 }
12286 }
12287
12288 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12289 : ChangeStatus::CHANGED;
12290 }
12291
12292 bool isPotentialUse(const Use &U) const override {
12293 return !isValidState() || Uses.contains(&U);
12294 }
12295
12296 /// See AbstractAttribute::manifest(...).
12297 ChangeStatus manifest(Attributor &A) override {
12298 return ChangeStatus::UNCHANGED;
12299 }
12300
12301 /// See AbstractAttribute::getAsStr().
12302 const std::string getAsStr(Attributor *A) const override {
12303 return "[" + std::to_string(Uses.size()) + " uses]";
12304 }
12305
12306 void trackStatistics() const override {
12307 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12308 }
12309
12310private:
12311 /// Set of (transitive) uses of this GlobalValue.
12312 SmallPtrSet<const Use *, 8> Uses;
12313};
12314} // namespace
12315
12316/// ------------------------ Indirect Call Info -------------------------------
12317namespace {
12318struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12319 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12320 : AAIndirectCallInfo(IRP, A) {}
12321
12322 /// See AbstractAttribute::initialize(...).
12323 void initialize(Attributor &A) override {
12324 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12325 if (!MD && !A.isClosedWorldModule())
12326 return;
12327
12328 if (MD) {
12329 for (const auto &Op : MD->operands())
12330 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12331 PotentialCallees.insert(Callee);
12332 } else if (A.isClosedWorldModule()) {
12333 ArrayRef<Function *> IndirectlyCallableFunctions =
12334 A.getInfoCache().getIndirectlyCallableFunctions(A);
12335 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12336 }
12337
12338 if (PotentialCallees.empty())
12339 indicateOptimisticFixpoint();
12340 }
12341
12342 ChangeStatus updateImpl(Attributor &A) override {
12343 CallBase *CB = cast<CallBase>(getCtxI());
12344 const Use &CalleeUse = CB->getCalledOperandUse();
12345 Value *FP = CB->getCalledOperand();
12346
12347 SmallSetVector<Function *, 4> AssumedCalleesNow;
12348 bool AllCalleesKnownNow = AllCalleesKnown;
12349
12350 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12351 bool &UsedAssumedInformation) {
12352 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12353 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12354 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12355 return true;
12356 UsedAssumedInformation = !GIAA->isAtFixpoint();
12357 return false;
12358 };
12359
12360 auto AddPotentialCallees = [&]() {
12361 for (auto *PotentialCallee : PotentialCallees) {
12362 bool UsedAssumedInformation = false;
12363 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12364 AssumedCalleesNow.insert(PotentialCallee);
12365 }
12366 };
12367
12368 // Use simplification to find potential callees, if !callees was present,
12369 // fallback to that set if necessary.
12370 bool UsedAssumedInformation = false;
12372 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12373 AA::ValueScope::AnyScope,
12374 UsedAssumedInformation)) {
12375 if (PotentialCallees.empty())
12376 return indicatePessimisticFixpoint();
12377 AddPotentialCallees();
12378 }
12379
12380 // Try to find a reason for \p Fn not to be a potential callee. If none was
12381 // found, add it to the assumed callees set.
12382 auto CheckPotentialCallee = [&](Function &Fn) {
12383 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12384 return false;
12385
12386 auto &CachedResult = FilterResults[&Fn];
12387 if (CachedResult.has_value())
12388 return CachedResult.value();
12389
12390 bool UsedAssumedInformation = false;
12391 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12392 if (!UsedAssumedInformation)
12393 CachedResult = false;
12394 return false;
12395 }
12396
12397 int NumFnArgs = Fn.arg_size();
12398 int NumCBArgs = CB->arg_size();
12399
12400 // Check if any excess argument (which we fill up with poison) is known to
12401 // be UB on undef.
12402 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12403 bool IsKnown = false;
12405 A, this, IRPosition::argument(*Fn.getArg(I)),
12406 DepClassTy::OPTIONAL, IsKnown)) {
12407 if (IsKnown)
12408 CachedResult = false;
12409 return false;
12410 }
12411 }
12412
12413 CachedResult = true;
12414 return true;
12415 };
12416
12417 // Check simplification result, prune known UB callees, also restrict it to
12418 // the !callees set, if present.
12419 for (auto &VAC : Values) {
12420 if (isa<UndefValue>(VAC.getValue()))
12421 continue;
12423 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12424 continue;
12425 // TODO: Check for known UB, e.g., poison + noundef.
12426 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12427 if (CheckPotentialCallee(*VACFn))
12428 AssumedCalleesNow.insert(VACFn);
12429 continue;
12430 }
12431 if (!PotentialCallees.empty()) {
12432 AddPotentialCallees();
12433 break;
12434 }
12435 AllCalleesKnownNow = false;
12436 }
12437
12438 if (AssumedCalleesNow == AssumedCallees &&
12439 AllCalleesKnown == AllCalleesKnownNow)
12440 return ChangeStatus::UNCHANGED;
12441
12442 std::swap(AssumedCallees, AssumedCalleesNow);
12443 AllCalleesKnown = AllCalleesKnownNow;
12444 return ChangeStatus::CHANGED;
12445 }
12446
12447 /// See AbstractAttribute::manifest(...).
12448 ChangeStatus manifest(Attributor &A) override {
12449 // If we can't specialize at all, give up now.
12450 if (!AllCalleesKnown && AssumedCallees.empty())
12451 return ChangeStatus::UNCHANGED;
12452
12453 CallBase *CB = cast<CallBase>(getCtxI());
12454 bool UsedAssumedInformation = false;
12455 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12456 UsedAssumedInformation))
12457 return ChangeStatus::UNCHANGED;
12458
12459 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12460 Value *FP = CB->getCalledOperand();
12461 if (FP->getType()->getPointerAddressSpace())
12462 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12463 FP->getName() + ".as0", CB->getIterator());
12464
12465 bool CBIsVoid = CB->getType()->isVoidTy();
12467 FunctionType *CSFT = CB->getFunctionType();
12468 SmallVector<Value *> CSArgs(CB->args());
12469
12470 // If we know all callees and there are none, the call site is (effectively)
12471 // dead (or UB).
12472 if (AssumedCallees.empty()) {
12473 assert(AllCalleesKnown &&
12474 "Expected all callees to be known if there are none.");
12475 A.changeToUnreachableAfterManifest(CB);
12476 return ChangeStatus::CHANGED;
12477 }
12478
12479 // Special handling for the single callee case.
12480 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12481 auto *NewCallee = AssumedCallees.front();
12482 if (isLegalToPromote(*CB, NewCallee)) {
12483 promoteCall(*CB, NewCallee, nullptr);
12484 NumIndirectCallsPromoted++;
12485 return ChangeStatus::CHANGED;
12486 }
12487 Instruction *NewCall =
12488 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12489 CB->getName(), CB->getIterator());
12490 if (!CBIsVoid)
12491 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12492 A.deleteAfterManifest(*CB);
12493 return ChangeStatus::CHANGED;
12494 }
12495
12496 // For each potential value we create a conditional
12497 //
12498 // ```
12499 // if (ptr == value) value(args);
12500 // else ...
12501 // ```
12502 //
12503 bool SpecializedForAnyCallees = false;
12504 bool SpecializedForAllCallees = AllCalleesKnown;
12505 ICmpInst *LastCmp = nullptr;
12506 SmallVector<Function *, 8> SkippedAssumedCallees;
12508 for (Function *NewCallee : AssumedCallees) {
12509 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12510 AssumedCallees.size())) {
12511 SkippedAssumedCallees.push_back(NewCallee);
12512 SpecializedForAllCallees = false;
12513 continue;
12514 }
12515 SpecializedForAnyCallees = true;
12516
12517 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12518 Instruction *ThenTI =
12519 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12520 BasicBlock *CBBB = CB->getParent();
12521 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12522 A.registerManifestAddedBasicBlock(*IP->getParent());
12523 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12524 BasicBlock *ElseBB;
12525 if (&*IP == CB) {
12526 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12527 ThenTI->getFunction(), CBBB);
12528 A.registerManifestAddedBasicBlock(*ElseBB);
12529 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12530 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12531 } else {
12532 ElseBB = IP->getParent();
12533 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12534 }
12535 CastInst *RetBC = nullptr;
12536 CallInst *NewCall = nullptr;
12537 if (isLegalToPromote(*CB, NewCallee)) {
12538 auto *CBClone = cast<CallBase>(CB->clone());
12539 CBClone->insertBefore(ThenTI->getIterator());
12540 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12541 NumIndirectCallsPromoted++;
12542 } else {
12543 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12544 CB->getName(), ThenTI->getIterator());
12545 }
12546 NewCalls.push_back({NewCall, RetBC});
12547 }
12548
12549 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12550 if (!AllCalleesKnown)
12551 return ChangeStatus::UNCHANGED;
12552 MDBuilder MDB(IndirectCB.getContext());
12553 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12554 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12555 return ChangeStatus::CHANGED;
12556 };
12557
12558 if (!SpecializedForAnyCallees)
12559 return AttachCalleeMetadata(*CB);
12560
12561 // Check if we need the fallback indirect call still.
12562 if (SpecializedForAllCallees) {
12564 LastCmp->eraseFromParent();
12565 new UnreachableInst(IP->getContext(), IP);
12566 IP->eraseFromParent();
12567 } else {
12568 auto *CBClone = cast<CallInst>(CB->clone());
12569 CBClone->setName(CB->getName());
12570 CBClone->insertBefore(*IP->getParent(), IP);
12571 NewCalls.push_back({CBClone, nullptr});
12572 AttachCalleeMetadata(*CBClone);
12573 }
12574
12575 // Check if we need a PHI to merge the results.
12576 if (!CBIsVoid) {
12577 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12578 CB->getName() + ".phi",
12579 CB->getParent()->getFirstInsertionPt());
12580 for (auto &It : NewCalls) {
12581 CallBase *NewCall = It.first;
12582 Instruction *CallRet = It.second ? It.second : It.first;
12583 if (CallRet->getType() == CB->getType())
12584 PHI->addIncoming(CallRet, CallRet->getParent());
12585 else if (NewCall->getType()->isVoidTy())
12586 PHI->addIncoming(PoisonValue::get(CB->getType()),
12587 NewCall->getParent());
12588 else
12589 llvm_unreachable("Call return should match or be void!");
12590 }
12591 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12592 }
12593
12594 A.deleteAfterManifest(*CB);
12595 Changed = ChangeStatus::CHANGED;
12596
12597 return Changed;
12598 }
12599
12600 /// See AbstractAttribute::getAsStr().
12601 const std::string getAsStr(Attributor *A) const override {
12602 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12603 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12604 " functions";
12605 }
12606
12607 void trackStatistics() const override {
12608 if (AllCalleesKnown) {
12610 Eliminated, CallSites,
12611 "Number of indirect call sites eliminated via specialization")
12612 } else {
12613 STATS_DECLTRACK(Specialized, CallSites,
12614 "Number of indirect call sites specialized")
12615 }
12616 }
12617
12618 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12619 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12620 }
12621
12622private:
12623 /// Map to remember filter results.
12624 DenseMap<Function *, std::optional<bool>> FilterResults;
12625
12626 /// If the !callee metadata was present, this set will contain all potential
12627 /// callees (superset).
12628 SmallSetVector<Function *, 4> PotentialCallees;
12629
12630 /// This set contains all currently assumed calllees, which might grow over
12631 /// time.
12632 SmallSetVector<Function *, 4> AssumedCallees;
12633
12634 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12635 /// if there could be others.
12636 bool AllCalleesKnown = true;
12637};
12638} // namespace
12639
12640/// --------------------- Invariant Load Pointer -------------------------------
12641namespace {
12642
12643struct AAInvariantLoadPointerImpl
12644 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12645 AAInvariantLoadPointer> {
12646
12647 enum {
12648 // pointer does not alias within the bounds of the function
12649 IS_NOALIAS = 1 << 0,
12650 // pointer is not involved in any effectful instructions within the bounds
12651 // of the function
12652 IS_NOEFFECT = 1 << 1,
12653 // loads are invariant within the bounds of the function
12654 IS_LOCALLY_INVARIANT = 1 << 2,
12655 // memory lifetime is constrained within the bounds of the function
12656 IS_LOCALLY_CONSTRAINED = 1 << 3,
12657
12658 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12659 IS_LOCALLY_CONSTRAINED,
12660 };
12661 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12662
12663 using Base =
12664 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12665
12666 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12667 // pessimistic about IS_KNOWN_INVARIANT
12668 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12669 : Base(IRP) {}
12670
12671 bool isKnownInvariant() const final {
12672 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12673 }
12674
12675 bool isKnownLocallyInvariant() const final {
12676 if (isKnown(IS_LOCALLY_INVARIANT))
12677 return true;
12678 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12679 }
12680
12681 bool isAssumedInvariant() const final {
12682 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12683 }
12684
12685 bool isAssumedLocallyInvariant() const final {
12686 if (isAssumed(IS_LOCALLY_INVARIANT))
12687 return true;
12688 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12689 }
12690
12691 ChangeStatus updateImpl(Attributor &A) override {
12692 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12693
12694 Changed |= updateNoAlias(A);
12695 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12696 return indicatePessimisticFixpoint();
12697
12698 Changed |= updateNoEffect(A);
12699
12700 Changed |= updateLocalInvariance(A);
12701
12702 return Changed;
12703 }
12704
12705 ChangeStatus manifest(Attributor &A) override {
12706 if (!isKnownInvariant())
12707 return ChangeStatus::UNCHANGED;
12708
12709 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12710 const Value *Ptr = &getAssociatedValue();
12711 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12712 if (U.get() != Ptr)
12713 return true;
12714 auto *I = dyn_cast<Instruction>(U.getUser());
12715 if (!I)
12716 return true;
12717
12718 // Ensure that we are only changing uses from the corresponding callgraph
12719 // SSC in the case that the AA isn't run on the entire module
12720 if (!A.isRunOn(I->getFunction()))
12721 return true;
12722
12723 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12724 return true;
12725
12726 if (auto *LI = dyn_cast<LoadInst>(I)) {
12727 LI->setMetadata(LLVMContext::MD_invariant_load,
12728 MDNode::get(LI->getContext(), {}));
12729 Changed = ChangeStatus::CHANGED;
12730 }
12731 return true;
12732 };
12733
12734 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12735 return Changed;
12736 }
12737
12738 /// See AbstractAttribute::getAsStr().
12739 const std::string getAsStr(Attributor *) const override {
12740 if (isKnownInvariant())
12741 return "load-invariant pointer";
12742 return "non-invariant pointer";
12743 }
12744
12745 /// See AbstractAttribute::trackStatistics().
12746 void trackStatistics() const override {}
12747
12748private:
12749 /// Indicate that noalias is required for the pointer to be invariant.
12750 bool requiresNoAlias() const {
12751 switch (getPositionKind()) {
12752 default:
12753 // Conservatively default to require noalias.
12754 return true;
12755 case IRP_FLOAT:
12756 case IRP_RETURNED:
12757 case IRP_CALL_SITE:
12758 return false;
12759 case IRP_CALL_SITE_RETURNED: {
12760 const auto &CB = cast<CallBase>(getAnchorValue());
12762 &CB, /*MustPreserveNullness=*/false);
12763 }
12764 case IRP_ARGUMENT: {
12765 const Function *F = getAssociatedFunction();
12766 assert(F && "no associated function for argument");
12767 return !isCallableCC(F->getCallingConv());
12768 }
12769 }
12770 }
12771
12772 bool isExternal() const {
12773 const Function *F = getAssociatedFunction();
12774 if (!F)
12775 return true;
12776 return isCallableCC(F->getCallingConv()) &&
12777 getPositionKind() != IRP_CALL_SITE_RETURNED;
12778 }
12779
12780 ChangeStatus updateNoAlias(Attributor &A) {
12781 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12782 return ChangeStatus::UNCHANGED;
12783
12784 // Try to use AANoAlias.
12785 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12786 getIRPosition(), this, DepClassTy::REQUIRED)) {
12787 if (ANoAlias->isKnownNoAlias()) {
12788 addKnownBits(IS_NOALIAS);
12789 return ChangeStatus::CHANGED;
12790 }
12791
12792 if (!ANoAlias->isAssumedNoAlias()) {
12793 removeAssumedBits(IS_NOALIAS);
12794 return ChangeStatus::CHANGED;
12795 }
12796
12797 return ChangeStatus::UNCHANGED;
12798 }
12799
12800 // Try to infer noalias from argument attribute, since it is applicable for
12801 // the duration of the function.
12802 if (const Argument *Arg = getAssociatedArgument()) {
12803 if (Arg->hasNoAliasAttr()) {
12804 addKnownBits(IS_NOALIAS);
12805 return ChangeStatus::UNCHANGED;
12806 }
12807
12808 // Noalias information is not provided, and cannot be inferred,
12809 // so we conservatively assume the pointer aliases.
12810 removeAssumedBits(IS_NOALIAS);
12811 return ChangeStatus::CHANGED;
12812 }
12813
12814 return ChangeStatus::UNCHANGED;
12815 }
12816
12817 ChangeStatus updateNoEffect(Attributor &A) {
12818 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12819 return ChangeStatus::UNCHANGED;
12820
12821 if (!getAssociatedFunction())
12822 return indicatePessimisticFixpoint();
12823
12824 if (isa<AllocaInst>(&getAssociatedValue()))
12825 return indicatePessimisticFixpoint();
12826
12827 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12828 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12829 return !LI || !LI->mayHaveSideEffects();
12830 };
12831 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12832 return indicatePessimisticFixpoint();
12833
12834 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12835 getIRPosition(), this, DepClassTy::REQUIRED)) {
12836 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12837 // attribute
12838 if (!AMemoryBehavior->isAssumedReadOnly())
12839 return indicatePessimisticFixpoint();
12840
12841 if (AMemoryBehavior->isKnownReadOnly()) {
12842 addKnownBits(IS_NOEFFECT);
12843 return ChangeStatus::UNCHANGED;
12844 }
12845
12846 return ChangeStatus::UNCHANGED;
12847 }
12848
12849 if (const Argument *Arg = getAssociatedArgument()) {
12850 if (Arg->onlyReadsMemory()) {
12851 addKnownBits(IS_NOEFFECT);
12852 return ChangeStatus::UNCHANGED;
12853 }
12854
12855 // Readonly information is not provided, and cannot be inferred from
12856 // AAMemoryBehavior.
12857 return indicatePessimisticFixpoint();
12858 }
12859
12860 return ChangeStatus::UNCHANGED;
12861 }
12862
12863 ChangeStatus updateLocalInvariance(Attributor &A) {
12864 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12865 return ChangeStatus::UNCHANGED;
12866
12867 // try to infer invariance from underlying objects
12868 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12869 getIRPosition(), this, DepClassTy::REQUIRED);
12870 if (!AUO)
12871 return ChangeStatus::UNCHANGED;
12872
12873 bool UsedAssumedInformation = false;
12874 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12875 if (!V.getType()->isPointerTy())
12876 return true;
12877 const auto *IsInvariantLoadPointer =
12878 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12879 DepClassTy::REQUIRED);
12880 // Conservatively fail if invariance cannot be inferred.
12881 if (!IsInvariantLoadPointer)
12882 return false;
12883
12884 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12885 return true;
12886 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12887 return false;
12888
12889 UsedAssumedInformation = true;
12890 return true;
12891 };
12892 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12893 return indicatePessimisticFixpoint();
12894
12895 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12897 CB, /*MustPreserveNullness=*/false)) {
12898 for (const Value *Arg : CB->args()) {
12899 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12900 return indicatePessimisticFixpoint();
12901 }
12902 }
12903 }
12904
12905 if (!UsedAssumedInformation) {
12906 // Pointer is known and not just assumed to be locally invariant.
12907 addKnownBits(IS_LOCALLY_INVARIANT);
12908 return ChangeStatus::CHANGED;
12909 }
12910
12911 return ChangeStatus::UNCHANGED;
12912 }
12913};
12914
12915struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12916 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12917 : AAInvariantLoadPointerImpl(IRP, A) {}
12918};
12919
12920struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12921 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12922 : AAInvariantLoadPointerImpl(IRP, A) {}
12923
12924 void initialize(Attributor &) override {
12925 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12926 }
12927};
12928
12929struct AAInvariantLoadPointerCallSiteReturned final
12930 : AAInvariantLoadPointerImpl {
12931 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12932 : AAInvariantLoadPointerImpl(IRP, A) {}
12933
12934 void initialize(Attributor &A) override {
12935 const Function *F = getAssociatedFunction();
12936 assert(F && "no associated function for return from call");
12937
12938 if (!F->isDeclaration() && !F->isIntrinsic())
12939 return AAInvariantLoadPointerImpl::initialize(A);
12940
12941 const auto &CB = cast<CallBase>(getAnchorValue());
12943 &CB, /*MustPreserveNullness=*/false))
12944 return AAInvariantLoadPointerImpl::initialize(A);
12945
12946 if (F->onlyReadsMemory() && F->hasNoSync())
12947 return AAInvariantLoadPointerImpl::initialize(A);
12948
12949 // At this point, the function is opaque, so we conservatively assume
12950 // non-invariance.
12951 indicatePessimisticFixpoint();
12952 }
12953};
12954
12955struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12956 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12957 : AAInvariantLoadPointerImpl(IRP, A) {}
12958
12959 void initialize(Attributor &) override {
12960 const Function *F = getAssociatedFunction();
12961 assert(F && "no associated function for argument");
12962
12963 if (!isCallableCC(F->getCallingConv())) {
12964 addKnownBits(IS_LOCALLY_CONSTRAINED);
12965 return;
12966 }
12967
12968 if (!F->hasLocalLinkage())
12969 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12970 }
12971};
12972
12973struct AAInvariantLoadPointerCallSiteArgument final
12974 : AAInvariantLoadPointerImpl {
12975 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12976 : AAInvariantLoadPointerImpl(IRP, A) {}
12977};
12978} // namespace
12979
12980/// ------------------------ Address Space ------------------------------------
12981namespace {
12982
12983template <typename InstType>
12984static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12985 Value *OriginalValue, PointerType *NewPtrTy,
12986 bool UseOriginalValue) {
12987 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12988 return false;
12989
12990 if (MemInst->isVolatile()) {
12991 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12992 *MemInst->getFunction());
12993 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12994 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12995 return false;
12996 }
12997
12998 if (UseOriginalValue) {
12999 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13000 return true;
13001 }
13002
13003 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13004 CastInst->insertBefore(MemInst->getIterator());
13005 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13006 return true;
13007}
13008
13009struct AAAddressSpaceImpl : public AAAddressSpace {
13010 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13011 : AAAddressSpace(IRP, A) {}
13012
13013 uint32_t getAddressSpace() const override {
13014 assert(isValidState() && "the AA is invalid");
13015 return AssumedAddressSpace;
13016 }
13017
13018 /// See AbstractAttribute::initialize(...).
13019 void initialize(Attributor &A) override {
13020 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13021 "Associated value is not a pointer");
13022
13023 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13024 indicatePessimisticFixpoint();
13025 return;
13026 }
13027
13028 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13029 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13030 if (AS != FlatAS) {
13031 [[maybe_unused]] bool R = takeAddressSpace(AS);
13032 assert(R && "The take should happen");
13033 indicateOptimisticFixpoint();
13034 }
13035 }
13036
13037 ChangeStatus updateImpl(Attributor &A) override {
13038 uint32_t OldAddressSpace = AssumedAddressSpace;
13039 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13040
13041 auto CheckAddressSpace = [&](Value &Obj) {
13042 // Ignore undef.
13043 if (isa<UndefValue>(&Obj))
13044 return true;
13045
13046 // If the object already has a non-flat address space, we simply take it.
13047 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13048 if (ObjAS != FlatAS)
13049 return takeAddressSpace(ObjAS);
13050
13051 // At this point, we know Obj is in the flat address space. For a final
13052 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13053 // associated function, if possible.
13054 Function *F = nullptr;
13055 if (auto *Arg = dyn_cast<Argument>(&Obj))
13056 F = Arg->getParent();
13057 else if (auto *I = dyn_cast<Instruction>(&Obj))
13058 F = I->getFunction();
13059
13060 // Use getAssumedAddrSpace if the associated function exists.
13061 if (F) {
13062 auto *TTI =
13063 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13064 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13065 if (AssumedAS != ~0U)
13066 return takeAddressSpace(AssumedAS);
13067 }
13068
13069 // Now we can't do anything else but to take the flat AS.
13070 return takeAddressSpace(FlatAS);
13071 };
13072
13073 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13074 DepClassTy::REQUIRED);
13075 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13076 return indicatePessimisticFixpoint();
13077
13078 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13079 : ChangeStatus::CHANGED;
13080 }
13081
13082 /// See AbstractAttribute::manifest(...).
13083 ChangeStatus manifest(Attributor &A) override {
13084 unsigned NewAS = getAddressSpace();
13085
13086 if (NewAS == InvalidAddressSpace ||
13087 NewAS == getAssociatedType()->getPointerAddressSpace())
13088 return ChangeStatus::UNCHANGED;
13089
13090 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13091
13092 Value *AssociatedValue = &getAssociatedValue();
13093 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13094
13095 PointerType *NewPtrTy =
13096 PointerType::get(getAssociatedType()->getContext(), NewAS);
13097 bool UseOriginalValue =
13098 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13099
13100 bool Changed = false;
13101
13102 auto Pred = [&](const Use &U, bool &) {
13103 if (U.get() != AssociatedValue)
13104 return true;
13105 auto *Inst = dyn_cast<Instruction>(U.getUser());
13106 if (!Inst)
13107 return true;
13108 // This is a WA to make sure we only change uses from the corresponding
13109 // CGSCC if the AA is run on CGSCC instead of the entire module.
13110 if (!A.isRunOn(Inst->getFunction()))
13111 return true;
13112 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13113 Changed |=
13114 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13115 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13116 Changed |=
13117 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13118 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13119 Changed |=
13120 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13121 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13122 Changed |=
13123 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13124 }
13125 return true;
13126 };
13127
13128 // It doesn't matter if we can't check all uses as we can simply
13129 // conservatively ignore those that can not be visited.
13130 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13131 /* CheckBBLivenessOnly */ true);
13132
13133 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13134 }
13135
13136 /// See AbstractAttribute::getAsStr().
13137 const std::string getAsStr(Attributor *A) const override {
13138 if (!isValidState())
13139 return "addrspace(<invalid>)";
13140 return "addrspace(" +
13141 (AssumedAddressSpace == InvalidAddressSpace
13142 ? "none"
13143 : std::to_string(AssumedAddressSpace)) +
13144 ")";
13145 }
13146
13147private:
13148 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13149
13150 bool takeAddressSpace(uint32_t AS) {
13151 if (AssumedAddressSpace == InvalidAddressSpace) {
13152 AssumedAddressSpace = AS;
13153 return true;
13154 }
13155 return AssumedAddressSpace == AS;
13156 }
13157
13158 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13159 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13160 assert(I->getSrcAddressSpace() != FlatAS &&
13161 "there should not be flat AS -> non-flat AS");
13162 return I->getPointerOperand();
13163 }
13164 if (auto *C = dyn_cast<ConstantExpr>(V))
13165 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13166 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13167 FlatAS &&
13168 "there should not be flat AS -> non-flat AS X");
13169 return C->getOperand(0);
13170 }
13171 return V;
13172 }
13173};
13174
13175struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13176 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13177 : AAAddressSpaceImpl(IRP, A) {}
13178
13179 void trackStatistics() const override {
13181 }
13182};
13183
13184struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13185 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13186 : AAAddressSpaceImpl(IRP, A) {}
13187
13188 /// See AbstractAttribute::initialize(...).
13189 void initialize(Attributor &A) override {
13190 // TODO: we don't rewrite function argument for now because it will need to
13191 // rewrite the function signature and all call sites.
13192 (void)indicatePessimisticFixpoint();
13193 }
13194
13195 void trackStatistics() const override {
13196 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13197 }
13198};
13199
13200struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13201 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13202 : AAAddressSpaceImpl(IRP, A) {}
13203
13204 void trackStatistics() const override {
13205 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13206 }
13207};
13208
13209struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13210 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13211 : AAAddressSpaceImpl(IRP, A) {}
13212
13213 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13214};
13215
13216struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13217 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13218 : AAAddressSpaceImpl(IRP, A) {}
13219
13220 /// See AbstractAttribute::initialize(...).
13221 void initialize(Attributor &A) override {
13222 // TODO: we don't rewrite call site argument for now because it will need to
13223 // rewrite the function signature of the callee.
13224 (void)indicatePessimisticFixpoint();
13225 }
13226
13227 void trackStatistics() const override {
13228 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13229 }
13230};
13231} // namespace
13232
13233/// ------------------------ No Alias Address Space ---------------------------
13234// This attribute assumes flat address space can alias all other address space
13235
13236// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13237// But merging it created failing cased on gateway test that cannot be
13238// reproduced locally. So should open a separated PR to handle the merge of
13239// AANoAliasAddrSpace and AAAddressSpace attribute
13240
13241namespace {
13242struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13243 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13244 : AANoAliasAddrSpace(IRP, A) {}
13245
13246 void initialize(Attributor &A) override {
13247 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13248 "Associated value is not a pointer");
13249
13250 resetASRanges(A);
13251
13252 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13253 if (!FlatAS.has_value()) {
13254 indicatePessimisticFixpoint();
13255 return;
13256 }
13257
13258 removeAS(*FlatAS);
13259
13260 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13261 if (AS != *FlatAS) {
13262 removeAS(AS);
13263 indicateOptimisticFixpoint();
13264 }
13265 }
13266
13267 ChangeStatus updateImpl(Attributor &A) override {
13268 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13269 uint32_t OldAssumed = getAssumed();
13270
13271 auto CheckAddressSpace = [&](Value &Obj) {
13272 if (isa<PoisonValue>(&Obj))
13273 return true;
13274
13275 unsigned AS = Obj.getType()->getPointerAddressSpace();
13276 if (AS == FlatAS)
13277 return false;
13278
13279 removeAS(Obj.getType()->getPointerAddressSpace());
13280 return true;
13281 };
13282
13283 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13284 getIRPosition(), this, DepClassTy::REQUIRED);
13285 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13286 return indicatePessimisticFixpoint();
13287
13288 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13289 : ChangeStatus::CHANGED;
13290 }
13291
13292 /// See AbstractAttribute::manifest(...).
13293 ChangeStatus manifest(Attributor &A) override {
13294 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13295
13296 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13297 if (AS != FlatAS || Map.empty())
13298 return ChangeStatus::UNCHANGED;
13299
13300 LLVMContext &Ctx = getAssociatedValue().getContext();
13301 MDNode *NoAliasASNode = nullptr;
13302 MDBuilder MDB(Ctx);
13303 // Has to use iterator to get the range info.
13304 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13305 if (!I.value())
13306 continue;
13307 unsigned Upper = I.stop();
13308 unsigned Lower = I.start();
13309 if (!NoAliasASNode) {
13310 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13311 continue;
13312 }
13313 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13314 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13315 }
13316
13317 Value *AssociatedValue = &getAssociatedValue();
13318 bool Changed = false;
13319
13320 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13321 if (U.get() != AssociatedValue)
13322 return true;
13323 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13324 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13325 return true;
13326 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13328 return true;
13329 if (!A.isRunOn(Inst->getFunction()))
13330 return true;
13331 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13332 Changed = true;
13333 return true;
13334 };
13335 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13336 /*CheckBBLivenessOnly=*/true);
13337 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13338 }
13339
13340 /// See AbstractAttribute::getAsStr().
13341 const std::string getAsStr(Attributor *A) const override {
13342 if (!isValidState())
13343 return "<invalid>";
13344 std::string Str;
13345 raw_string_ostream OS(Str);
13346 OS << "CanNotBeAddrSpace(";
13347 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13348 unsigned Upper = I.stop();
13349 unsigned Lower = I.start();
13350 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13351 }
13352 OS << " )";
13353 return OS.str();
13354 }
13355
13356private:
13357 void removeAS(unsigned AS) {
13358 RangeMap::iterator I = Map.find(AS);
13359
13360 if (I != Map.end()) {
13361 unsigned Upper = I.stop();
13362 unsigned Lower = I.start();
13363 I.erase();
13364 if (Upper == Lower)
13365 return;
13366 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13367 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13368 if (AS != 0 && Lower <= AS - 1)
13369 Map.insert(Lower, AS - 1, true);
13370 }
13371 }
13372
13373 void resetASRanges(Attributor &A) {
13374 Map.clear();
13375 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13376 }
13377};
13378
13379struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13380 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13381 : AANoAliasAddrSpaceImpl(IRP, A) {}
13382
13383 void trackStatistics() const override {
13384 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13385 }
13386};
13387
13388struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13389 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13390 : AANoAliasAddrSpaceImpl(IRP, A) {}
13391
13392 void trackStatistics() const override {
13393 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13394 }
13395};
13396
13397struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13398 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13399 : AANoAliasAddrSpaceImpl(IRP, A) {}
13400
13401 void trackStatistics() const override {
13402 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13403 }
13404};
13405
13406struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13407 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13408 : AANoAliasAddrSpaceImpl(IRP, A) {}
13409
13410 void trackStatistics() const override {
13411 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13412 }
13413};
13414
13415struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13416 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13417 : AANoAliasAddrSpaceImpl(IRP, A) {}
13418
13419 void trackStatistics() const override {
13420 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13421 }
13422};
13423} // namespace
13424/// ----------- Allocation Info ----------
13425namespace {
13426struct AAAllocationInfoImpl : public AAAllocationInfo {
13427 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13428 : AAAllocationInfo(IRP, A) {}
13429
13430 std::optional<TypeSize> getAllocatedSize() const override {
13431 assert(isValidState() && "the AA is invalid");
13432 return AssumedAllocatedSize;
13433 }
13434
13435 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13436 const DataLayout &DL) {
13437
13438 // TODO: implement case for malloc like instructions
13439 switch (I->getOpcode()) {
13440 case Instruction::Alloca: {
13441 AllocaInst *AI = cast<AllocaInst>(I);
13442 return AI->getAllocationSize(DL);
13443 }
13444 default:
13445 return std::nullopt;
13446 }
13447 }
13448
13449 ChangeStatus updateImpl(Attributor &A) override {
13450
13451 const IRPosition &IRP = getIRPosition();
13452 Instruction *I = IRP.getCtxI();
13453
13454 // TODO: update check for malloc like calls
13455 if (!isa<AllocaInst>(I))
13456 return indicatePessimisticFixpoint();
13457
13458 bool IsKnownNoCapture;
13460 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13461 return indicatePessimisticFixpoint();
13462
13463 const AAPointerInfo *PI =
13464 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13465
13466 if (!PI)
13467 return indicatePessimisticFixpoint();
13468
13469 if (!PI->getState().isValidState() || PI->reachesReturn())
13470 return indicatePessimisticFixpoint();
13471
13472 const DataLayout &DL = A.getDataLayout();
13473 const auto AllocationSize = findInitialAllocationSize(I, DL);
13474
13475 // If allocation size is nullopt, we give up.
13476 if (!AllocationSize)
13477 return indicatePessimisticFixpoint();
13478
13479 // For zero sized allocations, we give up.
13480 // Since we can't reduce further
13481 if (*AllocationSize == 0)
13482 return indicatePessimisticFixpoint();
13483
13484 int64_t BinSize = PI->numOffsetBins();
13485
13486 // TODO: implement for multiple bins
13487 if (BinSize > 1)
13488 return indicatePessimisticFixpoint();
13489
13490 if (BinSize == 0) {
13491 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13492 if (!changeAllocationSize(NewAllocationSize))
13493 return ChangeStatus::UNCHANGED;
13494 return ChangeStatus::CHANGED;
13495 }
13496
13497 // TODO: refactor this to be part of multiple bin case
13498 const auto &It = PI->begin();
13499
13500 // TODO: handle if Offset is not zero
13501 if (It->first.Offset != 0)
13502 return indicatePessimisticFixpoint();
13503
13504 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13505
13506 if (SizeOfBin >= *AllocationSize)
13507 return indicatePessimisticFixpoint();
13508
13509 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13510
13511 if (!changeAllocationSize(NewAllocationSize))
13512 return ChangeStatus::UNCHANGED;
13513
13514 return ChangeStatus::CHANGED;
13515 }
13516
13517 /// See AbstractAttribute::manifest(...).
13518 ChangeStatus manifest(Attributor &A) override {
13519
13520 assert(isValidState() &&
13521 "Manifest should only be called if the state is valid.");
13522
13523 Instruction *I = getIRPosition().getCtxI();
13524
13525 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13526
13527 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13528
13529 switch (I->getOpcode()) {
13530 // TODO: add case for malloc like calls
13531 case Instruction::Alloca: {
13532
13533 AllocaInst *AI = cast<AllocaInst>(I);
13534
13535 Type *CharType = Type::getInt8Ty(I->getContext());
13536
13537 auto *NumBytesToValue =
13538 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13539
13540 BasicBlock::iterator insertPt = AI->getIterator();
13541 insertPt = std::next(insertPt);
13542 AllocaInst *NewAllocaInst =
13543 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13544 AI->getAlign(), AI->getName(), insertPt);
13545
13546 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13547 return ChangeStatus::CHANGED;
13548
13549 break;
13550 }
13551 default:
13552 break;
13553 }
13554
13555 return ChangeStatus::UNCHANGED;
13556 }
13557
13558 /// See AbstractAttribute::getAsStr().
13559 const std::string getAsStr(Attributor *A) const override {
13560 if (!isValidState())
13561 return "allocationinfo(<invalid>)";
13562 return "allocationinfo(" +
13563 (AssumedAllocatedSize == HasNoAllocationSize
13564 ? "none"
13565 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13566 ")";
13567 }
13568
13569private:
13570 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13571
13572 // Maintain the computed allocation size of the object.
13573 // Returns (bool) weather the size of the allocation was modified or not.
13574 bool changeAllocationSize(std::optional<TypeSize> Size) {
13575 if (AssumedAllocatedSize == HasNoAllocationSize ||
13576 AssumedAllocatedSize != Size) {
13577 AssumedAllocatedSize = Size;
13578 return true;
13579 }
13580 return false;
13581 }
13582};
13583
13584struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13585 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13586 : AAAllocationInfoImpl(IRP, A) {}
13587
13588 void trackStatistics() const override {
13589 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13590 }
13591};
13592
13593struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13594 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13595 : AAAllocationInfoImpl(IRP, A) {}
13596
13597 /// See AbstractAttribute::initialize(...).
13598 void initialize(Attributor &A) override {
13599 // TODO: we don't rewrite function argument for now because it will need to
13600 // rewrite the function signature and all call sites
13601 (void)indicatePessimisticFixpoint();
13602 }
13603
13604 void trackStatistics() const override {
13605 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13606 }
13607};
13608
13609struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13610 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13611 : AAAllocationInfoImpl(IRP, A) {}
13612
13613 void trackStatistics() const override {
13614 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13615 }
13616};
13617
13618struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13619 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13620 : AAAllocationInfoImpl(IRP, A) {}
13621
13622 void trackStatistics() const override {
13623 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13624 }
13625};
13626
13627struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13628 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13629 : AAAllocationInfoImpl(IRP, A) {}
13630
13631 /// See AbstractAttribute::initialize(...).
13632 void initialize(Attributor &A) override {
13633
13634 (void)indicatePessimisticFixpoint();
13635 }
13636
13637 void trackStatistics() const override {
13638 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13639 }
13640};
13641} // namespace
13642
13643const char AANoUnwind::ID = 0;
13644const char AANoSync::ID = 0;
13645const char AANoFree::ID = 0;
13646const char AANonNull::ID = 0;
13647const char AAMustProgress::ID = 0;
13648const char AANoRecurse::ID = 0;
13649const char AANonConvergent::ID = 0;
13650const char AAWillReturn::ID = 0;
13651const char AAUndefinedBehavior::ID = 0;
13652const char AANoAlias::ID = 0;
13653const char AAIntraFnReachability::ID = 0;
13654const char AANoReturn::ID = 0;
13655const char AAIsDead::ID = 0;
13656const char AADereferenceable::ID = 0;
13657const char AAAlign::ID = 0;
13658const char AAInstanceInfo::ID = 0;
13659const char AANoCapture::ID = 0;
13660const char AAValueSimplify::ID = 0;
13661const char AAHeapToStack::ID = 0;
13662const char AAPrivatizablePtr::ID = 0;
13663const char AAMemoryBehavior::ID = 0;
13664const char AAMemoryLocation::ID = 0;
13665const char AAValueConstantRange::ID = 0;
13666const char AAPotentialConstantValues::ID = 0;
13667const char AAPotentialValues::ID = 0;
13668const char AANoUndef::ID = 0;
13669const char AANoFPClass::ID = 0;
13670const char AACallEdges::ID = 0;
13671const char AAInterFnReachability::ID = 0;
13672const char AAPointerInfo::ID = 0;
13673const char AAAssumptionInfo::ID = 0;
13674const char AAUnderlyingObjects::ID = 0;
13675const char AAInvariantLoadPointer::ID = 0;
13676const char AAAddressSpace::ID = 0;
13677const char AANoAliasAddrSpace::ID = 0;
13678const char AAAllocationInfo::ID = 0;
13679const char AAIndirectCallInfo::ID = 0;
13680const char AAGlobalValueInfo::ID = 0;
13681const char AADenormalFPMath::ID = 0;
13682
13683// Macro magic to create the static generator function for attributes that
13684// follow the naming scheme.
13685
13686#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13687 case IRPosition::PK: \
13688 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13689
13690#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13691 case IRPosition::PK: \
13692 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13693 ++NumAAs; \
13694 break;
13695
13696#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13697 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13698 CLASS *AA = nullptr; \
13699 switch (IRP.getPositionKind()) { \
13700 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13701 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13702 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13703 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13704 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13705 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13706 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13707 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13708 } \
13709 return *AA; \
13710 }
13711
13712#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13713 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13714 CLASS *AA = nullptr; \
13715 switch (IRP.getPositionKind()) { \
13716 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13717 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13718 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13719 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13720 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13721 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13722 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13723 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13724 } \
13725 return *AA; \
13726 }
13727
13728#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13729 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13730 CLASS *AA = nullptr; \
13731 switch (IRP.getPositionKind()) { \
13732 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13733 default: \
13734 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13735 " position!"); \
13736 } \
13737 return *AA; \
13738 }
13739
13740#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13741 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13742 CLASS *AA = nullptr; \
13743 switch (IRP.getPositionKind()) { \
13744 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13745 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13746 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13747 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13748 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13749 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13750 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13751 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13752 } \
13753 return *AA; \
13754 }
13755
13756#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13757 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13758 CLASS *AA = nullptr; \
13759 switch (IRP.getPositionKind()) { \
13760 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13761 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13762 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13763 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13764 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13765 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13766 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13767 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13768 } \
13769 return *AA; \
13770 }
13771
13772#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13773 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13774 CLASS *AA = nullptr; \
13775 switch (IRP.getPositionKind()) { \
13776 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13777 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13778 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13779 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13780 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13781 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13783 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13784 } \
13785 return *AA; \
13786 }
13787
13797
13815
13820
13825
13832
13834
13835#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13836#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13837#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13838#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13839#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13840#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13841#undef SWITCH_PK_CREATE
13842#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)
Definition CFG.cpp:135
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:1577
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
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:493
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
unsigned getNumSuccessors() const
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
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
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:407
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
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:283
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:164
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:729
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:329
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:2025
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:527
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2788
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:285
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:723
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:754
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:759
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:45
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:267
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:270
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:139
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:256
static constexpr uint64_t MaximumAlignment
Definition Value.h:832
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:259
iterator_range< user_iterator > users()
Definition Value.h:427
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:347
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:831
iterator_range< use_iterator > uses()
Definition Value.h:381
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
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:323
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 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.
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:182
@ Intraprocedural
Definition Attributor.h:183
@ Interprocedural
Definition Attributor.h:184
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.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
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:1739
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:1669
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:370
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:296
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:1630
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:336
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:366
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:24
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:1746
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:1636
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:364
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:425
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:496
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:508
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:509
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:507
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:330
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:355
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)
GenericCycleInfo< SSAContext > CycleInfo
Definition CycleInfo.h:23
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:241
static constexpr int64_t Unknown
Definition Attributor.h:320
static RangeTy getUnknown()
Definition Attributor.h:247
Value * getValue() const
Definition Attributor.h:194
const Instruction * getCtxI() const
Definition Attributor.h:195
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:593
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:724
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:661
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:643
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:617
CallBase CallBaseContext
Definition Attributor.h:596
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:811
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:629
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:666
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:607
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:603
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:606
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:604
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:605
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:608
@ IRP_INVALID
An invalid position.
Definition Attributor.h:600
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:777
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:650
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:800
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:636
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:939
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:791
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:710
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:820
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:689
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:889
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:921
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:656
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:765
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.