LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static inline Access getEmptyKey();
749 static inline Access getTombstoneKey();
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
756 static inline AA::RangeTy getEmptyKey() {
757 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
758 return AA::RangeTy{EmptyKey, EmptyKey};
759 }
760
761 static inline AA::RangeTy getTombstoneKey() {
762 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
763 return AA::RangeTy{TombstoneKey, TombstoneKey};
764 }
765
771
772 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
773 return A == B;
774 }
775};
776
777/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
778/// but the instruction
779struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
782 static inline Access getEmptyKey();
783 static inline Access getTombstoneKey();
784 static unsigned getHashValue(const Access &A);
785 static bool isEqual(const Access &LHS, const Access &RHS);
786};
787
788} // namespace llvm
789
790/// A type to track pointer/struct usage and accesses for AAPointerInfo.
792 /// Return the best possible representable state.
793 static State getBestState(const State &SIS) { return State(); }
794
795 /// Return the worst possible representable state.
796 static State getWorstState(const State &SIS) {
797 State R;
798 R.indicatePessimisticFixpoint();
799 return R;
800 }
801
802 State() = default;
803 State(State &&SIS) = default;
804
805 const State &getAssumed() const { return *this; }
806
807 /// See AbstractState::isValidState().
808 bool isValidState() const override { return BS.isValidState(); }
809
810 /// See AbstractState::isAtFixpoint().
811 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
812
813 /// See AbstractState::indicateOptimisticFixpoint().
815 BS.indicateOptimisticFixpoint();
817 }
818
819 /// See AbstractState::indicatePessimisticFixpoint().
821 BS.indicatePessimisticFixpoint();
823 }
824
825 State &operator=(const State &R) {
826 if (this == &R)
827 return *this;
828 BS = R.BS;
829 AccessList = R.AccessList;
830 OffsetBins = R.OffsetBins;
831 RemoteIMap = R.RemoteIMap;
832 ReturnedOffsets = R.ReturnedOffsets;
833 return *this;
834 }
835
837 if (this == &R)
838 return *this;
839 std::swap(BS, R.BS);
840 std::swap(AccessList, R.AccessList);
841 std::swap(OffsetBins, R.OffsetBins);
842 std::swap(RemoteIMap, R.RemoteIMap);
843 std::swap(ReturnedOffsets, R.ReturnedOffsets);
844 return *this;
845 }
846
847 /// Add a new Access to the state at offset \p Offset and with size \p Size.
848 /// The access is associated with \p I, writes \p Content (if anything), and
849 /// is of kind \p Kind. If an Access already exists for the same \p I and same
850 /// \p RemoteI, the two are combined, potentially losing information about
851 /// offset and size. The resulting access must now be moved from its original
852 /// OffsetBin to the bin for its new offset.
853 ///
854 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
856 Instruction &I, std::optional<Value *> Content,
858 Instruction *RemoteI = nullptr);
859
862 int64_t numOffsetBins() const { return OffsetBins.size(); }
863
864 const AAPointerInfo::Access &getAccess(unsigned Index) const {
865 return AccessList[Index];
866 }
867
868protected:
869 // Every memory instruction results in an Access object. We maintain a list of
870 // all Access objects that we own, along with the following maps:
871 //
872 // - OffsetBins: RangeTy -> { Access }
873 // - RemoteIMap: RemoteI x LocalI -> Access
874 //
875 // A RemoteI is any instruction that accesses memory. RemoteI is different
876 // from LocalI if and only if LocalI is a call; then RemoteI is some
877 // instruction in the callgraph starting from LocalI. Multiple paths in the
878 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
879 // are all combined into a single Access object. This may result in loss of
880 // information in RangeTy in the Access object.
884
885 /// Flag to determine if the underlying pointer is reaching a return statement
886 /// in the associated function or not. Returns in other functions cause
887 /// invalidation.
889
890 /// See AAPointerInfo::forallInterferingAccesses.
891 template <typename F>
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 for (const auto &It : OffsetBins) {
897 AA::RangeTy ItRange = It.getFirst();
898 if (!Range.mayOverlap(ItRange))
899 continue;
900 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
901 for (auto Index : It.getSecond()) {
902 auto &Access = AccessList[Index];
903 if (!CB(Access, IsExact))
904 return false;
905 }
906 }
907 return true;
908 }
909
910 /// See AAPointerInfo::forallInterferingAccesses.
911 template <typename F>
913 AA::RangeTy &Range) const {
914 if (!isValidState() || !ReturnedOffsets.isUnassigned())
915 return false;
916
917 auto LocalList = RemoteIMap.find(&I);
918 if (LocalList == RemoteIMap.end()) {
919 return true;
920 }
921
922 for (unsigned Index : LocalList->getSecond()) {
923 for (auto &R : AccessList[Index]) {
924 Range &= R;
925 if (Range.offsetAndSizeAreUnknown())
926 break;
927 }
928 }
930 }
931
932private:
933 /// State to track fixpoint and validity.
934 BooleanState BS;
935};
936
939 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
940 Instruction *RemoteI) {
941 RemoteI = RemoteI ? RemoteI : &I;
942
943 // Check if we have an access for this instruction, if not, simply add it.
944 auto &LocalList = RemoteIMap[RemoteI];
945 bool AccExists = false;
946 unsigned AccIndex = AccessList.size();
947 for (auto Index : LocalList) {
948 auto &A = AccessList[Index];
949 if (A.getLocalInst() == &I) {
950 AccExists = true;
951 AccIndex = Index;
952 break;
953 }
954 }
955
956 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
957 LLVM_DEBUG(if (ToAdd.size()) dbgs()
958 << "[AAPointerInfo] Inserting access in new offset bins\n";);
959
960 for (auto Key : ToAdd) {
961 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
962 OffsetBins[Key].insert(AccIndex);
963 }
964 };
965
966 if (!AccExists) {
967 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
968 assert((AccessList.size() == AccIndex + 1) &&
969 "New Access should have been at AccIndex");
970 LocalList.push_back(AccIndex);
971 AddToBins(AccessList[AccIndex].getRanges());
973 }
974
975 // Combine the new Access with the existing Access, and then update the
976 // mapping in the offset bins.
977 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
978 auto &Current = AccessList[AccIndex];
979 auto Before = Current;
980 Current &= Acc;
981 if (Current == Before)
983
984 auto &ExistingRanges = Before.getRanges();
985 auto &NewRanges = Current.getRanges();
986
987 // Ranges that are in the old access but not the new access need to be removed
988 // from the offset bins.
990 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
991 LLVM_DEBUG(if (ToRemove.size()) dbgs()
992 << "[AAPointerInfo] Removing access from old offset bins\n";);
993
994 for (auto Key : ToRemove) {
995 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
996 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
997 auto &Bin = OffsetBins[Key];
998 assert(Bin.count(AccIndex) &&
999 "Expected bin to actually contain the Access.");
1000 Bin.erase(AccIndex);
1001 }
1002
1003 // Ranges that are in the new access but not the old access need to be added
1004 // to the offset bins.
1006 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1007 AddToBins(ToAdd);
1008 return ChangeStatus::CHANGED;
1009}
1010
1011namespace {
1012
1013#ifndef NDEBUG
1015 const AAPointerInfo::OffsetInfo &OI) {
1016 OS << llvm::interleaved_array(OI);
1017 return OS;
1018}
1019#endif // NDEBUG
1020
1021struct AAPointerInfoImpl
1022 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1024 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1025
1026 /// See AbstractAttribute::getAsStr().
1027 const std::string getAsStr(Attributor *A) const override {
1028 return std::string("PointerInfo ") +
1029 (isValidState() ? (std::string("#") +
1030 std::to_string(OffsetBins.size()) + " bins")
1031 : "<invalid>") +
1032 (reachesReturn()
1033 ? (" (returned:" +
1034 join(map_range(ReturnedOffsets,
1035 [](int64_t O) { return std::to_string(O); }),
1036 ", ") +
1037 ")")
1038 : "");
1039 }
1040
1041 /// See AbstractAttribute::manifest(...).
1042 ChangeStatus manifest(Attributor &A) override {
1043 return AAPointerInfo::manifest(A);
1044 }
1045
1046 const_bin_iterator begin() const override { return State::begin(); }
1047 const_bin_iterator end() const override { return State::end(); }
1048 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1049 bool reachesReturn() const override {
1050 return !ReturnedOffsets.isUnassigned();
1051 }
1052 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1053 if (ReturnedOffsets.isUnknown()) {
1054 OI.setUnknown();
1055 return;
1056 }
1057
1058 OffsetInfo MergedOI;
1059 for (auto Offset : ReturnedOffsets) {
1060 OffsetInfo TmpOI = OI;
1061 TmpOI.addToAll(Offset);
1062 MergedOI.merge(TmpOI);
1063 }
1064 OI = std::move(MergedOI);
1065 }
1066
1067 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1068 if (ReturnedOffsets.isUnknown())
1069 return ChangeStatus::UNCHANGED;
1070 if (ReachedReturnedOffsets.isUnknown()) {
1071 ReturnedOffsets.setUnknown();
1072 return ChangeStatus::CHANGED;
1073 }
1074 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1075 return ChangeStatus::CHANGED;
1076 return ChangeStatus::UNCHANGED;
1077 }
1078
1079 bool forallInterferingAccesses(
1080 AA::RangeTy Range,
1081 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1082 const override {
1083 return State::forallInterferingAccesses(Range, CB);
1084 }
1085
1086 bool forallInterferingAccesses(
1087 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1088 bool FindInterferingWrites, bool FindInterferingReads,
1089 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1090 AA::RangeTy &Range,
1091 function_ref<bool(const Access &)> SkipCB) const override {
1092 HasBeenWrittenTo = false;
1093
1094 SmallPtrSet<const Access *, 8> DominatingWrites;
1095 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1096
1097 Function &Scope = *I.getFunction();
1098 bool IsKnownNoSync;
1099 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1100 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1101 IsKnownNoSync);
1102 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1103 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1104 bool AllInSameNoSyncFn = IsAssumedNoSync;
1105 bool InstIsExecutedByInitialThreadOnly =
1106 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1107
1108 // If the function is not ending in aligned barriers, we need the stores to
1109 // be in aligned barriers. The load being in one is not sufficient since the
1110 // store might be executed by a thread that disappears after, causing the
1111 // aligned barrier guarding the load to unblock and the load to read a value
1112 // that has no CFG path to the load.
1113 bool InstIsExecutedInAlignedRegion =
1114 FindInterferingReads && ExecDomainAA &&
1115 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1116
1117 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1118 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1119
1120 InformationCache &InfoCache = A.getInfoCache();
1121 bool IsThreadLocalObj =
1122 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1123
1124 // Helper to determine if we need to consider threading, which we cannot
1125 // right now. However, if the function is (assumed) nosync or the thread
1126 // executing all instructions is the main thread only we can ignore
1127 // threading. Also, thread-local objects do not require threading reasoning.
1128 // Finally, we can ignore threading if either access is executed in an
1129 // aligned region.
1130 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1131 if (IsThreadLocalObj || AllInSameNoSyncFn)
1132 return true;
1133 const auto *FnExecDomainAA =
1134 I.getFunction() == &Scope
1135 ? ExecDomainAA
1136 : A.lookupAAFor<AAExecutionDomain>(
1137 IRPosition::function(*I.getFunction()), &QueryingAA,
1138 DepClassTy::NONE);
1139 if (!FnExecDomainAA)
1140 return false;
1141 if (InstIsExecutedInAlignedRegion ||
1142 (FindInterferingWrites &&
1143 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1144 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1145 return true;
1146 }
1147 if (InstIsExecutedByInitialThreadOnly &&
1148 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1149 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1150 return true;
1151 }
1152 return false;
1153 };
1154
1155 // Helper to determine if the access is executed by the same thread as the
1156 // given instruction, for now it is sufficient to avoid any potential
1157 // threading effects as we cannot deal with them anyway.
1158 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1159 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1160 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1161 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1162 };
1163
1164 // TODO: Use inter-procedural reachability and dominance.
1165 bool IsKnownNoRecurse;
1167 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1168 IsKnownNoRecurse);
1169
1170 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1171 // AAExecutionDomain) such that we allow scopes other than kernels as long
1172 // as the reaching kernels are disjoint.
1173 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1174 bool ObjHasKernelLifetime = false;
1175 const bool UseDominanceReasoning =
1176 FindInterferingWrites && IsKnownNoRecurse;
1177 const DominatorTree *DT =
1178 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1179
1180 // Helper to check if a value has "kernel lifetime", that is it will not
1181 // outlive a GPU kernel. This is true for shared, constant, and local
1182 // globals on AMD and NVIDIA GPUs.
1183 auto HasKernelLifetime = [&](Value *V, Module &M) {
1184 if (!AA::isGPU(M))
1185 return false;
1186 unsigned VAS = V->getType()->getPointerAddressSpace();
1187 return AA::isGPUSharedAddressSpace(M, VAS) ||
1190 };
1191
1192 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1193 // to determine if we should look at reachability from the callee. For
1194 // certain pointers we know the lifetime and we do not have to step into the
1195 // callee to determine reachability as the pointer would be dead in the
1196 // callee. See the conditional initialization below.
1197 std::function<bool(const Function &)> IsLiveInCalleeCB;
1198
1199 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1200 // If the alloca containing function is not recursive the alloca
1201 // must be dead in the callee.
1202 const Function *AIFn = AI->getFunction();
1203 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1204 bool IsKnownNoRecurse;
1206 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1207 IsKnownNoRecurse)) {
1208 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1209 }
1210 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1211 // If the global has kernel lifetime we can stop if we reach a kernel
1212 // as it is "dead" in the (unknown) callees.
1213 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1214 if (ObjHasKernelLifetime)
1215 IsLiveInCalleeCB = [&A](const Function &Fn) {
1216 return !A.getInfoCache().isKernel(Fn);
1217 };
1218 }
1219
1220 // Set of accesses/instructions that will overwrite the result and are
1221 // therefore blockers in the reachability traversal.
1222 AA::InstExclusionSetTy ExclusionSet;
1223
1224 auto AccessCB = [&](const Access &Acc, bool Exact) {
1225 Function *AccScope = Acc.getRemoteInst()->getFunction();
1226 bool AccInSameScope = AccScope == &Scope;
1227
1228 // If the object has kernel lifetime we can ignore accesses only reachable
1229 // by other kernels. For now we only skip accesses *in* other kernels.
1230 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1231 A.getInfoCache().isKernel(*AccScope))
1232 return true;
1233
1234 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1235 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1236 ExclusionSet.insert(Acc.getRemoteInst());
1237 }
1238
1239 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1240 (!FindInterferingReads || !Acc.isRead()))
1241 return true;
1242
1243 bool Dominates = FindInterferingWrites && DT && Exact &&
1244 Acc.isMustAccess() && AccInSameScope &&
1245 DT->dominates(Acc.getRemoteInst(), &I);
1246 if (Dominates)
1247 DominatingWrites.insert(&Acc);
1248
1249 // Track if all interesting accesses are in the same `nosync` function as
1250 // the given instruction.
1251 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1252
1253 InterferingAccesses.push_back({&Acc, Exact});
1254 return true;
1255 };
1256 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1257 return false;
1258
1259 HasBeenWrittenTo = !DominatingWrites.empty();
1260
1261 // Dominating writes form a chain, find the least/lowest member.
1262 Instruction *LeastDominatingWriteInst = nullptr;
1263 for (const Access *Acc : DominatingWrites) {
1264 if (!LeastDominatingWriteInst) {
1265 LeastDominatingWriteInst = Acc->getRemoteInst();
1266 } else if (DT->dominates(LeastDominatingWriteInst,
1267 Acc->getRemoteInst())) {
1268 LeastDominatingWriteInst = Acc->getRemoteInst();
1269 }
1270 }
1271
1272 // Helper to determine if we can skip a specific write access.
1273 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1274 if (SkipCB && SkipCB(Acc))
1275 return true;
1276 if (!CanIgnoreThreading(Acc))
1277 return false;
1278
1279 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1280 // If we successfully excluded all effects we are interested in, the
1281 // access can be skipped.
1282 bool ReadChecked = !FindInterferingReads;
1283 bool WriteChecked = !FindInterferingWrites;
1284
1285 // If the instruction cannot reach the access, the former does not
1286 // interfere with what the access reads.
1287 if (!ReadChecked) {
1288 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1289 &ExclusionSet, IsLiveInCalleeCB))
1290 ReadChecked = true;
1291 }
1292 // If the instruction cannot be reach from the access, the latter does not
1293 // interfere with what the instruction reads.
1294 if (!WriteChecked) {
1295 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1296 &ExclusionSet, IsLiveInCalleeCB))
1297 WriteChecked = true;
1298 }
1299
1300 // If we still might be affected by the write of the access but there are
1301 // dominating writes in the function of the instruction
1302 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1303 // by them. This would have happend above if they are all in the same
1304 // function, so we only check the inter-procedural case. Effectively, we
1305 // want to show that there is no call after the dominting write that might
1306 // reach the access, and when it returns reach the instruction with the
1307 // updated value. To this end, we iterate all call sites, check if they
1308 // might reach the instruction without going through another access
1309 // (ExclusionSet) and at the same time might reach the access. However,
1310 // that is all part of AAInterFnReachability.
1311 if (!WriteChecked && HasBeenWrittenTo &&
1312 Acc.getRemoteInst()->getFunction() != &Scope) {
1313
1314 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1315 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1316 if (FnReachabilityAA) {
1317 // Without going backwards in the call tree, can we reach the access
1318 // from the least dominating write. Do not allow to pass the
1319 // instruction itself either.
1320 bool Inserted = ExclusionSet.insert(&I).second;
1321
1322 if (!FnReachabilityAA->instructionCanReach(
1323 A, *LeastDominatingWriteInst,
1324 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1325 WriteChecked = true;
1326
1327 if (Inserted)
1328 ExclusionSet.erase(&I);
1329 }
1330 }
1331
1332 if (ReadChecked && WriteChecked)
1333 return true;
1334
1335 if (!DT || !UseDominanceReasoning)
1336 return false;
1337 if (!DominatingWrites.count(&Acc))
1338 return false;
1339 return LeastDominatingWriteInst != Acc.getRemoteInst();
1340 };
1341
1342 // Run the user callback on all accesses we cannot skip and return if
1343 // that succeeded for all or not.
1344 for (auto &It : InterferingAccesses) {
1345 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1346 !CanSkipAccess(*It.first, It.second)) {
1347 if (!UserCB(*It.first, It.second))
1348 return false;
1349 }
1350 }
1351 return true;
1352 }
1353
1354 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1355 const AAPointerInfo &OtherAA,
1356 CallBase &CB) {
1357 using namespace AA::PointerInfo;
1358 if (!OtherAA.getState().isValidState() || !isValidState())
1359 return indicatePessimisticFixpoint();
1360
1361 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1362 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1363 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1364 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1365
1366 // Combine the accesses bin by bin.
1367 const auto &State = OtherAAImpl.getState();
1368 for (const auto &It : State) {
1369 for (auto Index : It.getSecond()) {
1370 const auto &RAcc = State.getAccess(Index);
1371 if (IsByval && !RAcc.isRead())
1372 continue;
1373 bool UsedAssumedInformation = false;
1374 AccessKind AK = RAcc.getKind();
1375 auto Content = A.translateArgumentToCallSiteContent(
1376 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1377 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1378 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1379
1380 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1381 RAcc.getType(), RAcc.getRemoteInst());
1382 }
1383 }
1384 return Changed;
1385 }
1386
1387 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1388 const OffsetInfo &Offsets, CallBase &CB,
1389 bool IsMustAcc) {
1390 using namespace AA::PointerInfo;
1391 if (!OtherAA.getState().isValidState() || !isValidState())
1392 return indicatePessimisticFixpoint();
1393
1394 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1395
1396 // Combine the accesses bin by bin.
1397 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1398 const auto &State = OtherAAImpl.getState();
1399 for (const auto &It : State) {
1400 for (auto Index : It.getSecond()) {
1401 const auto &RAcc = State.getAccess(Index);
1402 if (!IsMustAcc && RAcc.isAssumption())
1403 continue;
1404 for (auto Offset : Offsets) {
1405 auto NewRanges = Offset == AA::RangeTy::Unknown
1407 : RAcc.getRanges();
1408 if (!NewRanges.isUnknown()) {
1409 NewRanges.addToAllOffsets(Offset);
1410 }
1411 AccessKind AK = RAcc.getKind();
1412 if (!IsMustAcc)
1413 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1414 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1415 RAcc.getType(), RAcc.getRemoteInst());
1416 }
1417 }
1418 }
1419 return Changed;
1420 }
1421
1422 /// Statistic tracking for all AAPointerInfo implementations.
1423 /// See AbstractAttribute::trackStatistics().
1424 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1425
1426 /// Dump the state into \p O.
1427 void dumpState(raw_ostream &O) {
1428 for (auto &It : OffsetBins) {
1429 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1430 << "] : " << It.getSecond().size() << "\n";
1431 for (auto AccIndex : It.getSecond()) {
1432 auto &Acc = AccessList[AccIndex];
1433 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1434 if (Acc.getLocalInst() != Acc.getRemoteInst())
1435 O << " --> " << *Acc.getRemoteInst()
1436 << "\n";
1437 if (!Acc.isWrittenValueYetUndetermined()) {
1438 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1439 O << " - c: func " << Acc.getWrittenValue()->getName()
1440 << "\n";
1441 else if (Acc.getWrittenValue())
1442 O << " - c: " << *Acc.getWrittenValue() << "\n";
1443 else
1444 O << " - c: <unknown>\n";
1445 }
1446 }
1447 }
1448 }
1449};
1450
1451struct AAPointerInfoFloating : public AAPointerInfoImpl {
1453 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1454 : AAPointerInfoImpl(IRP, A) {}
1455
1456 /// Deal with an access and signal if it was handled successfully.
1457 bool handleAccess(Attributor &A, Instruction &I,
1458 std::optional<Value *> Content, AccessKind Kind,
1459 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1460 Type &Ty) {
1461 using namespace AA::PointerInfo;
1463 const DataLayout &DL = A.getDataLayout();
1464 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1465 if (!AccessSize.isScalable())
1466 Size = AccessSize.getFixedValue();
1467
1468 // Make a strictly ascending list of offsets as required by addAccess()
1469 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1470 llvm::sort(OffsetsSorted);
1471
1473 if (!VT || VT->getElementCount().isScalable() ||
1474 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1475 (*Content)->getType() != VT ||
1476 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1477 Changed =
1478 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1479 } else {
1480 // Handle vector stores with constant content element-wise.
1481 // TODO: We could look for the elements or create instructions
1482 // representing them.
1483 // TODO: We need to push the Content into the range abstraction
1484 // (AA::RangeTy) to allow different content values for different
1485 // ranges. ranges. Hence, support vectors storing different values.
1486 Type *ElementType = VT->getElementType();
1487 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1488 auto *ConstContent = cast<Constant>(*Content);
1489 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1490 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1491
1492 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1493 Value *ElementContent = ConstantExpr::getExtractElement(
1494 ConstContent, ConstantInt::get(Int32Ty, i));
1495
1496 // Add the element access.
1497 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1498 ElementContent, Kind, ElementType);
1499
1500 // Advance the offsets for the next element.
1501 for (auto &ElementOffset : ElementOffsets)
1502 ElementOffset += ElementSize;
1503 }
1504 }
1505 return true;
1506 };
1507
1508 /// See AbstractAttribute::updateImpl(...).
1509 ChangeStatus updateImpl(Attributor &A) override;
1510
1511 /// If the indices to \p GEP can be traced to constants, incorporate all
1512 /// of these into \p UsrOI.
1513 ///
1514 /// \return true iff \p UsrOI is updated.
1515 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1516 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1517 const GEPOperator *GEP);
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override {
1521 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1522 }
1523};
1524
1525bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1526 const DataLayout &DL,
1527 OffsetInfo &UsrOI,
1528 const OffsetInfo &PtrOI,
1529 const GEPOperator *GEP) {
1530 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1531 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1532 APInt ConstantOffset(BitWidth, 0);
1533
1534 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1535 "Don't look for constant values if the offset has already been "
1536 "determined to be unknown.");
1537
1538 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1539 UsrOI.setUnknown();
1540 return true;
1541 }
1542
1543 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1544 << (VariableOffsets.empty() ? "" : "not") << " constant "
1545 << *GEP << "\n");
1546
1547 auto Union = PtrOI;
1548 Union.addToAll(ConstantOffset.getSExtValue());
1549
1550 // Each VI in VariableOffsets has a set of potential constant values. Every
1551 // combination of elements, picked one each from these sets, is separately
1552 // added to the original set of offsets, thus resulting in more offsets.
1553 for (const auto &VI : VariableOffsets) {
1554 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1555 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1556 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1557 UsrOI.setUnknown();
1558 return true;
1559 }
1560
1561 // UndefValue is treated as a zero, which leaves Union as is.
1562 if (PotentialConstantsAA->undefIsContained())
1563 continue;
1564
1565 // We need at least one constant in every set to compute an actual offset.
1566 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1567 // don't actually exist. In other words, the absence of constant values
1568 // implies that the operation can be assumed dead for now.
1569 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1570 if (AssumedSet.empty())
1571 return false;
1572
1573 OffsetInfo Product;
1574 for (const auto &ConstOffset : AssumedSet) {
1575 auto CopyPerOffset = Union;
1576 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1577 VI.second.getZExtValue());
1578 Product.merge(CopyPerOffset);
1579 }
1580 Union = Product;
1581 }
1582
1583 UsrOI = std::move(Union);
1584 return true;
1585}
1586
1587ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1588 using namespace AA::PointerInfo;
1590 const DataLayout &DL = A.getDataLayout();
1591 Value &AssociatedValue = getAssociatedValue();
1592
1593 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1594 OffsetInfoMap[&AssociatedValue].insert(0);
1595
1596 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1597 // One does not simply walk into a map and assign a reference to a possibly
1598 // new location. That can cause an invalidation before the assignment
1599 // happens, like so:
1600 //
1601 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1602 //
1603 // The RHS is a reference that may be invalidated by an insertion caused by
1604 // the LHS. So we ensure that the side-effect of the LHS happens first.
1605
1606 assert(OffsetInfoMap.contains(CurPtr) &&
1607 "CurPtr does not exist in the map!");
1608
1609 auto &UsrOI = OffsetInfoMap[Usr];
1610 auto &PtrOI = OffsetInfoMap[CurPtr];
1611 assert(!PtrOI.isUnassigned() &&
1612 "Cannot pass through if the input Ptr was not visited!");
1613 UsrOI.merge(PtrOI);
1614 Follow = true;
1615 return true;
1616 };
1617
1618 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1619 Value *CurPtr = U.get();
1620 User *Usr = U.getUser();
1621 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1622 << "\n");
1623 assert(OffsetInfoMap.count(CurPtr) &&
1624 "The current pointer offset should have been seeded!");
1625 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1626 "Current pointer should be assigned");
1627
1628 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1629 if (CE->isCast())
1630 return HandlePassthroughUser(Usr, CurPtr, Follow);
1631 if (!isa<GEPOperator>(CE)) {
1632 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1633 << "\n");
1634 return false;
1635 }
1636 }
1637 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1638 // Note the order here, the Usr access might change the map, CurPtr is
1639 // already in it though.
1640 auto &UsrOI = OffsetInfoMap[Usr];
1641 auto &PtrOI = OffsetInfoMap[CurPtr];
1642
1643 if (UsrOI.isUnknown())
1644 return true;
1645
1646 if (PtrOI.isUnknown()) {
1647 Follow = true;
1648 UsrOI.setUnknown();
1649 return true;
1650 }
1651
1652 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1653 return true;
1654 }
1655 if (isa<PtrToIntInst>(Usr))
1656 return false;
1657 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1658 return HandlePassthroughUser(Usr, CurPtr, Follow);
1659 // Returns are allowed if they are in the associated functions. Users can
1660 // then check the call site return. Returns from other functions can't be
1661 // tracked and are cause for invalidation.
1662 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1663 if (RI->getFunction() == getAssociatedFunction()) {
1664 auto &PtrOI = OffsetInfoMap[CurPtr];
1665 Changed |= setReachesReturn(PtrOI);
1666 return true;
1667 }
1668 return false;
1669 }
1670
1671 // For PHIs we need to take care of the recurrence explicitly as the value
1672 // might change while we iterate through a loop. For now, we give up if
1673 // the PHI is not invariant.
1674 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1675 // Note the order here, the Usr access might change the map, CurPtr is
1676 // already in it though.
1677 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1678 auto &UsrOI = PhiIt->second;
1679 auto &PtrOI = OffsetInfoMap[CurPtr];
1680
1681 // Check if the PHI operand has already an unknown offset as we can't
1682 // improve on that anymore.
1683 if (PtrOI.isUnknown()) {
1684 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1685 << *CurPtr << " in " << *PHI << "\n");
1686 Follow = !UsrOI.isUnknown();
1687 UsrOI.setUnknown();
1688 return true;
1689 }
1690
1691 // Check if the PHI is invariant (so far).
1692 if (UsrOI == PtrOI) {
1693 assert(!PtrOI.isUnassigned() &&
1694 "Cannot assign if the current Ptr was not visited!");
1695 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1696 return true;
1697 }
1698
1699 // Check if the PHI operand can be traced back to AssociatedValue.
1700 APInt Offset(
1701 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1702 0);
1703 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1704 DL, Offset, /* AllowNonInbounds */ true);
1705 auto It = OffsetInfoMap.find(CurPtrBase);
1706 if (It == OffsetInfoMap.end()) {
1707 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1708 << *CurPtr << " in " << *PHI
1709 << " (base: " << *CurPtrBase << ")\n");
1710 UsrOI.setUnknown();
1711 Follow = true;
1712 return true;
1713 }
1714
1715 // Check if the PHI operand is not dependent on the PHI itself. Every
1716 // recurrence is a cyclic net of PHIs in the data flow, and has an
1717 // equivalent Cycle in the control flow. One of those PHIs must be in the
1718 // header of that control flow Cycle. This is independent of the choice of
1719 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1720 // every Cycle header; if such a node is marked unknown, this will
1721 // eventually propagate through the whole net of PHIs in the recurrence.
1722 const auto *CI =
1723 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1724 *PHI->getFunction());
1725 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1726 auto BaseOI = It->getSecond();
1727 BaseOI.addToAll(Offset.getZExtValue());
1728 if (IsFirstPHIUser || BaseOI == UsrOI) {
1729 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1730 << " in " << *Usr << "\n");
1731 return HandlePassthroughUser(Usr, CurPtr, Follow);
1732 }
1733
1734 LLVM_DEBUG(
1735 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1736 << *CurPtr << " in " << *PHI << "\n");
1737 UsrOI.setUnknown();
1738 Follow = true;
1739 return true;
1740 }
1741
1742 UsrOI.merge(PtrOI);
1743 Follow = true;
1744 return true;
1745 }
1746
1747 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1748 // If the access is to a pointer that may or may not be the associated
1749 // value, e.g. due to a PHI, we cannot assume it will be read.
1750 AccessKind AK = AccessKind::AK_R;
1751 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1752 AK = AccessKind(AK | AccessKind::AK_MUST);
1753 else
1754 AK = AccessKind(AK | AccessKind::AK_MAY);
1755 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1756 OffsetInfoMap[CurPtr].Offsets, Changed,
1757 *LoadI->getType()))
1758 return false;
1759
1760 auto IsAssumption = [](Instruction &I) {
1761 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1762 return II->isAssumeLikeIntrinsic();
1763 return false;
1764 };
1765
1766 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1767 // Check if the assumption and the load are executed together without
1768 // memory modification.
1769 do {
1770 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1771 return true;
1772 FromI = FromI->getNextNode();
1773 } while (FromI && FromI != ToI);
1774 return false;
1775 };
1776
1777 BasicBlock *BB = LoadI->getParent();
1778 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1779 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1780 return false;
1781 BasicBlock *IntrBB = IntrI.getParent();
1782 if (IntrI.getParent() == BB) {
1783 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1784 return false;
1785 } else {
1786 auto PredIt = pred_begin(IntrBB);
1787 if (PredIt == pred_end(IntrBB))
1788 return false;
1789 if ((*PredIt) != BB)
1790 return false;
1791 if (++PredIt != pred_end(IntrBB))
1792 return false;
1793 for (auto *SuccBB : successors(BB)) {
1794 if (SuccBB == IntrBB)
1795 continue;
1796 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1797 continue;
1798 return false;
1799 }
1800 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1801 return false;
1802 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1803 return false;
1804 }
1805 return true;
1806 };
1807
1808 std::pair<Value *, IntrinsicInst *> Assumption;
1809 for (const Use &LoadU : LoadI->uses()) {
1810 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1811 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1812 continue;
1813 for (const Use &CmpU : CmpI->uses()) {
1814 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1815 if (!IsValidAssume(*IntrI))
1816 continue;
1817 int Idx = CmpI->getOperandUse(0) == LoadU;
1818 Assumption = {CmpI->getOperand(Idx), IntrI};
1819 break;
1820 }
1821 }
1822 }
1823 if (Assumption.first)
1824 break;
1825 }
1826
1827 // Check if we found an assumption associated with this load.
1828 if (!Assumption.first || !Assumption.second)
1829 return true;
1830
1831 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1832 << *Assumption.second << ": " << *LoadI
1833 << " == " << *Assumption.first << "\n");
1834 bool UsedAssumedInformation = false;
1835 std::optional<Value *> Content = nullptr;
1836 if (Assumption.first)
1837 Content =
1838 A.getAssumedSimplified(*Assumption.first, *this,
1839 UsedAssumedInformation, AA::Interprocedural);
1840 return handleAccess(
1841 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1842 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1843 }
1844
1845 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1846 ArrayRef<Value *> OtherOps, AccessKind AK) {
1847 for (auto *OtherOp : OtherOps) {
1848 if (OtherOp == CurPtr) {
1849 LLVM_DEBUG(
1850 dbgs()
1851 << "[AAPointerInfo] Escaping use in store like instruction " << I
1852 << "\n");
1853 return false;
1854 }
1855 }
1856
1857 // If the access is to a pointer that may or may not be the associated
1858 // value, e.g. due to a PHI, we cannot assume it will be written.
1859 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1860 AK = AccessKind(AK | AccessKind::AK_MUST);
1861 else
1862 AK = AccessKind(AK | AccessKind::AK_MAY);
1863 bool UsedAssumedInformation = false;
1864 std::optional<Value *> Content = nullptr;
1865 if (ValueOp)
1866 Content = A.getAssumedSimplified(
1867 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1868 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1869 Changed, ValueTy);
1870 };
1871
1872 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1873 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1874 *StoreI->getValueOperand()->getType(),
1875 {StoreI->getValueOperand()}, AccessKind::AK_W);
1876 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1877 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1878 {RMWI->getValOperand()}, AccessKind::AK_RW);
1879 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1880 return HandleStoreLike(
1881 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1882 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1883 AccessKind::AK_RW);
1884
1885 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1886 if (CB->isLifetimeStartOrEnd())
1887 return true;
1888 const auto *TLI =
1889 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1890 if (getFreedOperand(CB, TLI) == U)
1891 return true;
1892 if (CB->isArgOperand(&U)) {
1893 unsigned ArgNo = CB->getArgOperandNo(&U);
1894 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1895 *this, IRPosition::callsite_argument(*CB, ArgNo),
1897 if (!CSArgPI)
1898 return false;
1899 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1900 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1901 IsArgMustAcc) |
1902 Changed;
1903 if (!CSArgPI->reachesReturn())
1904 return isValidState();
1905
1907 if (!Callee || Callee->arg_size() <= ArgNo)
1908 return false;
1909 bool UsedAssumedInformation = false;
1910 auto ReturnedValue = A.getAssumedSimplified(
1911 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1913 auto *ReturnedArg =
1914 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1915 auto *Arg = Callee->getArg(ArgNo);
1916 if (ReturnedArg && Arg != ReturnedArg)
1917 return true;
1918 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1919 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1921 if (!CSRetPI)
1922 return false;
1923 OffsetInfo OI = OffsetInfoMap[CurPtr];
1924 CSArgPI->addReturnedOffsetsTo(OI);
1925 Changed =
1926 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1927 return isValidState();
1928 }
1929 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1930 << "\n");
1931 return false;
1932 }
1933
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1935 return false;
1936 };
1937 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1938 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1939 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1940 if (OffsetInfoMap.count(NewU)) {
1941 LLVM_DEBUG({
1942 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1943 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1944 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1945 << "\n";
1946 }
1947 });
1948 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1949 }
1950 bool Unused;
1951 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1952 };
1953 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1954 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1955 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1956 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1957 return indicatePessimisticFixpoint();
1958 }
1959
1960 LLVM_DEBUG({
1961 dbgs() << "Accesses by bin after update:\n";
1962 dumpState(dbgs());
1963 });
1964
1965 return Changed;
1966}
1967
1968struct AAPointerInfoReturned final : AAPointerInfoImpl {
1969 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1970 : AAPointerInfoImpl(IRP, A) {}
1971
1972 /// See AbstractAttribute::updateImpl(...).
1973 ChangeStatus updateImpl(Attributor &A) override {
1974 return indicatePessimisticFixpoint();
1975 }
1976
1977 /// See AbstractAttribute::trackStatistics()
1978 void trackStatistics() const override {
1979 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1980 }
1981};
1982
1983struct AAPointerInfoArgument final : AAPointerInfoFloating {
1984 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1985 : AAPointerInfoFloating(IRP, A) {}
1986
1987 /// See AbstractAttribute::trackStatistics()
1988 void trackStatistics() const override {
1989 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1990 }
1991};
1992
1993struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1994 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1995 : AAPointerInfoFloating(IRP, A) {}
1996
1997 /// See AbstractAttribute::updateImpl(...).
1998 ChangeStatus updateImpl(Attributor &A) override {
1999 using namespace AA::PointerInfo;
2000 // We handle memory intrinsics explicitly, at least the first (=
2001 // destination) and second (=source) arguments as we know how they are
2002 // accessed.
2003 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2004 int64_t LengthVal = AA::RangeTy::Unknown;
2005 if (auto Length = MI->getLengthInBytes())
2006 LengthVal = Length->getSExtValue();
2007 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2008 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2009 if (ArgNo > 1) {
2010 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2011 << *MI << "\n");
2012 return indicatePessimisticFixpoint();
2013 } else {
2014 auto Kind =
2015 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2016 Changed =
2017 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2018 }
2019 LLVM_DEBUG({
2020 dbgs() << "Accesses by bin after update:\n";
2021 dumpState(dbgs());
2022 });
2023
2024 return Changed;
2025 }
2026
2027 // TODO: Once we have call site specific value information we can provide
2028 // call site specific liveness information and then it makes
2029 // sense to specialize attributes for call sites arguments instead of
2030 // redirecting requests to the callee argument.
2031 Argument *Arg = getAssociatedArgument();
2032 if (Arg) {
2033 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2034 auto *ArgAA =
2035 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2036 if (ArgAA && ArgAA->getState().isValidState())
2037 return translateAndAddStateFromCallee(A, *ArgAA,
2038 *cast<CallBase>(getCtxI()));
2039 if (!Arg->getParent()->isDeclaration())
2040 return indicatePessimisticFixpoint();
2041 }
2042
2043 bool IsKnownNoCapture;
2045 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2046 return indicatePessimisticFixpoint();
2047
2048 bool IsKnown = false;
2049 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2050 return ChangeStatus::UNCHANGED;
2051 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2052 auto Kind =
2053 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2054 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2055 nullptr);
2056 }
2057
2058 /// See AbstractAttribute::trackStatistics()
2059 void trackStatistics() const override {
2060 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2061 }
2062};
2063
2064struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2065 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2066 : AAPointerInfoFloating(IRP, A) {}
2067
2068 /// See AbstractAttribute::trackStatistics()
2069 void trackStatistics() const override {
2070 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2071 }
2072};
2073} // namespace
2074
2075/// -----------------------NoUnwind Function Attribute--------------------------
2076
2077namespace {
2078struct AANoUnwindImpl : AANoUnwind {
2079 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2080
2081 /// See AbstractAttribute::initialize(...).
2082 void initialize(Attributor &A) override {
2083 bool IsKnown;
2085 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2086 (void)IsKnown;
2087 }
2088
2089 const std::string getAsStr(Attributor *A) const override {
2090 return getAssumed() ? "nounwind" : "may-unwind";
2091 }
2092
2093 /// See AbstractAttribute::updateImpl(...).
2094 ChangeStatus updateImpl(Attributor &A) override {
2095 auto Opcodes = {
2096 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2097 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2098 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2099
2100 auto CheckForNoUnwind = [&](Instruction &I) {
2101 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2102 return true;
2103
2104 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2105 bool IsKnownNoUnwind;
2107 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2108 IsKnownNoUnwind);
2109 }
2110 return false;
2111 };
2112
2113 bool UsedAssumedInformation = false;
2114 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2115 UsedAssumedInformation))
2116 return indicatePessimisticFixpoint();
2117
2118 return ChangeStatus::UNCHANGED;
2119 }
2120};
2121
2122struct AANoUnwindFunction final : public AANoUnwindImpl {
2123 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2124 : AANoUnwindImpl(IRP, A) {}
2125
2126 /// See AbstractAttribute::trackStatistics()
2127 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2128};
2129
2130/// NoUnwind attribute deduction for a call sites.
2131struct AANoUnwindCallSite final
2132 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2133 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2134 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2135
2136 /// See AbstractAttribute::trackStatistics()
2137 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2138};
2139} // namespace
2140
2141/// ------------------------ NoSync Function Attribute -------------------------
2142
2143bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2144 switch (CB.getIntrinsicID()) {
2145 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2146 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2147 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2148 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2149 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2150 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2151 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2152 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2153 return true;
2154 case Intrinsic::amdgcn_s_barrier:
2155 if (ExecutedAligned)
2156 return true;
2157 break;
2158 default:
2159 break;
2160 }
2161 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2162}
2163
2165 if (!I->isAtomic())
2166 return false;
2167
2168 if (auto *FI = dyn_cast<FenceInst>(I))
2169 // All legal orderings for fence are stronger than monotonic.
2170 return FI->getSyncScopeID() != SyncScope::SingleThread;
2171 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2172 // Unordered is not a legal ordering for cmpxchg.
2173 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2174 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2175 }
2176
2177 AtomicOrdering Ordering;
2178 switch (I->getOpcode()) {
2179 case Instruction::AtomicRMW:
2180 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2181 break;
2182 case Instruction::Store:
2183 Ordering = cast<StoreInst>(I)->getOrdering();
2184 break;
2185 case Instruction::Load:
2186 Ordering = cast<LoadInst>(I)->getOrdering();
2187 break;
2188 default:
2190 "New atomic operations need to be known in the attributor.");
2191 }
2192
2193 return (Ordering != AtomicOrdering::Unordered &&
2194 Ordering != AtomicOrdering::Monotonic);
2195}
2196
2197namespace {
2198struct AANoSyncImpl : AANoSync {
2199 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2200
2201 /// See AbstractAttribute::initialize(...).
2202 void initialize(Attributor &A) override {
2203 bool IsKnown;
2204 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2205 DepClassTy::NONE, IsKnown));
2206 (void)IsKnown;
2207 }
2208
2209 const std::string getAsStr(Attributor *A) const override {
2210 return getAssumed() ? "nosync" : "may-sync";
2211 }
2212
2213 /// See AbstractAttribute::updateImpl(...).
2214 ChangeStatus updateImpl(Attributor &A) override;
2215};
2216
2217ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2218
2219 auto CheckRWInstForNoSync = [&](Instruction &I) {
2220 return AA::isNoSyncInst(A, I, *this);
2221 };
2222
2223 auto CheckForNoSync = [&](Instruction &I) {
2224 // At this point we handled all read/write effects and they are all
2225 // nosync, so they can be skipped.
2226 if (I.mayReadOrWriteMemory())
2227 return true;
2228
2229 bool IsKnown;
2230 CallBase &CB = cast<CallBase>(I);
2233 IsKnown))
2234 return true;
2235
2236 // non-convergent and readnone imply nosync.
2237 return !CB.isConvergent();
2238 };
2239
2240 bool UsedAssumedInformation = false;
2241 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2242 UsedAssumedInformation) ||
2243 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2244 UsedAssumedInformation))
2245 return indicatePessimisticFixpoint();
2246
2248}
2249
2250struct AANoSyncFunction final : public AANoSyncImpl {
2251 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2252 : AANoSyncImpl(IRP, A) {}
2253
2254 /// See AbstractAttribute::trackStatistics()
2255 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2256};
2257
2258/// NoSync attribute deduction for a call sites.
2259struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2260 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2261 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2262
2263 /// See AbstractAttribute::trackStatistics()
2264 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2265};
2266} // namespace
2267
2268/// ------------------------ No-Free Attributes ----------------------------
2269
2270namespace {
2271struct AANoFreeImpl : public AANoFree {
2272 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2273
2274 /// See AbstractAttribute::initialize(...).
2275 void initialize(Attributor &A) override {
2276 bool IsKnown;
2277 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2278 DepClassTy::NONE, IsKnown));
2279 (void)IsKnown;
2280 }
2281
2282 /// See AbstractAttribute::updateImpl(...).
2283 ChangeStatus updateImpl(Attributor &A) override {
2284 auto CheckForNoFree = [&](Instruction &I) {
2285 bool IsKnown;
2288 DepClassTy::REQUIRED, IsKnown);
2289 };
2290
2291 bool UsedAssumedInformation = false;
2292 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2293 UsedAssumedInformation))
2294 return indicatePessimisticFixpoint();
2295 return ChangeStatus::UNCHANGED;
2296 }
2297
2298 /// See AbstractAttribute::getAsStr().
2299 const std::string getAsStr(Attributor *A) const override {
2300 return getAssumed() ? "nofree" : "may-free";
2301 }
2302};
2303
2304struct AANoFreeFunction final : public AANoFreeImpl {
2305 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2306 : AANoFreeImpl(IRP, A) {}
2307
2308 /// See AbstractAttribute::trackStatistics()
2309 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2310};
2311
2312/// NoFree attribute deduction for a call sites.
2313struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2314 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2315 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2316
2317 /// See AbstractAttribute::trackStatistics()
2318 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2319};
2320
2321/// NoFree attribute for floating values.
2322struct AANoFreeFloating : AANoFreeImpl {
2323 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2324 : AANoFreeImpl(IRP, A) {}
2325
2326 /// See AbstractAttribute::trackStatistics()
2327 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2328
2329 /// See Abstract Attribute::updateImpl(...).
2330 ChangeStatus updateImpl(Attributor &A) override {
2331 const IRPosition &IRP = getIRPosition();
2332
2333 bool IsKnown;
2336 DepClassTy::OPTIONAL, IsKnown))
2337 return ChangeStatus::UNCHANGED;
2338
2339 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2340 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2341 Instruction *UserI = cast<Instruction>(U.getUser());
2342 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2343 if (CB->isBundleOperand(&U))
2344 return false;
2345 if (!CB->isArgOperand(&U))
2346 return true;
2347 unsigned ArgNo = CB->getArgOperandNo(&U);
2348
2349 bool IsKnown;
2351 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2352 DepClassTy::REQUIRED, IsKnown);
2353 }
2354
2355 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2356 isa<SelectInst>(UserI)) {
2357 Follow = true;
2358 return true;
2359 }
2360 if (isa<LoadInst>(UserI))
2361 return true;
2362
2363 if (isa<StoreInst>(UserI))
2364 return U.getOperandNo() == StoreInst::getPointerOperandIndex();
2365
2366 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2367 return true;
2368
2369 // Unknown user.
2370 return false;
2371 };
2372 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2373 return indicatePessimisticFixpoint();
2374
2375 return ChangeStatus::UNCHANGED;
2376 }
2377};
2378
2379/// NoFree attribute for a call site argument.
2380struct AANoFreeArgument final : AANoFreeFloating {
2381 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2382 : AANoFreeFloating(IRP, A) {}
2383
2384 /// See AbstractAttribute::trackStatistics()
2385 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2386};
2387
2388/// NoFree attribute for call site arguments.
2389struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2390 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2391 : AANoFreeFloating(IRP, A) {}
2392
2393 /// See AbstractAttribute::updateImpl(...).
2394 ChangeStatus updateImpl(Attributor &A) override {
2395 // TODO: Once we have call site specific value information we can provide
2396 // call site specific liveness information and then it makes
2397 // sense to specialize attributes for call sites arguments instead of
2398 // redirecting requests to the callee argument.
2399 Argument *Arg = getAssociatedArgument();
2400 if (!Arg)
2401 return indicatePessimisticFixpoint();
2402 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2403 bool IsKnown;
2405 DepClassTy::REQUIRED, IsKnown))
2406 return ChangeStatus::UNCHANGED;
2407 return indicatePessimisticFixpoint();
2408 }
2409
2410 /// See AbstractAttribute::trackStatistics()
2411 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2412};
2413
2414/// NoFree attribute for function return value.
2415struct AANoFreeReturned final : AANoFreeFloating {
2416 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2417 : AANoFreeFloating(IRP, A) {
2418 llvm_unreachable("NoFree is not applicable to function returns!");
2419 }
2420
2421 /// See AbstractAttribute::initialize(...).
2422 void initialize(Attributor &A) override {
2423 llvm_unreachable("NoFree is not applicable to function returns!");
2424 }
2425
2426 /// See AbstractAttribute::updateImpl(...).
2427 ChangeStatus updateImpl(Attributor &A) override {
2428 llvm_unreachable("NoFree is not applicable to function returns!");
2429 }
2430
2431 /// See AbstractAttribute::trackStatistics()
2432 void trackStatistics() const override {}
2433};
2434
2435/// NoFree attribute deduction for a call site return value.
2436struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2437 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2438 : AANoFreeFloating(IRP, A) {}
2439
2440 ChangeStatus manifest(Attributor &A) override {
2441 return ChangeStatus::UNCHANGED;
2442 }
2443 /// See AbstractAttribute::trackStatistics()
2444 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2445};
2446} // namespace
2447
2448/// ------------------------ NonNull Argument Attribute ------------------------
2449
2451 Attribute::AttrKind ImpliedAttributeKind,
2452 bool IgnoreSubsumingPositions) {
2454 AttrKinds.push_back(Attribute::NonNull);
2457 AttrKinds.push_back(Attribute::Dereferenceable);
2458 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2459 return true;
2460
2461 DominatorTree *DT = nullptr;
2462 AssumptionCache *AC = nullptr;
2463 InformationCache &InfoCache = A.getInfoCache();
2464 if (const Function *Fn = IRP.getAnchorScope()) {
2465 if (!Fn->isDeclaration()) {
2468 }
2469 }
2470
2472 if (IRP.getPositionKind() != IRP_RETURNED) {
2473 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2474 } else {
2475 bool UsedAssumedInformation = false;
2476 if (!A.checkForAllInstructions(
2477 [&](Instruction &I) {
2478 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2479 return true;
2480 },
2481 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2482 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2483 return false;
2484 }
2485
2486 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2487 return !isKnownNonZero(
2488 VAC.getValue(),
2489 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2490 }))
2491 return false;
2492
2493 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2494 Attribute::NonNull)});
2495 return true;
2496}
2497
2498namespace {
2499static int64_t getKnownNonNullAndDerefBytesForUse(
2500 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2501 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2502 TrackUse = false;
2503
2504 const Value *UseV = U->get();
2505 if (!UseV->getType()->isPointerTy())
2506 return 0;
2507
2508 // We need to follow common pointer manipulation uses to the accesses they
2509 // feed into. We can try to be smart to avoid looking through things we do not
2510 // like for now, e.g., non-inbounds GEPs.
2511 if (isa<CastInst>(I)) {
2512 TrackUse = true;
2513 return 0;
2514 }
2515
2517 TrackUse = true;
2518 return 0;
2519 }
2520
2521 Type *PtrTy = UseV->getType();
2522 const Function *F = I->getFunction();
2525 const DataLayout &DL = A.getInfoCache().getDL();
2526 if (const auto *CB = dyn_cast<CallBase>(I)) {
2527 if (CB->isBundleOperand(U)) {
2528 if (RetainedKnowledge RK = getKnowledgeFromUse(
2529 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2530 IsNonNull |=
2531 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2532 return RK.ArgValue;
2533 }
2534 return 0;
2535 }
2536
2537 if (CB->isCallee(U)) {
2538 IsNonNull |= !NullPointerIsDefined;
2539 return 0;
2540 }
2541
2542 unsigned ArgNo = CB->getArgOperandNo(U);
2543 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2544 // As long as we only use known information there is no need to track
2545 // dependences here.
2546 bool IsKnownNonNull;
2548 DepClassTy::NONE, IsKnownNonNull);
2549 IsNonNull |= IsKnownNonNull;
2550 auto *DerefAA =
2551 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2552 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2553 }
2554
2555 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2556 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2557 Loc->Size.isScalable() || I->isVolatile())
2558 return 0;
2559
2560 int64_t Offset;
2561 const Value *Base =
2562 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2563 if (Base && Base == &AssociatedValue) {
2564 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2565 IsNonNull |= !NullPointerIsDefined;
2566 return std::max(int64_t(0), DerefBytes);
2567 }
2568
2569 /// Corner case when an offset is 0.
2571 /*AllowNonInbounds*/ true);
2572 if (Base && Base == &AssociatedValue && Offset == 0) {
2573 int64_t DerefBytes = Loc->Size.getValue();
2574 IsNonNull |= !NullPointerIsDefined;
2575 return std::max(int64_t(0), DerefBytes);
2576 }
2577
2578 return 0;
2579}
2580
2581struct AANonNullImpl : AANonNull {
2582 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2583
2584 /// See AbstractAttribute::initialize(...).
2585 void initialize(Attributor &A) override {
2586 Value &V = *getAssociatedValue().stripPointerCasts();
2587 if (isa<ConstantPointerNull>(V)) {
2588 indicatePessimisticFixpoint();
2589 return;
2590 }
2591
2592 if (Instruction *CtxI = getCtxI())
2593 followUsesInMBEC(*this, A, getState(), *CtxI);
2594 }
2595
2596 /// See followUsesInMBEC
2597 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2598 AANonNull::StateType &State) {
2599 bool IsNonNull = false;
2600 bool TrackUse = false;
2601 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2602 IsNonNull, TrackUse);
2603 State.setKnown(IsNonNull);
2604 return TrackUse;
2605 }
2606
2607 /// See AbstractAttribute::getAsStr().
2608 const std::string getAsStr(Attributor *A) const override {
2609 return getAssumed() ? "nonnull" : "may-null";
2610 }
2611};
2612
2613/// NonNull attribute for a floating value.
2614struct AANonNullFloating : public AANonNullImpl {
2615 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2616 : AANonNullImpl(IRP, A) {}
2617
2618 /// See AbstractAttribute::updateImpl(...).
2619 ChangeStatus updateImpl(Attributor &A) override {
2620 auto CheckIRP = [&](const IRPosition &IRP) {
2621 bool IsKnownNonNull;
2623 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2624 };
2625
2626 bool Stripped;
2627 bool UsedAssumedInformation = false;
2628 Value *AssociatedValue = &getAssociatedValue();
2630 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2631 AA::AnyScope, UsedAssumedInformation))
2632 Stripped = false;
2633 else
2634 Stripped =
2635 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2636
2637 if (!Stripped) {
2638 bool IsKnown;
2639 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2640 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2641 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2642 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2643 IsKnown);
2644 }))
2645 return ChangeStatus::UNCHANGED;
2646 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2648 A, this, IRPosition::value(*Select->getFalseValue()),
2649 DepClassTy::OPTIONAL, IsKnown) &&
2651 A, this, IRPosition::value(*Select->getTrueValue()),
2652 DepClassTy::OPTIONAL, IsKnown))
2653 return ChangeStatus::UNCHANGED;
2654
2655 // If we haven't stripped anything we might still be able to use a
2656 // different AA, but only if the IRP changes. Effectively when we
2657 // interpret this not as a call site value but as a floating/argument
2658 // value.
2659 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2660 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2661 return indicatePessimisticFixpoint();
2662 return ChangeStatus::UNCHANGED;
2663 }
2664
2665 for (const auto &VAC : Values)
2666 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2667 return indicatePessimisticFixpoint();
2668
2669 return ChangeStatus::UNCHANGED;
2670 }
2671
2672 /// See AbstractAttribute::trackStatistics()
2673 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2674};
2675
2676/// NonNull attribute for function return value.
2677struct AANonNullReturned final
2678 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2679 false, AANonNull::IRAttributeKind, false> {
2680 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2681 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2682 false, Attribute::NonNull, false>(IRP, A) {
2683 }
2684
2685 /// See AbstractAttribute::getAsStr().
2686 const std::string getAsStr(Attributor *A) const override {
2687 return getAssumed() ? "nonnull" : "may-null";
2688 }
2689
2690 /// See AbstractAttribute::trackStatistics()
2691 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2692};
2693
2694/// NonNull attribute for function argument.
2695struct AANonNullArgument final
2696 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2697 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2698 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2699
2700 /// See AbstractAttribute::trackStatistics()
2701 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2702};
2703
2704struct AANonNullCallSiteArgument final : AANonNullFloating {
2705 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2706 : AANonNullFloating(IRP, A) {}
2707
2708 /// See AbstractAttribute::trackStatistics()
2709 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2710};
2711
2712/// NonNull attribute for a call site return position.
2713struct AANonNullCallSiteReturned final
2714 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2715 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2716 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2717
2718 /// See AbstractAttribute::trackStatistics()
2719 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2720};
2721} // namespace
2722
2723/// ------------------------ Must-Progress Attributes --------------------------
2724namespace {
2725struct AAMustProgressImpl : public AAMustProgress {
2726 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2727 : AAMustProgress(IRP, A) {}
2728
2729 /// See AbstractAttribute::initialize(...).
2730 void initialize(Attributor &A) override {
2731 bool IsKnown;
2733 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2734 (void)IsKnown;
2735 }
2736
2737 /// See AbstractAttribute::getAsStr()
2738 const std::string getAsStr(Attributor *A) const override {
2739 return getAssumed() ? "mustprogress" : "may-not-progress";
2740 }
2741};
2742
2743struct AAMustProgressFunction final : AAMustProgressImpl {
2744 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2745 : AAMustProgressImpl(IRP, A) {}
2746
2747 /// See AbstractAttribute::updateImpl(...).
2748 ChangeStatus updateImpl(Attributor &A) override {
2749 bool IsKnown;
2751 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2752 if (IsKnown)
2753 return indicateOptimisticFixpoint();
2754 return ChangeStatus::UNCHANGED;
2755 }
2756
2757 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2758 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2759 bool IsKnownMustProgress;
2761 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2762 /* IgnoreSubsumingPositions */ true);
2763 };
2764
2765 bool AllCallSitesKnown = true;
2766 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2767 /* RequireAllCallSites */ true,
2768 AllCallSitesKnown))
2769 return indicatePessimisticFixpoint();
2770
2771 return ChangeStatus::UNCHANGED;
2772 }
2773
2774 /// See AbstractAttribute::trackStatistics()
2775 void trackStatistics() const override {
2776 STATS_DECLTRACK_FN_ATTR(mustprogress)
2777 }
2778};
2779
2780/// MustProgress attribute deduction for a call sites.
2781struct AAMustProgressCallSite final : AAMustProgressImpl {
2782 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2783 : AAMustProgressImpl(IRP, A) {}
2784
2785 /// See AbstractAttribute::updateImpl(...).
2786 ChangeStatus updateImpl(Attributor &A) override {
2787 // TODO: Once we have call site specific value information we can provide
2788 // call site specific liveness information and then it makes
2789 // sense to specialize attributes for call sites arguments instead of
2790 // redirecting requests to the callee argument.
2791 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2792 bool IsKnownMustProgress;
2794 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2795 return indicatePessimisticFixpoint();
2796 return ChangeStatus::UNCHANGED;
2797 }
2798
2799 /// See AbstractAttribute::trackStatistics()
2800 void trackStatistics() const override {
2801 STATS_DECLTRACK_CS_ATTR(mustprogress);
2802 }
2803};
2804} // namespace
2805
2806/// ------------------------ No-Recurse Attributes ----------------------------
2807
2808namespace {
2809struct AANoRecurseImpl : public AANoRecurse {
2810 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2811
2812 /// See AbstractAttribute::initialize(...).
2813 void initialize(Attributor &A) override {
2814 bool IsKnown;
2816 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2817 (void)IsKnown;
2818 }
2819
2820 /// See AbstractAttribute::getAsStr()
2821 const std::string getAsStr(Attributor *A) const override {
2822 return getAssumed() ? "norecurse" : "may-recurse";
2823 }
2824};
2825
2826struct AANoRecurseFunction final : AANoRecurseImpl {
2827 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2828 : AANoRecurseImpl(IRP, A) {}
2829
2830 /// See AbstractAttribute::updateImpl(...).
2831 ChangeStatus updateImpl(Attributor &A) override {
2832
2833 // If all live call sites are known to be no-recurse, we are as well.
2834 auto CallSitePred = [&](AbstractCallSite ACS) {
2835 bool IsKnownNoRecurse;
2837 A, this,
2838 IRPosition::function(*ACS.getInstruction()->getFunction()),
2839 DepClassTy::NONE, IsKnownNoRecurse))
2840 return false;
2841 return IsKnownNoRecurse;
2842 };
2843 bool UsedAssumedInformation = false;
2844 if (A.checkForAllCallSites(CallSitePred, *this, true,
2845 UsedAssumedInformation)) {
2846 // If we know all call sites and all are known no-recurse, we are done.
2847 // If all known call sites, which might not be all that exist, are known
2848 // to be no-recurse, we are not done but we can continue to assume
2849 // no-recurse. If one of the call sites we have not visited will become
2850 // live, another update is triggered.
2851 if (!UsedAssumedInformation)
2852 indicateOptimisticFixpoint();
2853 return ChangeStatus::UNCHANGED;
2854 }
2855
2856 const AAInterFnReachability *EdgeReachability =
2857 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2858 DepClassTy::REQUIRED);
2859 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2860 return indicatePessimisticFixpoint();
2861 return ChangeStatus::UNCHANGED;
2862 }
2863
2864 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2865};
2866
2867/// NoRecurse attribute deduction for a call sites.
2868struct AANoRecurseCallSite final
2869 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2870 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2871 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2872
2873 /// See AbstractAttribute::trackStatistics()
2874 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2875};
2876} // namespace
2877
2878/// ------------------------ No-Convergent Attribute --------------------------
2879
2880namespace {
2881struct AANonConvergentImpl : public AANonConvergent {
2882 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2883 : AANonConvergent(IRP, A) {}
2884
2885 /// See AbstractAttribute::getAsStr()
2886 const std::string getAsStr(Attributor *A) const override {
2887 return getAssumed() ? "non-convergent" : "may-be-convergent";
2888 }
2889};
2890
2891struct AANonConvergentFunction final : AANonConvergentImpl {
2892 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2893 : AANonConvergentImpl(IRP, A) {}
2894
2895 /// See AbstractAttribute::updateImpl(...).
2896 ChangeStatus updateImpl(Attributor &A) override {
2897 // If all function calls are known to not be convergent, we are not
2898 // convergent.
2899 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2900 CallBase &CB = cast<CallBase>(Inst);
2902 if (!Callee || Callee->isIntrinsic()) {
2903 return false;
2904 }
2905 if (Callee->isDeclaration()) {
2906 return !Callee->hasFnAttribute(Attribute::Convergent);
2907 }
2908 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2909 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2910 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2911 };
2912
2913 bool UsedAssumedInformation = false;
2914 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2915 UsedAssumedInformation)) {
2916 return indicatePessimisticFixpoint();
2917 }
2918 return ChangeStatus::UNCHANGED;
2919 }
2920
2921 ChangeStatus manifest(Attributor &A) override {
2922 if (isKnownNotConvergent() &&
2923 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2924 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2925 return ChangeStatus::CHANGED;
2926 }
2927 return ChangeStatus::UNCHANGED;
2928 }
2929
2930 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2931};
2932} // namespace
2933
2934/// -------------------- Undefined-Behavior Attributes ------------------------
2935
2936namespace {
2937struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2938 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2939 : AAUndefinedBehavior(IRP, A) {}
2940
2941 /// See AbstractAttribute::updateImpl(...).
2942 // through a pointer (i.e. also branches etc.)
2943 ChangeStatus updateImpl(Attributor &A) override {
2944 const size_t UBPrevSize = KnownUBInsts.size();
2945 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2946
2947 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2948 // Volatile accesses on null are not necessarily UB.
2949 if (I.isVolatile())
2950 return true;
2951
2952 // Skip instructions that are already saved.
2953 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2954 return true;
2955
2956 // If we reach here, we know we have an instruction
2957 // that accesses memory through a pointer operand,
2958 // for which getPointerOperand() should give it to us.
2959 Value *PtrOp =
2960 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2961 assert(PtrOp &&
2962 "Expected pointer operand of memory accessing instruction");
2963
2964 // Either we stopped and the appropriate action was taken,
2965 // or we got back a simplified value to continue.
2966 std::optional<Value *> SimplifiedPtrOp =
2967 stopOnUndefOrAssumed(A, PtrOp, &I);
2968 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2969 return true;
2970 const Value *PtrOpVal = *SimplifiedPtrOp;
2971
2972 // A memory access through a pointer is considered UB
2973 // only if the pointer has constant null value.
2974 // TODO: Expand it to not only check constant values.
2975 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2976 AssumedNoUBInsts.insert(&I);
2977 return true;
2978 }
2979 const Type *PtrTy = PtrOpVal->getType();
2980
2981 // Because we only consider instructions inside functions,
2982 // assume that a parent function exists.
2983 const Function *F = I.getFunction();
2984
2985 // A memory access using constant null pointer is only considered UB
2986 // if null pointer is _not_ defined for the target platform.
2988 AssumedNoUBInsts.insert(&I);
2989 else
2990 KnownUBInsts.insert(&I);
2991 return true;
2992 };
2993
2994 auto InspectBrInstForUB = [&](Instruction &I) {
2995 // A conditional branch instruction is considered UB if it has `undef`
2996 // condition.
2997
2998 // Skip instructions that are already saved.
2999 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3000 return true;
3001
3002 // We know we have a branch instruction.
3003 auto *BrInst = cast<CondBrInst>(&I);
3004
3005 // Either we stopped and the appropriate action was taken,
3006 // or we got back a simplified value to continue.
3007 std::optional<Value *> SimplifiedCond =
3008 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3009 if (!SimplifiedCond || !*SimplifiedCond)
3010 return true;
3011 AssumedNoUBInsts.insert(&I);
3012 return true;
3013 };
3014
3015 auto InspectCallSiteForUB = [&](Instruction &I) {
3016 // Check whether a callsite always cause UB or not
3017
3018 // Skip instructions that are already saved.
3019 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3020 return true;
3021
3022 // Check nonnull and noundef argument attribute violation for each
3023 // callsite.
3024 CallBase &CB = cast<CallBase>(I);
3026 if (!Callee)
3027 return true;
3028 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3029 // If current argument is known to be simplified to null pointer and the
3030 // corresponding argument position is known to have nonnull attribute,
3031 // the argument is poison. Furthermore, if the argument is poison and
3032 // the position is known to have noundef attriubte, this callsite is
3033 // considered UB.
3034 if (idx >= Callee->arg_size())
3035 break;
3036 Value *ArgVal = CB.getArgOperand(idx);
3037 if (!ArgVal)
3038 continue;
3039 // Here, we handle three cases.
3040 // (1) Not having a value means it is dead. (we can replace the value
3041 // with undef)
3042 // (2) Simplified to undef. The argument violate noundef attriubte.
3043 // (3) Simplified to null pointer where known to be nonnull.
3044 // The argument is a poison value and violate noundef attribute.
3045 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3046 bool IsKnownNoUndef;
3048 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3049 if (!IsKnownNoUndef)
3050 continue;
3051 bool UsedAssumedInformation = false;
3052 std::optional<Value *> SimplifiedVal =
3053 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3054 UsedAssumedInformation, AA::Interprocedural);
3055 if (UsedAssumedInformation)
3056 continue;
3057 if (SimplifiedVal && !*SimplifiedVal)
3058 return true;
3059 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3060 KnownUBInsts.insert(&I);
3061 continue;
3062 }
3063 if (!ArgVal->getType()->isPointerTy() ||
3064 !isa<ConstantPointerNull>(**SimplifiedVal))
3065 continue;
3066 bool IsKnownNonNull;
3068 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3069 if (IsKnownNonNull)
3070 KnownUBInsts.insert(&I);
3071 }
3072 return true;
3073 };
3074
3075 auto InspectReturnInstForUB = [&](Instruction &I) {
3076 auto &RI = cast<ReturnInst>(I);
3077 // Either we stopped and the appropriate action was taken,
3078 // or we got back a simplified return value to continue.
3079 std::optional<Value *> SimplifiedRetValue =
3080 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3081 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3082 return true;
3083
3084 // Check if a return instruction always cause UB or not
3085 // Note: It is guaranteed that the returned position of the anchor
3086 // scope has noundef attribute when this is called.
3087 // We also ensure the return position is not "assumed dead"
3088 // because the returned value was then potentially simplified to
3089 // `undef` in AAReturnedValues without removing the `noundef`
3090 // attribute yet.
3091
3092 // When the returned position has noundef attriubte, UB occurs in the
3093 // following cases.
3094 // (1) Returned value is known to be undef.
3095 // (2) The value is known to be a null pointer and the returned
3096 // position has nonnull attribute (because the returned value is
3097 // poison).
3098 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3099 bool IsKnownNonNull;
3101 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3102 IsKnownNonNull);
3103 if (IsKnownNonNull)
3104 KnownUBInsts.insert(&I);
3105 }
3106
3107 return true;
3108 };
3109
3110 bool UsedAssumedInformation = false;
3111 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3112 {Instruction::Load, Instruction::Store,
3113 Instruction::AtomicCmpXchg,
3114 Instruction::AtomicRMW},
3115 UsedAssumedInformation,
3116 /* CheckBBLivenessOnly */ true);
3117 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3118 UsedAssumedInformation,
3119 /* CheckBBLivenessOnly */ true);
3120 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3121 UsedAssumedInformation);
3122
3123 // If the returned position of the anchor scope has noundef attriubte, check
3124 // all returned instructions.
3125 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3126 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3127 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3128 bool IsKnownNoUndef;
3130 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3131 if (IsKnownNoUndef)
3132 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3133 {Instruction::Ret}, UsedAssumedInformation,
3134 /* CheckBBLivenessOnly */ true);
3135 }
3136 }
3137
3138 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3139 UBPrevSize != KnownUBInsts.size())
3140 return ChangeStatus::CHANGED;
3141 return ChangeStatus::UNCHANGED;
3142 }
3143
3144 bool isKnownToCauseUB(Instruction *I) const override {
3145 return KnownUBInsts.count(I);
3146 }
3147
3148 bool isAssumedToCauseUB(Instruction *I) const override {
3149 // In simple words, if an instruction is not in the assumed to _not_
3150 // cause UB, then it is assumed UB (that includes those
3151 // in the KnownUBInsts set). The rest is boilerplate
3152 // is to ensure that it is one of the instructions we test
3153 // for UB.
3154
3155 switch (I->getOpcode()) {
3156 case Instruction::Load:
3157 case Instruction::Store:
3158 case Instruction::AtomicCmpXchg:
3159 case Instruction::AtomicRMW:
3160 case Instruction::CondBr:
3161 return !AssumedNoUBInsts.count(I);
3162 default:
3163 return false;
3164 }
3165 return false;
3166 }
3167
3168 ChangeStatus manifest(Attributor &A) override {
3169 if (KnownUBInsts.empty())
3170 return ChangeStatus::UNCHANGED;
3171 for (Instruction *I : KnownUBInsts)
3172 A.changeToUnreachableAfterManifest(I);
3173 return ChangeStatus::CHANGED;
3174 }
3175
3176 /// See AbstractAttribute::getAsStr()
3177 const std::string getAsStr(Attributor *A) const override {
3178 return getAssumed() ? "undefined-behavior" : "no-ub";
3179 }
3180
3181 /// Note: The correctness of this analysis depends on the fact that the
3182 /// following 2 sets will stop changing after some point.
3183 /// "Change" here means that their size changes.
3184 /// The size of each set is monotonically increasing
3185 /// (we only add items to them) and it is upper bounded by the number of
3186 /// instructions in the processed function (we can never save more
3187 /// elements in either set than this number). Hence, at some point,
3188 /// they will stop increasing.
3189 /// Consequently, at some point, both sets will have stopped
3190 /// changing, effectively making the analysis reach a fixpoint.
3191
3192 /// Note: These 2 sets are disjoint and an instruction can be considered
3193 /// one of 3 things:
3194 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3195 /// the KnownUBInsts set.
3196 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3197 /// has a reason to assume it).
3198 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3199 /// could not find a reason to assume or prove that it can cause UB,
3200 /// hence it assumes it doesn't. We have a set for these instructions
3201 /// so that we don't reprocess them in every update.
3202 /// Note however that instructions in this set may cause UB.
3203
3204protected:
3205 /// A set of all live instructions _known_ to cause UB.
3206 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3207
3208private:
3209 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3210 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3211
3212 // Should be called on updates in which if we're processing an instruction
3213 // \p I that depends on a value \p V, one of the following has to happen:
3214 // - If the value is assumed, then stop.
3215 // - If the value is known but undef, then consider it UB.
3216 // - Otherwise, do specific processing with the simplified value.
3217 // We return std::nullopt in the first 2 cases to signify that an appropriate
3218 // action was taken and the caller should stop.
3219 // Otherwise, we return the simplified value that the caller should
3220 // use for specific processing.
3221 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3222 Instruction *I) {
3223 bool UsedAssumedInformation = false;
3224 std::optional<Value *> SimplifiedV =
3225 A.getAssumedSimplified(IRPosition::value(*V), *this,
3226 UsedAssumedInformation, AA::Interprocedural);
3227 if (!UsedAssumedInformation) {
3228 // Don't depend on assumed values.
3229 if (!SimplifiedV) {
3230 // If it is known (which we tested above) but it doesn't have a value,
3231 // then we can assume `undef` and hence the instruction is UB.
3232 KnownUBInsts.insert(I);
3233 return std::nullopt;
3234 }
3235 if (!*SimplifiedV)
3236 return nullptr;
3237 V = *SimplifiedV;
3238 }
3239 if (isa<UndefValue>(V)) {
3240 KnownUBInsts.insert(I);
3241 return std::nullopt;
3242 }
3243 return V;
3244 }
3245};
3246
3247struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3248 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3249 : AAUndefinedBehaviorImpl(IRP, A) {}
3250
3251 /// See AbstractAttribute::trackStatistics()
3252 void trackStatistics() const override {
3253 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3254 "Number of instructions known to have UB");
3255 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3256 KnownUBInsts.size();
3257 }
3258};
3259} // namespace
3260
3261/// ------------------------ Will-Return Attributes ----------------------------
3262
3263namespace {
3264// Helper function that checks whether a function has any cycle which we don't
3265// know if it is bounded or not.
3266// Loops with maximum trip count are considered bounded, any other cycle not.
3267static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3268 ScalarEvolution *SE =
3269 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3270 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3271 // If either SCEV or LoopInfo is not available for the function then we assume
3272 // any cycle to be unbounded cycle.
3273 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3274 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3275 if (!SE || !LI) {
3276 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3277 if (SCCI.hasCycle())
3278 return true;
3279 return false;
3280 }
3281
3282 // If there's irreducible control, the function may contain non-loop cycles.
3284 return true;
3285
3286 // Any loop that does not have a max trip count is considered unbounded cycle.
3287 for (auto *L : LI->getLoopsInPreorder()) {
3288 if (!SE->getSmallConstantMaxTripCount(L))
3289 return true;
3290 }
3291 return false;
3292}
3293
3294struct AAWillReturnImpl : public AAWillReturn {
3295 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3296 : AAWillReturn(IRP, A) {}
3297
3298 /// See AbstractAttribute::initialize(...).
3299 void initialize(Attributor &A) override {
3300 bool IsKnown;
3302 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3303 (void)IsKnown;
3304 }
3305
3306 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3307 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3308 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3309 return false;
3310
3311 bool IsKnown;
3312 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3313 return IsKnown || !KnownOnly;
3314 return false;
3315 }
3316
3317 /// See AbstractAttribute::updateImpl(...).
3318 ChangeStatus updateImpl(Attributor &A) override {
3319 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3320 return ChangeStatus::UNCHANGED;
3321
3322 auto CheckForWillReturn = [&](Instruction &I) {
3324 bool IsKnown;
3326 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3327 if (IsKnown)
3328 return true;
3329 } else {
3330 return false;
3331 }
3332 bool IsKnownNoRecurse;
3334 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3335 };
3336
3337 bool UsedAssumedInformation = false;
3338 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3339 UsedAssumedInformation))
3340 return indicatePessimisticFixpoint();
3341
3342 auto CheckForVolatile = [&](Instruction &I) {
3343 // Volatile operations are not willreturn.
3344 return !I.isVolatile();
3345 };
3346 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3347 {Instruction::Load, Instruction::Store,
3348 Instruction::AtomicCmpXchg,
3349 Instruction::AtomicRMW},
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 if (!I->isTerminator() && !I->mayHaveSideEffects())
4152 return true;
4153
4154 auto *CB = dyn_cast<CallBase>(I);
4155 if (!CB || isa<IntrinsicInst>(CB))
4156 return false;
4157
4158 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4159
4160 bool IsKnownNoUnwind;
4162 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4163 return false;
4164
4165 bool IsKnown;
4166 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4167 }
4168};
4169
4170struct AAIsDeadFloating : public AAIsDeadValueImpl {
4171 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4172 : AAIsDeadValueImpl(IRP, A) {}
4173
4174 /// See AbstractAttribute::initialize(...).
4175 void initialize(Attributor &A) override {
4176 AAIsDeadValueImpl::initialize(A);
4177
4178 if (isa<UndefValue>(getAssociatedValue())) {
4179 indicatePessimisticFixpoint();
4180 return;
4181 }
4182
4183 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4184 if (!isAssumedSideEffectFree(A, I)) {
4186 indicatePessimisticFixpoint();
4187 else
4188 removeAssumedBits(HAS_NO_EFFECT);
4189 }
4190 }
4191
4192 bool isDeadFence(Attributor &A, FenceInst &FI) {
4193 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4194 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4195 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4196 return false;
4197 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4198 return true;
4199 }
4200
4201 bool isDeadStore(Attributor &A, StoreInst &SI,
4202 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4203 // Lang ref now states volatile store is not UB/dead, let's skip them.
4204 if (SI.isVolatile())
4205 return false;
4206
4207 // If we are collecting assumes to be deleted we are in the manifest stage.
4208 // It's problematic to collect the potential copies again now so we use the
4209 // cached ones.
4210 bool UsedAssumedInformation = false;
4211 if (!AssumeOnlyInst) {
4212 PotentialCopies.clear();
4213 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4214 UsedAssumedInformation)) {
4215 LLVM_DEBUG(
4216 dbgs()
4217 << "[AAIsDead] Could not determine potential copies of store!\n");
4218 return false;
4219 }
4220 }
4221 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4222 << " potential copies.\n");
4223
4224 InformationCache &InfoCache = A.getInfoCache();
4225 return llvm::all_of(PotentialCopies, [&](Value *V) {
4226 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4227 UsedAssumedInformation))
4228 return true;
4229 if (auto *LI = dyn_cast<LoadInst>(V)) {
4230 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4231 auto &UserI = cast<Instruction>(*U.getUser());
4232 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4233 if (AssumeOnlyInst)
4234 AssumeOnlyInst->insert(&UserI);
4235 return true;
4236 }
4237 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4238 })) {
4239 return true;
4240 }
4241 }
4242 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4243 << " is assumed live!\n");
4244 return false;
4245 });
4246 }
4247
4248 /// See AbstractAttribute::getAsStr().
4249 const std::string getAsStr(Attributor *A) const override {
4250 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4252 if (isValidState())
4253 return "assumed-dead-store";
4255 if (isValidState())
4256 return "assumed-dead-fence";
4257 return AAIsDeadValueImpl::getAsStr(A);
4258 }
4259
4260 /// See AbstractAttribute::updateImpl(...).
4261 ChangeStatus updateImpl(Attributor &A) override {
4262 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4263 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4264 if (!isDeadStore(A, *SI))
4265 return indicatePessimisticFixpoint();
4266 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4267 if (!isDeadFence(A, *FI))
4268 return indicatePessimisticFixpoint();
4269 } else {
4270 if (!isAssumedSideEffectFree(A, I))
4271 return indicatePessimisticFixpoint();
4272 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4273 return indicatePessimisticFixpoint();
4274 }
4276 }
4277
4278 bool isRemovableStore() const override {
4279 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4280 }
4281
4282 /// See AbstractAttribute::manifest(...).
4283 ChangeStatus manifest(Attributor &A) override {
4284 Value &V = getAssociatedValue();
4285 if (auto *I = dyn_cast<Instruction>(&V)) {
4286 // If we get here we basically know the users are all dead. We check if
4287 // isAssumedSideEffectFree returns true here again because it might not be
4288 // the case and only the users are dead but the instruction (=call) is
4289 // still needed.
4290 if (auto *SI = dyn_cast<StoreInst>(I)) {
4291 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4292 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4293 (void)IsDead;
4294 assert(IsDead && "Store was assumed to be dead!");
4295 A.deleteAfterManifest(*I);
4296 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4297 Instruction *AOI = AssumeOnlyInst[i];
4298 for (auto *Usr : AOI->users())
4299 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4300 A.deleteAfterManifest(*AOI);
4301 }
4302 return ChangeStatus::CHANGED;
4303 }
4304 if (auto *FI = dyn_cast<FenceInst>(I)) {
4305 assert(isDeadFence(A, *FI));
4306 A.deleteAfterManifest(*FI);
4307 return ChangeStatus::CHANGED;
4308 }
4309 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4310 A.deleteAfterManifest(*I);
4311 return ChangeStatus::CHANGED;
4312 }
4313 }
4315 }
4316
4317 /// See AbstractAttribute::trackStatistics()
4318 void trackStatistics() const override {
4320 }
4321
4322private:
4323 // The potential copies of a dead store, used for deletion during manifest.
4324 SmallSetVector<Value *, 4> PotentialCopies;
4325};
4326
4327struct AAIsDeadArgument : public AAIsDeadFloating {
4328 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4329 : AAIsDeadFloating(IRP, A) {}
4330
4331 /// See AbstractAttribute::manifest(...).
4332 ChangeStatus manifest(Attributor &A) override {
4333 Argument &Arg = *getAssociatedArgument();
4334 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4335 if (A.registerFunctionSignatureRewrite(
4336 Arg, /* ReplacementTypes */ {},
4339 return ChangeStatus::CHANGED;
4340 }
4341 return ChangeStatus::UNCHANGED;
4342 }
4343
4344 /// See AbstractAttribute::trackStatistics()
4345 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4346};
4347
4348struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4349 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4350 : AAIsDeadValueImpl(IRP, A) {}
4351
4352 /// See AbstractAttribute::initialize(...).
4353 void initialize(Attributor &A) override {
4354 AAIsDeadValueImpl::initialize(A);
4355 if (isa<UndefValue>(getAssociatedValue()))
4356 indicatePessimisticFixpoint();
4357 }
4358
4359 /// See AbstractAttribute::updateImpl(...).
4360 ChangeStatus updateImpl(Attributor &A) override {
4361 // TODO: Once we have call site specific value information we can provide
4362 // call site specific liveness information and then it makes
4363 // sense to specialize attributes for call sites arguments instead of
4364 // redirecting requests to the callee argument.
4365 Argument *Arg = getAssociatedArgument();
4366 if (!Arg)
4367 return indicatePessimisticFixpoint();
4368 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4369 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4370 if (!ArgAA)
4371 return indicatePessimisticFixpoint();
4372 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4373 }
4374
4375 /// See AbstractAttribute::manifest(...).
4376 ChangeStatus manifest(Attributor &A) override {
4377 CallBase &CB = cast<CallBase>(getAnchorValue());
4378 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4379 assert(!isa<UndefValue>(U.get()) &&
4380 "Expected undef values to be filtered out!");
4381 UndefValue &UV = *UndefValue::get(U->getType());
4382 if (A.changeUseAfterManifest(U, UV))
4383 return ChangeStatus::CHANGED;
4384 return ChangeStatus::UNCHANGED;
4385 }
4386
4387 /// See AbstractAttribute::trackStatistics()
4388 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4389};
4390
4391struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4392 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4393 : AAIsDeadFloating(IRP, A) {}
4394
4395 /// See AAIsDead::isAssumedDead().
4396 bool isAssumedDead() const override {
4397 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4398 }
4399
4400 /// See AbstractAttribute::initialize(...).
4401 void initialize(Attributor &A) override {
4402 AAIsDeadFloating::initialize(A);
4403 if (isa<UndefValue>(getAssociatedValue())) {
4404 indicatePessimisticFixpoint();
4405 return;
4406 }
4407
4408 // We track this separately as a secondary state.
4409 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4410 }
4411
4412 /// See AbstractAttribute::updateImpl(...).
4413 ChangeStatus updateImpl(Attributor &A) override {
4414 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4415 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4416 IsAssumedSideEffectFree = false;
4417 Changed = ChangeStatus::CHANGED;
4418 }
4419 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4420 return indicatePessimisticFixpoint();
4421 return Changed;
4422 }
4423
4424 /// See AbstractAttribute::trackStatistics()
4425 void trackStatistics() const override {
4426 if (IsAssumedSideEffectFree)
4428 else
4429 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4430 }
4431
4432 /// See AbstractAttribute::getAsStr().
4433 const std::string getAsStr(Attributor *A) const override {
4434 return isAssumedDead()
4435 ? "assumed-dead"
4436 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4437 }
4438
4439private:
4440 bool IsAssumedSideEffectFree = true;
4441};
4442
4443struct AAIsDeadReturned : public AAIsDeadValueImpl {
4444 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4445 : AAIsDeadValueImpl(IRP, A) {}
4446
4447 /// See AbstractAttribute::updateImpl(...).
4448 ChangeStatus updateImpl(Attributor &A) override {
4449
4450 bool UsedAssumedInformation = false;
4451 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4452 {Instruction::Ret}, UsedAssumedInformation);
4453
4454 auto PredForCallSite = [&](AbstractCallSite ACS) {
4455 if (ACS.isCallbackCall() || !ACS.getInstruction())
4456 return false;
4457 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4458 };
4459
4460 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4461 UsedAssumedInformation))
4462 return indicatePessimisticFixpoint();
4463
4464 return ChangeStatus::UNCHANGED;
4465 }
4466
4467 /// See AbstractAttribute::manifest(...).
4468 ChangeStatus manifest(Attributor &A) override {
4469 // TODO: Rewrite the signature to return void?
4470 bool AnyChange = false;
4471 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4472 auto RetInstPred = [&](Instruction &I) {
4473 ReturnInst &RI = cast<ReturnInst>(I);
4475 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4476 return true;
4477 };
4478 bool UsedAssumedInformation = false;
4479 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4480 UsedAssumedInformation);
4481 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4482 }
4483
4484 /// See AbstractAttribute::trackStatistics()
4485 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4486};
4487
4488struct AAIsDeadFunction : public AAIsDead {
4489 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4490
4491 /// See AbstractAttribute::initialize(...).
4492 void initialize(Attributor &A) override {
4493 Function *F = getAnchorScope();
4494 assert(F && "Did expect an anchor function");
4495 if (!isAssumedDeadInternalFunction(A)) {
4496 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4497 assumeLive(A, F->getEntryBlock());
4498 }
4499 }
4500
4501 bool isAssumedDeadInternalFunction(Attributor &A) {
4502 if (!getAnchorScope()->hasLocalLinkage())
4503 return false;
4504 bool UsedAssumedInformation = false;
4505 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4506 true, UsedAssumedInformation);
4507 }
4508
4509 /// See AbstractAttribute::getAsStr().
4510 const std::string getAsStr(Attributor *A) const override {
4511 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4512 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4513 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4514 std::to_string(KnownDeadEnds.size()) + "]";
4515 }
4516
4517 /// See AbstractAttribute::manifest(...).
4518 ChangeStatus manifest(Attributor &A) override {
4519 assert(getState().isValidState() &&
4520 "Attempted to manifest an invalid state!");
4521
4522 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4523 Function &F = *getAnchorScope();
4524
4525 if (AssumedLiveBlocks.empty()) {
4526 A.deleteAfterManifest(F);
4527 return ChangeStatus::CHANGED;
4528 }
4529
4530 // Flag to determine if we can change an invoke to a call assuming the
4531 // callee is nounwind. This is not possible if the personality of the
4532 // function allows to catch asynchronous exceptions.
4533 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4534
4535 KnownDeadEnds.set_union(ToBeExploredFrom);
4536 for (const Instruction *DeadEndI : KnownDeadEnds) {
4537 auto *CB = dyn_cast<CallBase>(DeadEndI);
4538 if (!CB)
4539 continue;
4540 bool IsKnownNoReturn;
4542 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4543 IsKnownNoReturn);
4544 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4545 continue;
4546
4547 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4548 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4549 else
4550 A.changeToUnreachableAfterManifest(
4551 const_cast<Instruction *>(DeadEndI->getNextNode()));
4552 HasChanged = ChangeStatus::CHANGED;
4553 }
4554
4555 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4556 for (BasicBlock &BB : F)
4557 if (!AssumedLiveBlocks.count(&BB)) {
4558 A.deleteAfterManifest(BB);
4559 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4560 HasChanged = ChangeStatus::CHANGED;
4561 }
4562
4563 return HasChanged;
4564 }
4565
4566 /// See AbstractAttribute::updateImpl(...).
4567 ChangeStatus updateImpl(Attributor &A) override;
4568
4569 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4570 assert(From->getParent() == getAnchorScope() &&
4571 To->getParent() == getAnchorScope() &&
4572 "Used AAIsDead of the wrong function");
4573 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4574 }
4575
4576 /// See AbstractAttribute::trackStatistics()
4577 void trackStatistics() const override {}
4578
4579 /// Returns true if the function is assumed dead.
4580 bool isAssumedDead() const override { return false; }
4581
4582 /// See AAIsDead::isKnownDead().
4583 bool isKnownDead() const override { return false; }
4584
4585 /// See AAIsDead::isAssumedDead(BasicBlock *).
4586 bool isAssumedDead(const BasicBlock *BB) const override {
4587 assert(BB->getParent() == getAnchorScope() &&
4588 "BB must be in the same anchor scope function.");
4589
4590 if (!getAssumed())
4591 return false;
4592 return !AssumedLiveBlocks.count(BB);
4593 }
4594
4595 /// See AAIsDead::isKnownDead(BasicBlock *).
4596 bool isKnownDead(const BasicBlock *BB) const override {
4597 return getKnown() && isAssumedDead(BB);
4598 }
4599
4600 /// See AAIsDead::isAssumed(Instruction *I).
4601 bool isAssumedDead(const Instruction *I) const override {
4602 assert(I->getParent()->getParent() == getAnchorScope() &&
4603 "Instruction must be in the same anchor scope function.");
4604
4605 if (!getAssumed())
4606 return false;
4607
4608 // If it is not in AssumedLiveBlocks then it for sure dead.
4609 // Otherwise, it can still be after noreturn call in a live block.
4610 if (!AssumedLiveBlocks.count(I->getParent()))
4611 return true;
4612
4613 // If it is not after a liveness barrier it is live.
4614 const Instruction *PrevI = I->getPrevNode();
4615 while (PrevI) {
4616 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4617 return true;
4618 PrevI = PrevI->getPrevNode();
4619 }
4620 return false;
4621 }
4622
4623 /// See AAIsDead::isKnownDead(Instruction *I).
4624 bool isKnownDead(const Instruction *I) const override {
4625 return getKnown() && isAssumedDead(I);
4626 }
4627
4628 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4629 /// that internal function called from \p BB should now be looked at.
4630 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4631 if (!AssumedLiveBlocks.insert(&BB).second)
4632 return false;
4633
4634 // We assume that all of BB is (probably) live now and if there are calls to
4635 // internal functions we will assume that those are now live as well. This
4636 // is a performance optimization for blocks with calls to a lot of internal
4637 // functions. It can however cause dead functions to be treated as live.
4638 for (const Instruction &I : BB)
4639 if (const auto *CB = dyn_cast<CallBase>(&I))
4641 if (F->hasLocalLinkage())
4642 A.markLiveInternalFunction(*F);
4643 return true;
4644 }
4645
4646 /// Collection of instructions that need to be explored again, e.g., we
4647 /// did assume they do not transfer control to (one of their) successors.
4648 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4649
4650 /// Collection of instructions that are known to not transfer control.
4651 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4652
4653 /// Collection of all assumed live edges
4654 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4655
4656 /// Collection of all assumed live BasicBlocks.
4657 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4658};
4659
4660static bool
4661identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4662 AbstractAttribute &AA,
4663 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4664 const IRPosition &IPos = IRPosition::callsite_function(CB);
4665
4666 bool IsKnownNoReturn;
4668 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4669 return !IsKnownNoReturn;
4670 if (CB.isTerminator())
4671 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4672 else
4673 AliveSuccessors.push_back(CB.getNextNode());
4674 return false;
4675}
4676
4677static bool
4678identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4679 AbstractAttribute &AA,
4680 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4681 bool UsedAssumedInformation =
4682 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4683
4684 // First, determine if we can change an invoke to a call assuming the
4685 // callee is nounwind. This is not possible if the personality of the
4686 // function allows to catch asynchronous exceptions.
4687 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4688 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4689 } else {
4690 const IRPosition &IPos = IRPosition::callsite_function(II);
4691
4692 bool IsKnownNoUnwind;
4694 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4695 UsedAssumedInformation |= !IsKnownNoUnwind;
4696 } else {
4697 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4698 }
4699 }
4700 return UsedAssumedInformation;
4701}
4702
4703static bool
4704identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4705 AbstractAttribute &,
4706 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4707 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4708 return false;
4709}
4710
4711static bool
4712identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4713 AbstractAttribute &AA,
4714 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4715 bool UsedAssumedInformation = false;
4716 std::optional<Constant *> C =
4717 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4718 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4719 // No value yet, assume both edges are dead.
4720 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4721 const BasicBlock *SuccBB =
4722 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4723 AliveSuccessors.push_back(&SuccBB->front());
4724 } else {
4725 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4726 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4727 UsedAssumedInformation = false;
4728 }
4729 return UsedAssumedInformation;
4730}
4731
4732static bool
4733identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4734 AbstractAttribute &AA,
4735 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4736 bool UsedAssumedInformation = false;
4738 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4739 Values, AA::AnyScope,
4740 UsedAssumedInformation)) {
4741 // Something went wrong, assume all successors are live.
4742 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4743 AliveSuccessors.push_back(&SuccBB->front());
4744 return false;
4745 }
4746
4747 if (Values.empty() ||
4748 (Values.size() == 1 &&
4749 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4750 // No valid value yet, assume all edges are dead.
4751 return UsedAssumedInformation;
4752 }
4753
4754 Type &Ty = *SI.getCondition()->getType();
4755 SmallPtrSet<ConstantInt *, 8> Constants;
4756 auto CheckForConstantInt = [&](Value *V) {
4757 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4758 Constants.insert(CI);
4759 return true;
4760 }
4761 return false;
4762 };
4763
4764 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4765 return CheckForConstantInt(VAC.getValue());
4766 })) {
4767 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4768 AliveSuccessors.push_back(&SuccBB->front());
4769 return UsedAssumedInformation;
4770 }
4771
4772 unsigned MatchedCases = 0;
4773 for (const auto &CaseIt : SI.cases()) {
4774 if (Constants.count(CaseIt.getCaseValue())) {
4775 ++MatchedCases;
4776 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4777 }
4778 }
4779
4780 // If all potential values have been matched, we will not visit the default
4781 // case.
4782 if (MatchedCases < Constants.size())
4783 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4784 return UsedAssumedInformation;
4785}
4786
4787ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4789
4790 if (AssumedLiveBlocks.empty()) {
4791 if (isAssumedDeadInternalFunction(A))
4793
4794 Function *F = getAnchorScope();
4795 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4796 assumeLive(A, F->getEntryBlock());
4797 Change = ChangeStatus::CHANGED;
4798 }
4799
4800 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4801 << getAnchorScope()->size() << "] BBs and "
4802 << ToBeExploredFrom.size() << " exploration points and "
4803 << KnownDeadEnds.size() << " known dead ends\n");
4804
4805 // Copy and clear the list of instructions we need to explore from. It is
4806 // refilled with instructions the next update has to look at.
4807 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4808 ToBeExploredFrom.end());
4809 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4810
4812 while (!Worklist.empty()) {
4813 const Instruction *I = Worklist.pop_back_val();
4814 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4815
4816 // Fast forward for uninteresting instructions. We could look for UB here
4817 // though.
4818 while (!I->isTerminator() && !isa<CallBase>(I))
4819 I = I->getNextNode();
4820
4821 AliveSuccessors.clear();
4822
4823 bool UsedAssumedInformation = false;
4824 switch (I->getOpcode()) {
4825 // TODO: look for (assumed) UB to backwards propagate "deadness".
4826 default:
4827 assert(I->isTerminator() &&
4828 "Expected non-terminators to be handled already!");
4829 for (const BasicBlock *SuccBB : successors(I->getParent()))
4830 AliveSuccessors.push_back(&SuccBB->front());
4831 break;
4832 case Instruction::Call:
4833 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4834 *this, AliveSuccessors);
4835 break;
4836 case Instruction::Invoke:
4837 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4838 *this, AliveSuccessors);
4839 break;
4840 case Instruction::UncondBr:
4841 UsedAssumedInformation = identifyAliveSuccessors(
4842 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4843 break;
4844 case Instruction::CondBr:
4845 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4846 *this, AliveSuccessors);
4847 break;
4848 case Instruction::Switch:
4849 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4850 *this, AliveSuccessors);
4851 break;
4852 }
4853
4854 if (UsedAssumedInformation) {
4855 NewToBeExploredFrom.insert(I);
4856 } else if (AliveSuccessors.empty() ||
4857 (I->isTerminator() &&
4858 AliveSuccessors.size() < I->getNumSuccessors())) {
4859 if (KnownDeadEnds.insert(I))
4860 Change = ChangeStatus::CHANGED;
4861 }
4862
4863 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4864 << AliveSuccessors.size() << " UsedAssumedInformation: "
4865 << UsedAssumedInformation << "\n");
4866
4867 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4868 if (!I->isTerminator()) {
4869 assert(AliveSuccessors.size() == 1 &&
4870 "Non-terminator expected to have a single successor!");
4871 Worklist.push_back(AliveSuccessor);
4872 } else {
4873 // record the assumed live edge
4874 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4875 if (AssumedLiveEdges.insert(Edge).second)
4876 Change = ChangeStatus::CHANGED;
4877 if (assumeLive(A, *AliveSuccessor->getParent()))
4878 Worklist.push_back(AliveSuccessor);
4879 }
4880 }
4881 }
4882
4883 // Check if the content of ToBeExploredFrom changed, ignore the order.
4884 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4885 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4886 return !ToBeExploredFrom.count(I);
4887 })) {
4888 Change = ChangeStatus::CHANGED;
4889 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4890 }
4891
4892 // If we know everything is live there is no need to query for liveness.
4893 // Instead, indicating a pessimistic fixpoint will cause the state to be
4894 // "invalid" and all queries to be answered conservatively without lookups.
4895 // To be in this state we have to (1) finished the exploration and (3) not
4896 // discovered any non-trivial dead end and (2) not ruled unreachable code
4897 // dead.
4898 if (ToBeExploredFrom.empty() &&
4899 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4900 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4901 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4902 }))
4903 return indicatePessimisticFixpoint();
4904 return Change;
4905}
4906
4907/// Liveness information for a call sites.
4908struct AAIsDeadCallSite final : AAIsDeadFunction {
4909 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4910 : AAIsDeadFunction(IRP, A) {}
4911
4912 /// See AbstractAttribute::initialize(...).
4913 void initialize(Attributor &A) override {
4914 // TODO: Once we have call site specific value information we can provide
4915 // call site specific liveness information and then it makes
4916 // sense to specialize attributes for call sites instead of
4917 // redirecting requests to the callee.
4918 llvm_unreachable("Abstract attributes for liveness are not "
4919 "supported for call sites yet!");
4920 }
4921
4922 /// See AbstractAttribute::updateImpl(...).
4923 ChangeStatus updateImpl(Attributor &A) override {
4924 return indicatePessimisticFixpoint();
4925 }
4926
4927 /// See AbstractAttribute::trackStatistics()
4928 void trackStatistics() const override {}
4929};
4930} // namespace
4931
4932/// -------------------- Dereferenceable Argument Attribute --------------------
4933
4934namespace {
4935struct AADereferenceableImpl : AADereferenceable {
4936 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4937 : AADereferenceable(IRP, A) {}
4938 using StateType = DerefState;
4939
4940 /// See AbstractAttribute::initialize(...).
4941 void initialize(Attributor &A) override {
4942 Value &V = *getAssociatedValue().stripPointerCasts();
4944 A.getAttrs(getIRPosition(),
4945 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4946 Attrs, /* IgnoreSubsumingPositions */ false);
4947 for (const Attribute &Attr : Attrs)
4948 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4949
4950 // Ensure we initialize the non-null AA (if necessary).
4951 bool IsKnownNonNull;
4953 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4954
4955 bool CanBeNull, CanBeFreed;
4956 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4957 A.getDataLayout(), CanBeNull, CanBeFreed));
4958
4959 if (Instruction *CtxI = getCtxI())
4960 followUsesInMBEC(*this, A, getState(), *CtxI);
4961 }
4962
4963 /// See AbstractAttribute::getState()
4964 /// {
4965 StateType &getState() override { return *this; }
4966 const StateType &getState() const override { return *this; }
4967 /// }
4968
4969 /// Helper function for collecting accessed bytes in must-be-executed-context
4970 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4971 DerefState &State) {
4972 const Value *UseV = U->get();
4973 if (!UseV->getType()->isPointerTy())
4974 return;
4975
4976 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4977 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4978 return;
4979
4980 int64_t Offset;
4982 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4983 if (Base && Base == &getAssociatedValue())
4984 State.addAccessedBytes(Offset, Loc->Size.getValue());
4985 }
4986
4987 /// See followUsesInMBEC
4988 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4989 AADereferenceable::StateType &State) {
4990 bool IsNonNull = false;
4991 bool TrackUse = false;
4992 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4993 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4994 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4995 << " for instruction " << *I << "\n");
4996
4997 addAccessedBytesForUse(A, U, I, State);
4998 State.takeKnownDerefBytesMaximum(DerefBytes);
4999 return TrackUse;
5000 }
5001
5002 /// See AbstractAttribute::manifest(...).
5003 ChangeStatus manifest(Attributor &A) override {
5004 ChangeStatus Change = AADereferenceable::manifest(A);
5005 bool IsKnownNonNull;
5006 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5007 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5008 if (IsAssumedNonNull &&
5009 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5010 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5011 return ChangeStatus::CHANGED;
5012 }
5013 return Change;
5014 }
5015
5016 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5017 SmallVectorImpl<Attribute> &Attrs) const override {
5018 // TODO: Add *_globally support
5019 bool IsKnownNonNull;
5020 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5021 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5022 if (IsAssumedNonNull)
5023 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5024 Ctx, getAssumedDereferenceableBytes()));
5025 else
5026 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5027 Ctx, getAssumedDereferenceableBytes()));
5028 }
5029
5030 /// See AbstractAttribute::getAsStr().
5031 const std::string getAsStr(Attributor *A) const override {
5032 if (!getAssumedDereferenceableBytes())
5033 return "unknown-dereferenceable";
5034 bool IsKnownNonNull;
5035 bool IsAssumedNonNull = false;
5036 if (A)
5038 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5039 return std::string("dereferenceable") +
5040 (IsAssumedNonNull ? "" : "_or_null") +
5041 (isAssumedGlobal() ? "_globally" : "") + "<" +
5042 std::to_string(getKnownDereferenceableBytes()) + "-" +
5043 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5044 (!A ? " [non-null is unknown]" : "");
5045 }
5046};
5047
5048/// Dereferenceable attribute for a floating value.
5049struct AADereferenceableFloating : AADereferenceableImpl {
5050 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5051 : AADereferenceableImpl(IRP, A) {}
5052
5053 /// See AbstractAttribute::updateImpl(...).
5054 ChangeStatus updateImpl(Attributor &A) override {
5055 bool Stripped;
5056 bool UsedAssumedInformation = false;
5058 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5059 AA::AnyScope, UsedAssumedInformation)) {
5060 Values.push_back({getAssociatedValue(), getCtxI()});
5061 Stripped = false;
5062 } else {
5063 Stripped = Values.size() != 1 ||
5064 Values.front().getValue() != &getAssociatedValue();
5065 }
5066
5067 const DataLayout &DL = A.getDataLayout();
5068 DerefState T;
5069
5070 auto VisitValueCB = [&](const Value &V) -> bool {
5071 unsigned IdxWidth =
5072 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5073 APInt Offset(IdxWidth, 0);
5075 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5076 /* AllowNonInbounds */ true);
5077
5078 const auto *AA = A.getAAFor<AADereferenceable>(
5079 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5080 int64_t DerefBytes = 0;
5081 if (!AA || (!Stripped && this == AA)) {
5082 // Use IR information if we did not strip anything.
5083 // TODO: track globally.
5084 bool CanBeNull, CanBeFreed;
5085 DerefBytes =
5086 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5087 T.GlobalState.indicatePessimisticFixpoint();
5088 } else {
5089 const DerefState &DS = AA->getState();
5090 DerefBytes = DS.DerefBytesState.getAssumed();
5091 T.GlobalState &= DS.GlobalState;
5092 }
5093
5094 // For now we do not try to "increase" dereferenceability due to negative
5095 // indices as we first have to come up with code to deal with loops and
5096 // for overflows of the dereferenceable bytes.
5097 int64_t OffsetSExt = Offset.getSExtValue();
5098 if (OffsetSExt < 0)
5099 OffsetSExt = 0;
5100
5101 T.takeAssumedDerefBytesMinimum(
5102 std::max(int64_t(0), DerefBytes - OffsetSExt));
5103
5104 if (this == AA) {
5105 if (!Stripped) {
5106 // If nothing was stripped IR information is all we got.
5107 T.takeKnownDerefBytesMaximum(
5108 std::max(int64_t(0), DerefBytes - OffsetSExt));
5109 T.indicatePessimisticFixpoint();
5110 } else if (OffsetSExt > 0) {
5111 // If something was stripped but there is circular reasoning we look
5112 // for the offset. If it is positive we basically decrease the
5113 // dereferenceable bytes in a circular loop now, which will simply
5114 // drive them down to the known value in a very slow way which we
5115 // can accelerate.
5116 T.indicatePessimisticFixpoint();
5117 }
5118 }
5119
5120 return T.isValidState();
5121 };
5122
5123 for (const auto &VAC : Values)
5124 if (!VisitValueCB(*VAC.getValue()))
5125 return indicatePessimisticFixpoint();
5126
5127 return clampStateAndIndicateChange(getState(), T);
5128 }
5129
5130 /// See AbstractAttribute::trackStatistics()
5131 void trackStatistics() const override {
5132 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5133 }
5134};
5135
5136/// Dereferenceable attribute for a return value.
5137struct AADereferenceableReturned final
5138 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5139 using Base =
5140 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5141 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5142 : Base(IRP, A) {}
5143
5144 /// See AbstractAttribute::trackStatistics()
5145 void trackStatistics() const override {
5146 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5147 }
5148};
5149
5150/// Dereferenceable attribute for an argument
5151struct AADereferenceableArgument final
5152 : AAArgumentFromCallSiteArguments<AADereferenceable,
5153 AADereferenceableImpl> {
5154 using Base =
5155 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5156 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5157 : Base(IRP, A) {}
5158
5159 /// See AbstractAttribute::trackStatistics()
5160 void trackStatistics() const override {
5161 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5162 }
5163};
5164
5165/// Dereferenceable attribute for a call site argument.
5166struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5167 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5168 : AADereferenceableFloating(IRP, A) {}
5169
5170 /// See AbstractAttribute::trackStatistics()
5171 void trackStatistics() const override {
5172 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5173 }
5174};
5175
5176/// Dereferenceable attribute deduction for a call site return value.
5177struct AADereferenceableCallSiteReturned final
5178 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5179 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5180 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5181 : Base(IRP, A) {}
5182
5183 /// See AbstractAttribute::trackStatistics()
5184 void trackStatistics() const override {
5185 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5186 }
5187};
5188} // namespace
5189
5190// ------------------------ Align Argument Attribute ------------------------
5191
5192namespace {
5193
5194static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5195 Value &AssociatedValue, const Use *U,
5196 const Instruction *I, bool &TrackUse) {
5197 // We need to follow common pointer manipulation uses to the accesses they
5198 // feed into.
5199 if (isa<CastInst>(I)) {
5200 // Follow all but ptr2int casts.
5201 TrackUse = !isa<PtrToIntInst>(I);
5202 return 0;
5203 }
5204 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5205 if (GEP->hasAllConstantIndices())
5206 TrackUse = true;
5207 return 0;
5208 }
5209 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5210 switch (II->getIntrinsicID()) {
5211 case Intrinsic::ptrmask: {
5212 // Is it appropriate to pull attribute in initialization?
5213 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5214 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5215 const auto *AlignAA = A.getAAFor<AAAlign>(
5216 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5217 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5218 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5220 Align ConstAlign(UINT64_C(1) << ShiftValue);
5221 if (ConstAlign >= AlignAA->getKnownAlign())
5222 return Align(1).value();
5223 }
5224 if (AlignAA)
5225 return AlignAA->getKnownAlign().value();
5226 break;
5227 }
5228 case Intrinsic::amdgcn_make_buffer_rsrc: {
5229 const auto *AlignAA = A.getAAFor<AAAlign>(
5230 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5231 if (AlignAA)
5232 return AlignAA->getKnownAlign().value();
5233 break;
5234 }
5235 default:
5236 break;
5237 }
5238
5239 MaybeAlign MA;
5240 if (const auto *CB = dyn_cast<CallBase>(I)) {
5241 if (CB->isBundleOperand(U) || CB->isCallee(U))
5242 return 0;
5243
5244 unsigned ArgNo = CB->getArgOperandNo(U);
5245 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5246 // As long as we only use known information there is no need to track
5247 // dependences here.
5248 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5249 if (AlignAA)
5250 MA = MaybeAlign(AlignAA->getKnownAlign());
5251 }
5252
5253 const DataLayout &DL = A.getDataLayout();
5254 const Value *UseV = U->get();
5255 if (auto *SI = dyn_cast<StoreInst>(I)) {
5256 if (SI->getPointerOperand() == UseV)
5257 MA = SI->getAlign();
5258 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5259 if (LI->getPointerOperand() == UseV)
5260 MA = LI->getAlign();
5261 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5262 if (AI->getPointerOperand() == UseV)
5263 MA = AI->getAlign();
5264 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5265 if (AI->getPointerOperand() == UseV)
5266 MA = AI->getAlign();
5267 }
5268
5269 if (!MA || *MA <= QueryingAA.getKnownAlign())
5270 return 0;
5271
5272 unsigned Alignment = MA->value();
5273 int64_t Offset;
5274
5275 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5276 if (Base == &AssociatedValue) {
5277 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5278 // So we can say that the maximum power of two which is a divisor of
5279 // gcd(Offset, Alignment) is an alignment.
5280
5281 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5282 Alignment = llvm::bit_floor(gcd);
5283 }
5284 }
5285
5286 return Alignment;
5287}
5288
5289struct AAAlignImpl : AAAlign {
5290 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5291
5292 /// See AbstractAttribute::initialize(...).
5293 void initialize(Attributor &A) override {
5295 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5296 for (const Attribute &Attr : Attrs)
5297 takeKnownMaximum(Attr.getValueAsInt());
5298
5299 Value &V = *getAssociatedValue().stripPointerCasts();
5300 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5301
5302 if (Instruction *CtxI = getCtxI())
5303 followUsesInMBEC(*this, A, getState(), *CtxI);
5304 }
5305
5306 /// See AbstractAttribute::manifest(...).
5307 ChangeStatus manifest(Attributor &A) override {
5308 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5309
5310 // Check for users that allow alignment annotations.
5311 Value &AssociatedValue = getAssociatedValue();
5312 if (isa<ConstantData>(AssociatedValue))
5313 return ChangeStatus::UNCHANGED;
5314
5315 for (const Use &U : AssociatedValue.uses()) {
5316 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5317 if (SI->getPointerOperand() == &AssociatedValue)
5318 if (SI->getAlign() < getAssumedAlign()) {
5319 STATS_DECLTRACK(AAAlign, Store,
5320 "Number of times alignment added to a store");
5321 SI->setAlignment(getAssumedAlign());
5322 InstrChanged = ChangeStatus::CHANGED;
5323 }
5324 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5325 if (LI->getPointerOperand() == &AssociatedValue)
5326 if (LI->getAlign() < getAssumedAlign()) {
5327 LI->setAlignment(getAssumedAlign());
5328 STATS_DECLTRACK(AAAlign, Load,
5329 "Number of times alignment added to a load");
5330 InstrChanged = ChangeStatus::CHANGED;
5331 }
5332 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5333 if (RMW->getPointerOperand() == &AssociatedValue) {
5334 if (RMW->getAlign() < getAssumedAlign()) {
5335 STATS_DECLTRACK(AAAlign, AtomicRMW,
5336 "Number of times alignment added to atomicrmw");
5337
5338 RMW->setAlignment(getAssumedAlign());
5339 InstrChanged = ChangeStatus::CHANGED;
5340 }
5341 }
5342 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5343 if (CAS->getPointerOperand() == &AssociatedValue) {
5344 if (CAS->getAlign() < getAssumedAlign()) {
5345 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5346 "Number of times alignment added to cmpxchg");
5347 CAS->setAlignment(getAssumedAlign());
5348 InstrChanged = ChangeStatus::CHANGED;
5349 }
5350 }
5351 }
5352 }
5353
5354 ChangeStatus Changed = AAAlign::manifest(A);
5355
5356 Align InheritAlign =
5357 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5358 if (InheritAlign >= getAssumedAlign())
5359 return InstrChanged;
5360 return Changed | InstrChanged;
5361 }
5362
5363 // TODO: Provide a helper to determine the implied ABI alignment and check in
5364 // the existing manifest method and a new one for AAAlignImpl that value
5365 // to avoid making the alignment explicit if it did not improve.
5366
5367 /// See AbstractAttribute::getDeducedAttributes
5368 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5369 SmallVectorImpl<Attribute> &Attrs) const override {
5370 if (getAssumedAlign() > 1)
5371 Attrs.emplace_back(
5372 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5373 }
5374
5375 /// See followUsesInMBEC
5376 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5377 AAAlign::StateType &State) {
5378 bool TrackUse = false;
5379
5380 unsigned int KnownAlign =
5381 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5382 State.takeKnownMaximum(KnownAlign);
5383
5384 return TrackUse;
5385 }
5386
5387 /// See AbstractAttribute::getAsStr().
5388 const std::string getAsStr(Attributor *A) const override {
5389 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5390 std::to_string(getAssumedAlign().value()) + ">";
5391 }
5392};
5393
5394/// Align attribute for a floating value.
5395struct AAAlignFloating : AAAlignImpl {
5396 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5397
5398 /// See AbstractAttribute::updateImpl(...).
5399 ChangeStatus updateImpl(Attributor &A) override {
5400 const DataLayout &DL = A.getDataLayout();
5401
5402 bool Stripped;
5403 bool UsedAssumedInformation = false;
5405 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5406 AA::AnyScope, UsedAssumedInformation)) {
5407 Values.push_back({getAssociatedValue(), getCtxI()});
5408 Stripped = false;
5409 } else {
5410 Stripped = Values.size() != 1 ||
5411 Values.front().getValue() != &getAssociatedValue();
5412 }
5413
5414 StateType T;
5415 auto VisitValueCB = [&](Value &V) -> bool {
5417 return true;
5418 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5419 DepClassTy::REQUIRED);
5420 if (!AA || (!Stripped && this == AA)) {
5421 int64_t Offset;
5422 unsigned Alignment = 1;
5423 if (const Value *Base =
5425 // TODO: Use AAAlign for the base too.
5426 Align PA = Base->getPointerAlignment(DL);
5427 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5428 // So we can say that the maximum power of two which is a divisor of
5429 // gcd(Offset, Alignment) is an alignment.
5430
5431 uint32_t gcd =
5432 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5433 Alignment = llvm::bit_floor(gcd);
5434 } else {
5435 Alignment = V.getPointerAlignment(DL).value();
5436 }
5437 // Use only IR information if we did not strip anything.
5438 T.takeKnownMaximum(Alignment);
5439 T.indicatePessimisticFixpoint();
5440 } else {
5441 // Use abstract attribute information.
5442 const AAAlign::StateType &DS = AA->getState();
5443 T ^= DS;
5444 }
5445 return T.isValidState();
5446 };
5447
5448 for (const auto &VAC : Values) {
5449 if (!VisitValueCB(*VAC.getValue()))
5450 return indicatePessimisticFixpoint();
5451 }
5452
5453 // TODO: If we know we visited all incoming values, thus no are assumed
5454 // dead, we can take the known information from the state T.
5455 return clampStateAndIndicateChange(getState(), T);
5456 }
5457
5458 /// See AbstractAttribute::trackStatistics()
5459 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5460};
5461
5462/// Align attribute for function return value.
5463struct AAAlignReturned final
5464 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5465 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5466 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5467
5468 /// See AbstractAttribute::trackStatistics()
5469 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5470};
5471
5472/// Align attribute for function argument.
5473struct AAAlignArgument final
5474 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5475 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5476 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5477
5478 /// See AbstractAttribute::manifest(...).
5479 ChangeStatus manifest(Attributor &A) override {
5480 // If the associated argument is involved in a must-tail call we give up
5481 // because we would need to keep the argument alignments of caller and
5482 // callee in-sync. Just does not seem worth the trouble right now.
5483 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5484 return ChangeStatus::UNCHANGED;
5485 return Base::manifest(A);
5486 }
5487
5488 /// See AbstractAttribute::trackStatistics()
5489 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5490};
5491
5492struct AAAlignCallSiteArgument final : AAAlignFloating {
5493 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5494 : AAAlignFloating(IRP, A) {}
5495
5496 /// See AbstractAttribute::manifest(...).
5497 ChangeStatus manifest(Attributor &A) override {
5498 // If the associated argument is involved in a must-tail call we give up
5499 // because we would need to keep the argument alignments of caller and
5500 // callee in-sync. Just does not seem worth the trouble right now.
5501 if (Argument *Arg = getAssociatedArgument())
5502 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5503 return ChangeStatus::UNCHANGED;
5504 ChangeStatus Changed = AAAlignImpl::manifest(A);
5505 Align InheritAlign =
5506 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5507 if (InheritAlign >= getAssumedAlign())
5508 Changed = ChangeStatus::UNCHANGED;
5509 return Changed;
5510 }
5511
5512 /// See AbstractAttribute::updateImpl(Attributor &A).
5513 ChangeStatus updateImpl(Attributor &A) override {
5514 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5515 if (Argument *Arg = getAssociatedArgument()) {
5516 // We only take known information from the argument
5517 // so we do not need to track a dependence.
5518 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5519 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5520 if (ArgAlignAA)
5521 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5522 }
5523 return Changed;
5524 }
5525
5526 /// See AbstractAttribute::trackStatistics()
5527 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5528};
5529
5530/// Align attribute deduction for a call site return value.
5531struct AAAlignCallSiteReturned final
5532 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5533 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5534 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5535 : Base(IRP, A) {}
5536
5537 ChangeStatus updateImpl(Attributor &A) override {
5538 Instruction *I = getIRPosition().getCtxI();
5539 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5540 switch (II->getIntrinsicID()) {
5541 case Intrinsic::ptrmask: {
5542 Align Alignment;
5543 bool Valid = false;
5544
5545 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5546 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5547 if (ConstVals && ConstVals->isValidState()) {
5548 unsigned ShiftValue =
5549 std::min(ConstVals->getAssumedMinTrailingZeros(),
5550 Value::MaxAlignmentExponent);
5551 Alignment = Align(UINT64_C(1) << ShiftValue);
5552 Valid = true;
5553 }
5554
5555 const auto *AlignAA =
5556 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5557 DepClassTy::REQUIRED);
5558 if (AlignAA) {
5559 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5560 Valid = true;
5561 }
5562
5563 if (Valid)
5565 this->getState(),
5566 std::min(this->getAssumedAlign(), Alignment).value());
5567 break;
5568 }
5569 // FIXME: Should introduce target specific sub-attributes and letting
5570 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5571 // specific intrinsics.
5572 case Intrinsic::amdgcn_make_buffer_rsrc: {
5573 const auto *AlignAA =
5574 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5575 DepClassTy::REQUIRED);
5576 if (AlignAA)
5578 this->getState(), AlignAA->getAssumedAlign().value());
5579 break;
5580 }
5581 default:
5582 break;
5583 }
5584 }
5585 return Base::updateImpl(A);
5586 };
5587 /// See AbstractAttribute::trackStatistics()
5588 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5589};
5590} // namespace
5591
5592/// ------------------ Function No-Return Attribute ----------------------------
5593namespace {
5594struct AANoReturnImpl : public AANoReturn {
5595 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5596
5597 /// See AbstractAttribute::initialize(...).
5598 void initialize(Attributor &A) override {
5599 bool IsKnown;
5601 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5602 (void)IsKnown;
5603 }
5604
5605 /// See AbstractAttribute::getAsStr().
5606 const std::string getAsStr(Attributor *A) const override {
5607 return getAssumed() ? "noreturn" : "may-return";
5608 }
5609
5610 /// See AbstractAttribute::updateImpl(Attributor &A).
5611 ChangeStatus updateImpl(Attributor &A) override {
5612 auto CheckForNoReturn = [](Instruction &) { return false; };
5613 bool UsedAssumedInformation = false;
5614 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5615 {(unsigned)Instruction::Ret},
5616 UsedAssumedInformation))
5617 return indicatePessimisticFixpoint();
5618 return ChangeStatus::UNCHANGED;
5619 }
5620};
5621
5622struct AANoReturnFunction final : AANoReturnImpl {
5623 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5624 : AANoReturnImpl(IRP, A) {}
5625
5626 /// See AbstractAttribute::trackStatistics()
5627 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5628};
5629
5630/// NoReturn attribute deduction for a call sites.
5631struct AANoReturnCallSite final
5632 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5633 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5634 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5635
5636 /// See AbstractAttribute::trackStatistics()
5637 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5638};
5639} // namespace
5640
5641/// ----------------------- Instance Info ---------------------------------
5642
5643namespace {
5644/// A class to hold the state of for no-capture attributes.
5645struct AAInstanceInfoImpl : public AAInstanceInfo {
5646 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5647 : AAInstanceInfo(IRP, A) {}
5648
5649 /// See AbstractAttribute::initialize(...).
5650 void initialize(Attributor &A) override {
5651 Value &V = getAssociatedValue();
5652 if (auto *C = dyn_cast<Constant>(&V)) {
5653 if (C->isThreadDependent())
5654 indicatePessimisticFixpoint();
5655 else
5656 indicateOptimisticFixpoint();
5657 return;
5658 }
5659 if (auto *CB = dyn_cast<CallBase>(&V))
5660 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5661 !CB->mayReadFromMemory()) {
5662 indicateOptimisticFixpoint();
5663 return;
5664 }
5665 if (auto *I = dyn_cast<Instruction>(&V)) {
5666 const auto *CI =
5667 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5668 *I->getFunction());
5669 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5670 indicatePessimisticFixpoint();
5671 return;
5672 }
5673 }
5674 }
5675
5676 /// See AbstractAttribute::updateImpl(...).
5677 ChangeStatus updateImpl(Attributor &A) override {
5678 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5679
5680 Value &V = getAssociatedValue();
5681 const Function *Scope = nullptr;
5682 if (auto *I = dyn_cast<Instruction>(&V))
5683 Scope = I->getFunction();
5684 if (auto *A = dyn_cast<Argument>(&V)) {
5685 Scope = A->getParent();
5686 if (!Scope->hasLocalLinkage())
5687 return Changed;
5688 }
5689 if (!Scope)
5690 return indicateOptimisticFixpoint();
5691
5692 bool IsKnownNoRecurse;
5694 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5695 IsKnownNoRecurse))
5696 return Changed;
5697
5698 auto UsePred = [&](const Use &U, bool &Follow) {
5699 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5700 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5701 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5702 Follow = true;
5703 return true;
5704 }
5705 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5706 (isa<StoreInst>(UserI) &&
5707 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5708 return true;
5709 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5710 // This check is not guaranteeing uniqueness but for now that we cannot
5711 // end up with two versions of \p U thinking it was one.
5713 if (!Callee || !Callee->hasLocalLinkage())
5714 return true;
5715 if (!CB->isArgOperand(&U))
5716 return false;
5717 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5719 DepClassTy::OPTIONAL);
5720 if (!ArgInstanceInfoAA ||
5721 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5722 return false;
5723 // If this call base might reach the scope again we might forward the
5724 // argument back here. This is very conservative.
5726 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5727 [Scope](const Function &Fn) { return &Fn != Scope; }))
5728 return false;
5729 return true;
5730 }
5731 return false;
5732 };
5733
5734 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5735 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5736 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5737 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5738 AA::isDynamicallyUnique(A, *this, *Ptr))
5739 return true;
5740 }
5741 return false;
5742 };
5743
5744 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5745 DepClassTy::OPTIONAL,
5746 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5747 return indicatePessimisticFixpoint();
5748
5749 return Changed;
5750 }
5751
5752 /// See AbstractState::getAsStr().
5753 const std::string getAsStr(Attributor *A) const override {
5754 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5755 }
5756
5757 /// See AbstractAttribute::trackStatistics()
5758 void trackStatistics() const override {}
5759};
5760
5761/// InstanceInfo attribute for floating values.
5762struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5763 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5764 : AAInstanceInfoImpl(IRP, A) {}
5765};
5766
5767/// NoCapture attribute for function arguments.
5768struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5769 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5770 : AAInstanceInfoFloating(IRP, A) {}
5771};
5772
5773/// InstanceInfo attribute for call site arguments.
5774struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5775 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5776 : AAInstanceInfoImpl(IRP, A) {}
5777
5778 /// See AbstractAttribute::updateImpl(...).
5779 ChangeStatus updateImpl(Attributor &A) override {
5780 // TODO: Once we have call site specific value information we can provide
5781 // call site specific liveness information and then it makes
5782 // sense to specialize attributes for call sites arguments instead of
5783 // redirecting requests to the callee argument.
5784 Argument *Arg = getAssociatedArgument();
5785 if (!Arg)
5786 return indicatePessimisticFixpoint();
5787 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5788 auto *ArgAA =
5789 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5790 if (!ArgAA)
5791 return indicatePessimisticFixpoint();
5792 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5793 }
5794};
5795
5796/// InstanceInfo attribute for function return value.
5797struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5798 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5799 : AAInstanceInfoImpl(IRP, A) {
5800 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5801 }
5802
5803 /// See AbstractAttribute::initialize(...).
5804 void initialize(Attributor &A) override {
5805 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5806 }
5807
5808 /// See AbstractAttribute::updateImpl(...).
5809 ChangeStatus updateImpl(Attributor &A) override {
5810 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5811 }
5812};
5813
5814/// InstanceInfo attribute deduction for a call site return value.
5815struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5816 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5817 : AAInstanceInfoFloating(IRP, A) {}
5818};
5819} // namespace
5820
5821/// ----------------------- Variable Capturing ---------------------------------
5823 Attribute::AttrKind ImpliedAttributeKind,
5824 bool IgnoreSubsumingPositions) {
5825 assert(ImpliedAttributeKind == Attribute::Captures &&
5826 "Unexpected attribute kind");
5827 Value &V = IRP.getAssociatedValue();
5828 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5829 return V.use_empty();
5830
5831 // You cannot "capture" null in the default address space.
5832 //
5833 // FIXME: This should use NullPointerIsDefined to account for the function
5834 // attribute.
5836 V.getType()->getPointerAddressSpace() == 0)) {
5837 return true;
5838 }
5839
5841 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5842 /* IgnoreSubsumingPositions */ true);
5843 for (const Attribute &Attr : Attrs)
5844 if (capturesNothing(Attr.getCaptureInfo()))
5845 return true;
5846
5848 if (Argument *Arg = IRP.getAssociatedArgument()) {
5850 A.getAttrs(IRPosition::argument(*Arg),
5851 {Attribute::Captures, Attribute::ByVal}, Attrs,
5852 /* IgnoreSubsumingPositions */ true);
5853 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5854 return Attr.getKindAsEnum() == Attribute::ByVal ||
5856 });
5857 if (ArgNoCapture) {
5858 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5859 V.getContext(), CaptureInfo::none()));
5860 return true;
5861 }
5862 }
5863
5864 if (const Function *F = IRP.getAssociatedFunction()) {
5865 // Check what state the associated function can actually capture.
5868 if (State.isKnown(NO_CAPTURE)) {
5869 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5871 return true;
5872 }
5873 }
5874
5875 return false;
5876}
5877
5878/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5879/// depending on the ability of the function associated with \p IRP to capture
5880/// state in memory and through "returning/throwing", respectively.
5882 const Function &F,
5883 BitIntegerState &State) {
5884 // TODO: Once we have memory behavior attributes we should use them here.
5885
5886 // If we know we cannot communicate or write to memory, we do not care about
5887 // ptr2int anymore.
5888 bool ReadOnly = F.onlyReadsMemory();
5889 bool NoThrow = F.doesNotThrow();
5890 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5891 if (ReadOnly && NoThrow && IsVoidReturn) {
5892 State.addKnownBits(NO_CAPTURE);
5893 return;
5894 }
5895
5896 // A function cannot capture state in memory if it only reads memory, it can
5897 // however return/throw state and the state might be influenced by the
5898 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5899 if (ReadOnly)
5900 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5901
5902 // A function cannot communicate state back if it does not through
5903 // exceptions and doesn not return values.
5904 if (NoThrow && IsVoidReturn)
5905 State.addKnownBits(NOT_CAPTURED_IN_RET);
5906
5907 // Check existing "returned" attributes.
5908 int ArgNo = IRP.getCalleeArgNo();
5909 if (!NoThrow || ArgNo < 0 ||
5910 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5911 return;
5912
5913 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5914 if (F.hasParamAttribute(U, Attribute::Returned)) {
5915 if (U == unsigned(ArgNo))
5916 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5917 else if (ReadOnly)
5918 State.addKnownBits(NO_CAPTURE);
5919 else
5920 State.addKnownBits(NOT_CAPTURED_IN_RET);
5921 break;
5922 }
5923}
5924
5925namespace {
5926/// A class to hold the state of for no-capture attributes.
5927struct AANoCaptureImpl : public AANoCapture {
5928 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5929
5930 /// See AbstractAttribute::initialize(...).
5931 void initialize(Attributor &A) override {
5932 bool IsKnown;
5934 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5935 (void)IsKnown;
5936 }
5937
5938 /// See AbstractAttribute::updateImpl(...).
5939 ChangeStatus updateImpl(Attributor &A) override;
5940
5941 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5942 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5943 SmallVectorImpl<Attribute> &Attrs) const override {
5944 if (!isAssumedNoCaptureMaybeReturned())
5945 return;
5946
5947 if (isArgumentPosition()) {
5948 if (isAssumedNoCapture())
5949 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5950 else if (ManifestInternal)
5951 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5952 }
5953 }
5954
5955 /// See AbstractState::getAsStr().
5956 const std::string getAsStr(Attributor *A) const override {
5957 if (isKnownNoCapture())
5958 return "known not-captured";
5959 if (isAssumedNoCapture())
5960 return "assumed not-captured";
5961 if (isKnownNoCaptureMaybeReturned())
5962 return "known not-captured-maybe-returned";
5963 if (isAssumedNoCaptureMaybeReturned())
5964 return "assumed not-captured-maybe-returned";
5965 return "assumed-captured";
5966 }
5967
5968 /// Check the use \p U and update \p State accordingly. Return true if we
5969 /// should continue to update the state.
5970 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5971 bool &Follow) {
5972 Instruction *UInst = cast<Instruction>(U.getUser());
5973 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5974 << *UInst << "\n");
5975
5976 // Deal with ptr2int by following uses.
5977 if (isa<PtrToIntInst>(UInst)) {
5978 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5979 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5980 /* Return */ true);
5981 }
5982
5983 // For stores we already checked if we can follow them, if they make it
5984 // here we give up.
5985 if (isa<StoreInst>(UInst))
5986 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5987 /* Return */ true);
5988
5989 // Explicitly catch return instructions.
5990 if (isa<ReturnInst>(UInst)) {
5991 if (UInst->getFunction() == getAnchorScope())
5992 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5993 /* Return */ true);
5994 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5995 /* Return */ true);
5996 }
5997
5998 // For now we only use special logic for call sites. However, the tracker
5999 // itself knows about a lot of other non-capturing cases already.
6000 auto *CB = dyn_cast<CallBase>(UInst);
6001 if (!CB || !CB->isArgOperand(&U))
6002 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6003 /* Return */ true);
6004
6005 unsigned ArgNo = CB->getArgOperandNo(&U);
6006 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6007 // If we have a abstract no-capture attribute for the argument we can use
6008 // it to justify a non-capture attribute here. This allows recursion!
6009 bool IsKnownNoCapture;
6010 const AANoCapture *ArgNoCaptureAA = nullptr;
6011 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6012 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6013 &ArgNoCaptureAA);
6014 if (IsAssumedNoCapture)
6015 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6016 /* Return */ false);
6017 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6018 Follow = true;
6019 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6020 /* Return */ false);
6021 }
6022
6023 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6024 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6025 /* Return */ true);
6026 }
6027
6028 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6029 /// \p CapturedInRet, then return true if we should continue updating the
6030 /// state.
6031 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6032 bool CapturedInInt, bool CapturedInRet) {
6033 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6034 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6035 if (CapturedInMem)
6036 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6037 if (CapturedInInt)
6038 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6039 if (CapturedInRet)
6040 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6041 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6042 }
6043};
6044
6045ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6046 const IRPosition &IRP = getIRPosition();
6047 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6048 : &IRP.getAssociatedValue();
6049 if (!V)
6050 return indicatePessimisticFixpoint();
6051
6052 const Function *F =
6053 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6054
6055 // TODO: Is the checkForAllUses below useful for constants?
6056 if (!F)
6057 return indicatePessimisticFixpoint();
6058
6060 const IRPosition &FnPos = IRPosition::function(*F);
6061
6062 // Readonly means we cannot capture through memory.
6063 bool IsKnown;
6064 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6065 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6066 if (IsKnown)
6067 addKnownBits(NOT_CAPTURED_IN_MEM);
6068 }
6069
6070 // Make sure all returned values are different than the underlying value.
6071 // TODO: we could do this in a more sophisticated way inside
6072 // AAReturnedValues, e.g., track all values that escape through returns
6073 // directly somehow.
6074 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6076 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6078 UsedAssumedInformation))
6079 return false;
6080 bool SeenConstant = false;
6081 for (const AA::ValueAndContext &VAC : Values) {
6082 if (isa<Constant>(VAC.getValue())) {
6083 if (SeenConstant)
6084 return false;
6085 SeenConstant = true;
6086 } else if (!isa<Argument>(VAC.getValue()) ||
6087 VAC.getValue() == getAssociatedArgument())
6088 return false;
6089 }
6090 return true;
6091 };
6092
6093 bool IsKnownNoUnwind;
6095 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6096 bool IsVoidTy = F->getReturnType()->isVoidTy();
6097 bool UsedAssumedInformation = false;
6098 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6099 T.addKnownBits(NOT_CAPTURED_IN_RET);
6100 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6102 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6103 addKnownBits(NOT_CAPTURED_IN_RET);
6104 if (isKnown(NOT_CAPTURED_IN_MEM))
6105 return indicateOptimisticFixpoint();
6106 }
6107 }
6108 }
6109
6110 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6111 // TODO(captures): Make this more precise.
6112 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6113 if (capturesNothing(CI))
6114 return true;
6115 if (CI.isPassthrough()) {
6116 Follow = true;
6117 return true;
6118 }
6119 return checkUse(A, T, U, Follow);
6120 };
6121
6122 if (!A.checkForAllUses(UseCheck, *this, *V))
6123 return indicatePessimisticFixpoint();
6124
6125 AANoCapture::StateType &S = getState();
6126 auto Assumed = S.getAssumed();
6127 S.intersectAssumedBits(T.getAssumed());
6128 if (!isAssumedNoCaptureMaybeReturned())
6129 return indicatePessimisticFixpoint();
6130 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6132}
6133
6134/// NoCapture attribute for function arguments.
6135struct AANoCaptureArgument final : AANoCaptureImpl {
6136 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6137 : AANoCaptureImpl(IRP, A) {}
6138
6139 /// See AbstractAttribute::trackStatistics()
6140 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6141};
6142
6143/// NoCapture attribute for call site arguments.
6144struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6145 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6146 : AANoCaptureImpl(IRP, A) {}
6147
6148 /// See AbstractAttribute::updateImpl(...).
6149 ChangeStatus updateImpl(Attributor &A) override {
6150 // TODO: Once we have call site specific value information we can provide
6151 // call site specific liveness information and then it makes
6152 // sense to specialize attributes for call sites arguments instead of
6153 // redirecting requests to the callee argument.
6154 Argument *Arg = getAssociatedArgument();
6155 if (!Arg)
6156 return indicatePessimisticFixpoint();
6157 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6158 bool IsKnownNoCapture;
6159 const AANoCapture *ArgAA = nullptr;
6161 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6162 &ArgAA))
6163 return ChangeStatus::UNCHANGED;
6164 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6165 return indicatePessimisticFixpoint();
6166 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6167 }
6168
6169 /// See AbstractAttribute::trackStatistics()
6170 void trackStatistics() const override {
6172 };
6173};
6174
6175/// NoCapture attribute for floating values.
6176struct AANoCaptureFloating final : AANoCaptureImpl {
6177 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6178 : AANoCaptureImpl(IRP, A) {}
6179
6180 /// See AbstractAttribute::trackStatistics()
6181 void trackStatistics() const override {
6183 }
6184};
6185
6186/// NoCapture attribute for function return value.
6187struct AANoCaptureReturned final : AANoCaptureImpl {
6188 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6189 : AANoCaptureImpl(IRP, A) {
6190 llvm_unreachable("NoCapture is not applicable to function returns!");
6191 }
6192
6193 /// See AbstractAttribute::initialize(...).
6194 void initialize(Attributor &A) override {
6195 llvm_unreachable("NoCapture is not applicable to function returns!");
6196 }
6197
6198 /// See AbstractAttribute::updateImpl(...).
6199 ChangeStatus updateImpl(Attributor &A) override {
6200 llvm_unreachable("NoCapture is not applicable to function returns!");
6201 }
6202
6203 /// See AbstractAttribute::trackStatistics()
6204 void trackStatistics() const override {}
6205};
6206
6207/// NoCapture attribute deduction for a call site return value.
6208struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6209 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6210 : AANoCaptureImpl(IRP, A) {}
6211
6212 /// See AbstractAttribute::initialize(...).
6213 void initialize(Attributor &A) override {
6214 const Function *F = getAnchorScope();
6215 // Check what state the associated function can actually capture.
6216 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6217 }
6218
6219 /// See AbstractAttribute::trackStatistics()
6220 void trackStatistics() const override {
6222 }
6223};
6224} // namespace
6225
6226/// ------------------ Value Simplify Attribute ----------------------------
6227
6228bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6229 // FIXME: Add a typecast support.
6232 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6233 return false;
6234
6235 LLVM_DEBUG({
6237 dbgs() << "[ValueSimplify] is assumed to be "
6238 << **SimplifiedAssociatedValue << "\n";
6239 else
6240 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6241 });
6242 return true;
6243}
6244
6245namespace {
6246struct AAValueSimplifyImpl : AAValueSimplify {
6247 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6248 : AAValueSimplify(IRP, A) {}
6249
6250 /// See AbstractAttribute::initialize(...).
6251 void initialize(Attributor &A) override {
6252 if (getAssociatedValue().getType()->isVoidTy())
6253 indicatePessimisticFixpoint();
6254 if (A.hasSimplificationCallback(getIRPosition()))
6255 indicatePessimisticFixpoint();
6256 }
6257
6258 /// See AbstractAttribute::getAsStr().
6259 const std::string getAsStr(Attributor *A) const override {
6260 LLVM_DEBUG({
6261 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6262 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6263 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6264 });
6265 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6266 : "not-simple";
6267 }
6268
6269 /// See AbstractAttribute::trackStatistics()
6270 void trackStatistics() const override {}
6271
6272 /// See AAValueSimplify::getAssumedSimplifiedValue()
6273 std::optional<Value *>
6274 getAssumedSimplifiedValue(Attributor &A) const override {
6275 return SimplifiedAssociatedValue;
6276 }
6277
6278 /// Ensure the return value is \p V with type \p Ty, if not possible return
6279 /// nullptr. If \p Check is true we will only verify such an operation would
6280 /// suceed and return a non-nullptr value if that is the case. No IR is
6281 /// generated or modified.
6282 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6283 bool Check) {
6284 if (auto *TypedV = AA::getWithType(V, Ty))
6285 return TypedV;
6286 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6287 return Check ? &V
6288 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6289 &V, &Ty, "", CtxI->getIterator());
6290 return nullptr;
6291 }
6292
6293 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6294 /// If \p Check is true we will only verify such an operation would suceed and
6295 /// return a non-nullptr value if that is the case. No IR is generated or
6296 /// modified.
6297 static Value *reproduceInst(Attributor &A,
6298 const AbstractAttribute &QueryingAA,
6299 Instruction &I, Type &Ty, Instruction *CtxI,
6300 bool Check, ValueToValueMapTy &VMap) {
6301 assert(CtxI && "Cannot reproduce an instruction without context!");
6302 if (Check && (I.mayReadFromMemory() ||
6303 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6304 /* TLI */ nullptr)))
6305 return nullptr;
6306 for (Value *Op : I.operands()) {
6307 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6308 if (!NewOp) {
6309 assert(Check && "Manifest of new value unexpectedly failed!");
6310 return nullptr;
6311 }
6312 if (!Check)
6313 VMap[Op] = NewOp;
6314 }
6315 if (Check)
6316 return &I;
6317
6318 Instruction *CloneI = I.clone();
6319 // TODO: Try to salvage debug information here.
6320 CloneI->setDebugLoc(DebugLoc());
6321 VMap[&I] = CloneI;
6322 CloneI->insertBefore(CtxI->getIterator());
6323 RemapInstruction(CloneI, VMap);
6324 return CloneI;
6325 }
6326
6327 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6328 /// If \p Check is true we will only verify such an operation would suceed and
6329 /// return a non-nullptr value if that is the case. No IR is generated or
6330 /// modified.
6331 static Value *reproduceValue(Attributor &A,
6332 const AbstractAttribute &QueryingAA, Value &V,
6333 Type &Ty, Instruction *CtxI, bool Check,
6334 ValueToValueMapTy &VMap) {
6335 if (const auto &NewV = VMap.lookup(&V))
6336 return NewV;
6337 bool UsedAssumedInformation = false;
6338 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6339 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6340 if (!SimpleV.has_value())
6341 return PoisonValue::get(&Ty);
6342 Value *EffectiveV = &V;
6343 if (*SimpleV)
6344 EffectiveV = *SimpleV;
6345 if (auto *C = dyn_cast<Constant>(EffectiveV))
6346 return C;
6347 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6348 A.getInfoCache()))
6349 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6350 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6351 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6352 return ensureType(A, *NewV, Ty, CtxI, Check);
6353 return nullptr;
6354 }
6355
6356 /// Return a value we can use as replacement for the associated one, or
6357 /// nullptr if we don't have one that makes sense.
6358 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6359 Value *NewV = SimplifiedAssociatedValue
6360 ? *SimplifiedAssociatedValue
6361 : UndefValue::get(getAssociatedType());
6362 if (NewV && NewV != &getAssociatedValue()) {
6363 ValueToValueMapTy VMap;
6364 // First verify we can reprduce the value with the required type at the
6365 // context location before we actually start modifying the IR.
6366 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6367 /* CheckOnly */ true, VMap))
6368 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6369 /* CheckOnly */ false, VMap);
6370 }
6371 return nullptr;
6372 }
6373
6374 /// Helper function for querying AAValueSimplify and updating candidate.
6375 /// \param IRP The value position we are trying to unify with SimplifiedValue
6376 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6377 const IRPosition &IRP, bool Simplify = true) {
6378 bool UsedAssumedInformation = false;
6379 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6380 if (Simplify)
6381 QueryingValueSimplified = A.getAssumedSimplified(
6382 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6383 return unionAssumed(QueryingValueSimplified);
6384 }
6385
6386 /// Returns a candidate is found or not
6387 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6388 if (!getAssociatedValue().getType()->isIntegerTy())
6389 return false;
6390
6391 // This will also pass the call base context.
6392 const auto *AA =
6393 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6394 if (!AA)
6395 return false;
6396
6397 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6398
6399 if (!COpt) {
6400 SimplifiedAssociatedValue = std::nullopt;
6401 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6402 return true;
6403 }
6404 if (auto *C = *COpt) {
6405 SimplifiedAssociatedValue = C;
6406 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6407 return true;
6408 }
6409 return false;
6410 }
6411
6412 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6413 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6414 return true;
6415 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6416 return true;
6417 return false;
6418 }
6419
6420 /// See AbstractAttribute::manifest(...).
6421 ChangeStatus manifest(Attributor &A) override {
6422 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6423 for (auto &U : getAssociatedValue().uses()) {
6424 // Check if we need to adjust the insertion point to make sure the IR is
6425 // valid.
6426 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6427 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6428 IP = PHI->getIncomingBlock(U)->getTerminator();
6429 if (auto *NewV = manifestReplacementValue(A, IP)) {
6430 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6431 << " -> " << *NewV << " :: " << *this << "\n");
6432 if (A.changeUseAfterManifest(U, *NewV))
6433 Changed = ChangeStatus::CHANGED;
6434 }
6435 }
6436
6437 return Changed | AAValueSimplify::manifest(A);
6438 }
6439
6440 /// See AbstractState::indicatePessimisticFixpoint(...).
6441 ChangeStatus indicatePessimisticFixpoint() override {
6442 SimplifiedAssociatedValue = &getAssociatedValue();
6443 return AAValueSimplify::indicatePessimisticFixpoint();
6444 }
6445};
6446
6447struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6448 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6449 : AAValueSimplifyImpl(IRP, A) {}
6450
6451 void initialize(Attributor &A) override {
6452 AAValueSimplifyImpl::initialize(A);
6453 if (A.hasAttr(getIRPosition(),
6454 {Attribute::InAlloca, Attribute::Preallocated,
6455 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6456 /* IgnoreSubsumingPositions */ true))
6457 indicatePessimisticFixpoint();
6458 }
6459
6460 /// See AbstractAttribute::updateImpl(...).
6461 ChangeStatus updateImpl(Attributor &A) override {
6462 // Byval is only replacable if it is readonly otherwise we would write into
6463 // the replaced value and not the copy that byval creates implicitly.
6464 Argument *Arg = getAssociatedArgument();
6465 if (Arg->hasByValAttr()) {
6466 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6467 // there is no race by not copying a constant byval.
6468 bool IsKnown;
6469 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6470 return indicatePessimisticFixpoint();
6471 }
6472
6473 auto Before = SimplifiedAssociatedValue;
6474
6475 auto PredForCallSite = [&](AbstractCallSite ACS) {
6476 const IRPosition &ACSArgPos =
6477 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6478 // Check if a coresponding argument was found or if it is on not
6479 // associated (which can happen for callback calls).
6480 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6481 return false;
6482
6483 // Simplify the argument operand explicitly and check if the result is
6484 // valid in the current scope. This avoids refering to simplified values
6485 // in other functions, e.g., we don't want to say a an argument in a
6486 // static function is actually an argument in a different function.
6487 bool UsedAssumedInformation = false;
6488 std::optional<Constant *> SimpleArgOp =
6489 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6490 if (!SimpleArgOp)
6491 return true;
6492 if (!*SimpleArgOp)
6493 return false;
6494 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6495 return false;
6496 return unionAssumed(*SimpleArgOp);
6497 };
6498
6499 // Generate a answer specific to a call site context.
6500 bool Success;
6501 bool UsedAssumedInformation = false;
6502 if (hasCallBaseContext() &&
6503 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6504 Success = PredForCallSite(
6505 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6506 else
6507 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6508 UsedAssumedInformation);
6509
6510 if (!Success)
6511 if (!askSimplifiedValueForOtherAAs(A))
6512 return indicatePessimisticFixpoint();
6513
6514 // If a candidate was found in this update, return CHANGED.
6515 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6516 : ChangeStatus ::CHANGED;
6517 }
6518
6519 /// See AbstractAttribute::trackStatistics()
6520 void trackStatistics() const override {
6521 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6522 }
6523};
6524
6525struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6526 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6527 : AAValueSimplifyImpl(IRP, A) {}
6528
6529 /// See AAValueSimplify::getAssumedSimplifiedValue()
6530 std::optional<Value *>
6531 getAssumedSimplifiedValue(Attributor &A) const override {
6532 if (!isValidState())
6533 return nullptr;
6534 return SimplifiedAssociatedValue;
6535 }
6536
6537 /// See AbstractAttribute::updateImpl(...).
6538 ChangeStatus updateImpl(Attributor &A) override {
6539 auto Before = SimplifiedAssociatedValue;
6540
6541 auto ReturnInstCB = [&](Instruction &I) {
6542 auto &RI = cast<ReturnInst>(I);
6543 return checkAndUpdate(
6544 A, *this,
6545 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6546 };
6547
6548 bool UsedAssumedInformation = false;
6549 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6550 UsedAssumedInformation))
6551 if (!askSimplifiedValueForOtherAAs(A))
6552 return indicatePessimisticFixpoint();
6553
6554 // If a candidate was found in this update, return CHANGED.
6555 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6556 : ChangeStatus ::CHANGED;
6557 }
6558
6559 ChangeStatus manifest(Attributor &A) override {
6560 // We queried AAValueSimplify for the returned values so they will be
6561 // replaced if a simplified form was found. Nothing to do here.
6562 return ChangeStatus::UNCHANGED;
6563 }
6564
6565 /// See AbstractAttribute::trackStatistics()
6566 void trackStatistics() const override {
6567 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6568 }
6569};
6570
6571struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6572 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6573 : AAValueSimplifyImpl(IRP, A) {}
6574
6575 /// See AbstractAttribute::initialize(...).
6576 void initialize(Attributor &A) override {
6577 AAValueSimplifyImpl::initialize(A);
6578 Value &V = getAnchorValue();
6579
6580 // TODO: add other stuffs
6581 if (isa<Constant>(V))
6582 indicatePessimisticFixpoint();
6583 }
6584
6585 /// See AbstractAttribute::updateImpl(...).
6586 ChangeStatus updateImpl(Attributor &A) override {
6587 auto Before = SimplifiedAssociatedValue;
6588 if (!askSimplifiedValueForOtherAAs(A))
6589 return indicatePessimisticFixpoint();
6590
6591 // If a candidate was found in this update, return CHANGED.
6592 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6593 : ChangeStatus ::CHANGED;
6594 }
6595
6596 /// See AbstractAttribute::trackStatistics()
6597 void trackStatistics() const override {
6598 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6599 }
6600};
6601
6602struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6603 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6604 : AAValueSimplifyImpl(IRP, A) {}
6605
6606 /// See AbstractAttribute::initialize(...).
6607 void initialize(Attributor &A) override {
6608 SimplifiedAssociatedValue = nullptr;
6609 indicateOptimisticFixpoint();
6610 }
6611 /// See AbstractAttribute::initialize(...).
6612 ChangeStatus updateImpl(Attributor &A) override {
6614 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6615 }
6616 /// See AbstractAttribute::trackStatistics()
6617 void trackStatistics() const override {
6618 STATS_DECLTRACK_FN_ATTR(value_simplify)
6619 }
6620};
6621
6622struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6623 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6624 : AAValueSimplifyFunction(IRP, A) {}
6625 /// See AbstractAttribute::trackStatistics()
6626 void trackStatistics() const override {
6627 STATS_DECLTRACK_CS_ATTR(value_simplify)
6628 }
6629};
6630
6631struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6632 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6633 : AAValueSimplifyImpl(IRP, A) {}
6634
6635 void initialize(Attributor &A) override {
6636 AAValueSimplifyImpl::initialize(A);
6637 Function *Fn = getAssociatedFunction();
6638 assert(Fn && "Did expect an associted function");
6639 for (Argument &Arg : Fn->args()) {
6640 if (Arg.hasReturnedAttr()) {
6641 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6642 Arg.getArgNo());
6644 checkAndUpdate(A, *this, IRP))
6645 indicateOptimisticFixpoint();
6646 else
6647 indicatePessimisticFixpoint();
6648 return;
6649 }
6650 }
6651 }
6652
6653 /// See AbstractAttribute::updateImpl(...).
6654 ChangeStatus updateImpl(Attributor &A) override {
6655 return indicatePessimisticFixpoint();
6656 }
6657
6658 void trackStatistics() const override {
6659 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6660 }
6661};
6662
6663struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6664 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6665 : AAValueSimplifyFloating(IRP, A) {}
6666
6667 /// See AbstractAttribute::manifest(...).
6668 ChangeStatus manifest(Attributor &A) override {
6669 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6670 // TODO: We should avoid simplification duplication to begin with.
6671 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6672 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6673 if (FloatAA && FloatAA->getState().isValidState())
6674 return Changed;
6675
6676 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6677 Use &U = cast<CallBase>(&getAnchorValue())
6678 ->getArgOperandUse(getCallSiteArgNo());
6679 if (A.changeUseAfterManifest(U, *NewV))
6680 Changed = ChangeStatus::CHANGED;
6681 }
6682
6683 return Changed | AAValueSimplify::manifest(A);
6684 }
6685
6686 void trackStatistics() const override {
6687 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6688 }
6689};
6690} // namespace
6691
6692/// ----------------------- Heap-To-Stack Conversion ---------------------------
6693namespace {
6694struct AAHeapToStackFunction final : public AAHeapToStack {
6695
6696 static bool isGlobalizedLocal(const CallBase &CB) {
6697 Attribute A = CB.getFnAttr("alloc-family");
6698 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6699 }
6700
6701 struct AllocationInfo {
6702 /// The call that allocates the memory.
6703 CallBase *const CB;
6704
6705 /// Whether this allocation is an OpenMP globalized local variable.
6706 bool IsGlobalizedLocal = false;
6707
6708 /// The status wrt. a rewrite.
6709 enum {
6710 STACK_DUE_TO_USE,
6711 STACK_DUE_TO_FREE,
6712 INVALID,
6713 } Status = STACK_DUE_TO_USE;
6714
6715 /// Flag to indicate if we encountered a use that might free this allocation
6716 /// but which is not in the deallocation infos.
6717 bool HasPotentiallyFreeingUnknownUses = false;
6718
6719 /// Flag to indicate that we should place the new alloca in the function
6720 /// entry block rather than where the call site (CB) is.
6721 bool MoveAllocaIntoEntry = true;
6722
6723 /// The set of free calls that use this allocation.
6724 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6725 };
6726
6727 struct DeallocationInfo {
6728 /// The call that deallocates the memory.
6729 CallBase *const CB;
6730 /// The value freed by the call.
6731 Value *FreedOp;
6732
6733 /// Flag to indicate if we don't know all objects this deallocation might
6734 /// free.
6735 bool MightFreeUnknownObjects = false;
6736
6737 /// The set of allocation calls that are potentially freed.
6738 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6739 };
6740
6741 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6742 : AAHeapToStack(IRP, A) {}
6743
6744 ~AAHeapToStackFunction() override {
6745 // Ensure we call the destructor so we release any memory allocated in the
6746 // sets.
6747 for (auto &It : AllocationInfos)
6748 It.second->~AllocationInfo();
6749 for (auto &It : DeallocationInfos)
6750 It.second->~DeallocationInfo();
6751 }
6752
6753 void initialize(Attributor &A) override {
6754 AAHeapToStack::initialize(A);
6755
6756 const Function *F = getAnchorScope();
6757 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6758
6759 auto AllocationIdentifierCB = [&](Instruction &I) {
6760 CallBase *CB = dyn_cast<CallBase>(&I);
6761 if (!CB)
6762 return true;
6763 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6764 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6765 return true;
6766 }
6767 // To do heap to stack, we need to know that the allocation itself is
6768 // removable once uses are rewritten, and that we can initialize the
6769 // alloca to the same pattern as the original allocation result.
6770 if (isRemovableAlloc(CB, TLI)) {
6771 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6772 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6773 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6774 AllocationInfos[CB] = AI;
6775 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6776 }
6777 }
6778 return true;
6779 };
6780
6781 bool UsedAssumedInformation = false;
6782 bool Success = A.checkForAllCallLikeInstructions(
6783 AllocationIdentifierCB, *this, UsedAssumedInformation,
6784 /* CheckBBLivenessOnly */ false,
6785 /* CheckPotentiallyDead */ true);
6786 (void)Success;
6787 assert(Success && "Did not expect the call base visit callback to fail!");
6788
6790 [](const IRPosition &, const AbstractAttribute *,
6791 bool &) -> std::optional<Value *> { return nullptr; };
6792 for (const auto &It : AllocationInfos)
6793 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6794 SCB);
6795 for (const auto &It : DeallocationInfos)
6796 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6797 SCB);
6798 }
6799
6800 const std::string getAsStr(Attributor *A) const override {
6801 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6802 for (const auto &It : AllocationInfos) {
6803 if (It.second->Status == AllocationInfo::INVALID)
6804 ++NumInvalidMallocs;
6805 else
6806 ++NumH2SMallocs;
6807 }
6808 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6809 std::to_string(NumInvalidMallocs);
6810 }
6811
6812 /// See AbstractAttribute::trackStatistics().
6813 void trackStatistics() const override {
6814 STATS_DECL(
6815 MallocCalls, Function,
6816 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6817 for (const auto &It : AllocationInfos)
6818 if (It.second->Status != AllocationInfo::INVALID)
6819 ++BUILD_STAT_NAME(MallocCalls, Function);
6820 }
6821
6822 bool isAssumedHeapToStack(const CallBase &CB) const override {
6823 if (isValidState())
6824 if (AllocationInfo *AI =
6825 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6826 return AI->Status != AllocationInfo::INVALID;
6827 return false;
6828 }
6829
6830 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6831 if (!isValidState())
6832 return false;
6833
6834 for (const auto &It : AllocationInfos) {
6835 AllocationInfo &AI = *It.second;
6836 if (AI.Status == AllocationInfo::INVALID)
6837 continue;
6838
6839 if (AI.PotentialFreeCalls.count(&CB))
6840 return true;
6841 }
6842
6843 return false;
6844 }
6845
6846 ChangeStatus manifest(Attributor &A) override {
6847 assert(getState().isValidState() &&
6848 "Attempted to manifest an invalid state!");
6849
6850 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6851 Function *F = getAnchorScope();
6852 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6853
6854 for (auto &It : AllocationInfos) {
6855 AllocationInfo &AI = *It.second;
6856 if (AI.Status == AllocationInfo::INVALID)
6857 continue;
6858
6859 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6860 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6861 A.deleteAfterManifest(*FreeCall);
6862 HasChanged = ChangeStatus::CHANGED;
6863 }
6864
6865 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6866 << "\n");
6867
6868 auto Remark = [&](OptimizationRemark OR) {
6869 if (AI.IsGlobalizedLocal)
6870 return OR << "Moving globalized variable to the stack.";
6871 return OR << "Moving memory allocation from the heap to the stack.";
6872 };
6873 if (AI.IsGlobalizedLocal)
6874 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6875 else
6876 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6877
6878 const DataLayout &DL = A.getInfoCache().getDL();
6879 Value *Size;
6880 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6881 if (SizeAPI) {
6882 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6883 } else {
6884 LLVMContext &Ctx = AI.CB->getContext();
6885 ObjectSizeOpts Opts;
6886 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6887 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6888 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6889 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6890 Size = SizeOffsetPair.Size;
6891 }
6892
6893 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6894 ? F->getEntryBlock().begin()
6895 : AI.CB->getIterator();
6896
6897 Align Alignment(1);
6898 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6899 Alignment = std::max(Alignment, *RetAlign);
6900 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6901 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6902 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6903 "Expected an alignment during manifest!");
6904 Alignment =
6905 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6906 }
6907
6908 // TODO: Hoist the alloca towards the function entry.
6909 unsigned AS = DL.getAllocaAddrSpace();
6910 Instruction *Alloca =
6911 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6912 AI.CB->getName() + ".h2s", IP);
6913
6914 if (Alloca->getType() != AI.CB->getType())
6915 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6916 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6917
6918 auto *I8Ty = Type::getInt8Ty(F->getContext());
6919 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6920 assert(InitVal &&
6921 "Must be able to materialize initial memory state of allocation");
6922
6923 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6924
6925 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6926 auto *NBB = II->getNormalDest();
6927 UncondBrInst::Create(NBB, AI.CB->getParent());
6928 A.deleteAfterManifest(*AI.CB);
6929 } else {
6930 A.deleteAfterManifest(*AI.CB);
6931 }
6932
6933 // Initialize the alloca with the same value as used by the allocation
6934 // function. We can skip undef as the initial value of an alloc is
6935 // undef, and the memset would simply end up being DSEd.
6936 if (!isa<UndefValue>(InitVal)) {
6937 IRBuilder<> Builder(Alloca->getNextNode());
6938 // TODO: Use alignment above if align!=1
6939 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6940 }
6941 HasChanged = ChangeStatus::CHANGED;
6942 }
6943
6944 return HasChanged;
6945 }
6946
6947 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6948 Value &V) {
6949 bool UsedAssumedInformation = false;
6950 std::optional<Constant *> SimpleV =
6951 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6952 if (!SimpleV)
6953 return APInt(64, 0);
6954 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6955 return CI->getValue();
6956 return std::nullopt;
6957 }
6958
6959 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6960 AllocationInfo &AI) {
6961 auto Mapper = [&](const Value *V) -> const Value * {
6962 bool UsedAssumedInformation = false;
6963 if (std::optional<Constant *> SimpleV =
6964 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6965 if (*SimpleV)
6966 return *SimpleV;
6967 return V;
6968 };
6969
6970 const Function *F = getAnchorScope();
6971 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6972 return getAllocSize(AI.CB, TLI, Mapper);
6973 }
6974
6975 /// Collection of all malloc-like calls in a function with associated
6976 /// information.
6977 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6978
6979 /// Collection of all free-like calls in a function with associated
6980 /// information.
6981 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6982
6983 ChangeStatus updateImpl(Attributor &A) override;
6984};
6985
6986ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6988 const Function *F = getAnchorScope();
6989 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6990
6991 const auto *LivenessAA =
6992 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6993
6994 MustBeExecutedContextExplorer *Explorer =
6995 A.getInfoCache().getMustBeExecutedContextExplorer();
6996
6997 bool StackIsAccessibleByOtherThreads =
6998 A.getInfoCache().stackIsAccessibleByOtherThreads();
6999
7000 LoopInfo *LI =
7001 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7002 std::optional<bool> MayContainIrreducibleControl;
7003 auto IsInLoop = [&](BasicBlock &BB) {
7004 if (&F->getEntryBlock() == &BB)
7005 return false;
7006 if (!MayContainIrreducibleControl.has_value())
7007 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7008 if (*MayContainIrreducibleControl)
7009 return true;
7010 if (!LI)
7011 return true;
7012 return LI->getLoopFor(&BB) != nullptr;
7013 };
7014
7015 // Flag to ensure we update our deallocation information at most once per
7016 // updateImpl call and only if we use the free check reasoning.
7017 bool HasUpdatedFrees = false;
7018
7019 auto UpdateFrees = [&]() {
7020 HasUpdatedFrees = true;
7021
7022 for (auto &It : DeallocationInfos) {
7023 DeallocationInfo &DI = *It.second;
7024 // For now we cannot use deallocations that have unknown inputs, skip
7025 // them.
7026 if (DI.MightFreeUnknownObjects)
7027 continue;
7028
7029 // No need to analyze dead calls, ignore them instead.
7030 bool UsedAssumedInformation = false;
7031 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7032 /* CheckBBLivenessOnly */ true))
7033 continue;
7034
7035 // Use the non-optimistic version to get the freed object.
7036 Value *Obj = getUnderlyingObject(DI.FreedOp);
7037 if (!Obj) {
7038 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7039 DI.MightFreeUnknownObjects = true;
7040 continue;
7041 }
7042
7043 // Free of null and undef can be ignored as no-ops (or UB in the latter
7044 // case).
7046 continue;
7047
7048 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7049 if (!ObjCB) {
7050 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7051 << "\n");
7052 DI.MightFreeUnknownObjects = true;
7053 continue;
7054 }
7055
7056 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7057 if (!AI) {
7058 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7059 << "\n");
7060 DI.MightFreeUnknownObjects = true;
7061 continue;
7062 }
7063
7064 DI.PotentialAllocationCalls.insert(ObjCB);
7065 }
7066 };
7067
7068 auto FreeCheck = [&](AllocationInfo &AI) {
7069 // If the stack is not accessible by other threads, the "must-free" logic
7070 // doesn't apply as the pointer could be shared and needs to be places in
7071 // "shareable" memory.
7072 if (!StackIsAccessibleByOtherThreads) {
7073 bool IsKnownNoSycn;
7075 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7076 LLVM_DEBUG(
7077 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7078 "other threads and function is not nosync:\n");
7079 return false;
7080 }
7081 }
7082 if (!HasUpdatedFrees)
7083 UpdateFrees();
7084
7085 // TODO: Allow multi exit functions that have different free calls.
7086 if (AI.PotentialFreeCalls.size() != 1) {
7087 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7088 << AI.PotentialFreeCalls.size() << "\n");
7089 return false;
7090 }
7091 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7092 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7093 if (!DI) {
7094 LLVM_DEBUG(
7095 dbgs() << "[H2S] unique free call was not known as deallocation call "
7096 << *UniqueFree << "\n");
7097 return false;
7098 }
7099 if (DI->MightFreeUnknownObjects) {
7100 LLVM_DEBUG(
7101 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7102 return false;
7103 }
7104 if (DI->PotentialAllocationCalls.empty())
7105 return true;
7106 if (DI->PotentialAllocationCalls.size() > 1) {
7107 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7108 << DI->PotentialAllocationCalls.size()
7109 << " different allocations\n");
7110 return false;
7111 }
7112 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7113 LLVM_DEBUG(
7114 dbgs()
7115 << "[H2S] unique free call not known to free this allocation but "
7116 << **DI->PotentialAllocationCalls.begin() << "\n");
7117 return false;
7118 }
7119
7120 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7121 if (!AI.IsGlobalizedLocal) {
7122 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7123 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7124 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7125 "with the allocation "
7126 << *UniqueFree << "\n");
7127 return false;
7128 }
7129 }
7130 return true;
7131 };
7132
7133 auto UsesCheck = [&](AllocationInfo &AI) {
7134 bool ValidUsesOnly = true;
7135
7136 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7137 Instruction *UserI = cast<Instruction>(U.getUser());
7138 if (isa<LoadInst>(UserI))
7139 return true;
7140 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7141 if (SI->getValueOperand() == U.get()) {
7143 << "[H2S] escaping store to memory: " << *UserI << "\n");
7144 ValidUsesOnly = false;
7145 } else {
7146 // A store into the malloc'ed memory is fine.
7147 }
7148 return true;
7149 }
7150 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7151 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7152 return true;
7153 if (DeallocationInfos.count(CB)) {
7154 AI.PotentialFreeCalls.insert(CB);
7155 return true;
7156 }
7157
7158 unsigned ArgNo = CB->getArgOperandNo(&U);
7159 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7160
7161 bool IsKnownNoCapture;
7162 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7163 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7164
7165 // If a call site argument use is nofree, we are fine.
7166 bool IsKnownNoFree;
7167 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7168 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7169
7170 if (!IsAssumedNoCapture ||
7171 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7172 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7173
7174 // Emit a missed remark if this is missed OpenMP globalization.
7175 auto Remark = [&](OptimizationRemarkMissed ORM) {
7176 return ORM
7177 << "Could not move globalized variable to the stack. "
7178 "Variable is potentially captured in call. Mark "
7179 "parameter as `__attribute__((noescape))` to override.";
7180 };
7181
7182 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7183 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7184
7185 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7186 ValidUsesOnly = false;
7187 }
7188 return true;
7189 }
7190
7191 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7192 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7193 Follow = true;
7194 return true;
7195 }
7196 // Unknown user for which we can not track uses further (in a way that
7197 // makes sense).
7198 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7199 ValidUsesOnly = false;
7200 return true;
7201 };
7202 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7203 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7204 [&](const Use &OldU, const Use &NewU) {
7205 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7206 return !SI || StackIsAccessibleByOtherThreads ||
7207 AA::isAssumedThreadLocalObject(
7208 A, *SI->getPointerOperand(), *this);
7209 }))
7210 return false;
7211 return ValidUsesOnly;
7212 };
7213
7214 // The actual update starts here. We look at all allocations and depending on
7215 // their status perform the appropriate check(s).
7216 for (auto &It : AllocationInfos) {
7217 AllocationInfo &AI = *It.second;
7218 if (AI.Status == AllocationInfo::INVALID)
7219 continue;
7220
7221 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7222 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7223 if (!APAlign) {
7224 // Can't generate an alloca which respects the required alignment
7225 // on the allocation.
7226 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7227 << "\n");
7228 AI.Status = AllocationInfo::INVALID;
7230 continue;
7231 }
7232 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7233 !APAlign->isPowerOf2()) {
7234 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7235 << "\n");
7236 AI.Status = AllocationInfo::INVALID;
7238 continue;
7239 }
7240 }
7241
7242 std::optional<APInt> Size = getSize(A, *this, AI);
7243 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7244 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7245 LLVM_DEBUG({
7246 if (!Size)
7247 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7248 else
7249 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7250 << MaxHeapToStackSize << "\n";
7251 });
7252
7253 AI.Status = AllocationInfo::INVALID;
7255 continue;
7256 }
7257 }
7258
7259 switch (AI.Status) {
7260 case AllocationInfo::STACK_DUE_TO_USE:
7261 if (UsesCheck(AI))
7262 break;
7263 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7264 [[fallthrough]];
7265 case AllocationInfo::STACK_DUE_TO_FREE:
7266 if (FreeCheck(AI))
7267 break;
7268 AI.Status = AllocationInfo::INVALID;
7270 break;
7271 case AllocationInfo::INVALID:
7272 llvm_unreachable("Invalid allocations should never reach this point!");
7273 };
7274
7275 // Check if we still think we can move it into the entry block. If the
7276 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7277 // ignore the potential complications associated with loops.
7278 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7279 if (AI.MoveAllocaIntoEntry &&
7280 (!Size.has_value() ||
7281 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7282 AI.MoveAllocaIntoEntry = false;
7283 }
7284
7285 return Changed;
7286}
7287} // namespace
7288
7289/// ----------------------- Privatizable Pointers ------------------------------
7290namespace {
7291struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7292 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7293 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7294
7295 ChangeStatus indicatePessimisticFixpoint() override {
7296 AAPrivatizablePtr::indicatePessimisticFixpoint();
7297 PrivatizableType = nullptr;
7298 return ChangeStatus::CHANGED;
7299 }
7300
7301 /// Identify the type we can chose for a private copy of the underlying
7302 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7303 /// none.
7304 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7305
7306 /// Return a privatizable type that encloses both T0 and T1.
7307 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7308 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7309 std::optional<Type *> T1) {
7310 if (!T0)
7311 return T1;
7312 if (!T1)
7313 return T0;
7314 if (T0 == T1)
7315 return T0;
7316 return nullptr;
7317 }
7318
7319 std::optional<Type *> getPrivatizableType() const override {
7320 return PrivatizableType;
7321 }
7322
7323 const std::string getAsStr(Attributor *A) const override {
7324 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7325 }
7326
7327protected:
7328 std::optional<Type *> PrivatizableType;
7329};
7330
7331// TODO: Do this for call site arguments (probably also other values) as well.
7332
7333struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7334 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7335 : AAPrivatizablePtrImpl(IRP, A) {}
7336
7337 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7338 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7339 // If this is a byval argument and we know all the call sites (so we can
7340 // rewrite them), there is no need to check them explicitly.
7341 bool UsedAssumedInformation = false;
7343 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7344 /* IgnoreSubsumingPositions */ true);
7345 if (!Attrs.empty() &&
7346 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7347 true, UsedAssumedInformation))
7348 return Attrs[0].getValueAsType();
7349
7350 std::optional<Type *> Ty;
7351 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7352
7353 // Make sure the associated call site argument has the same type at all call
7354 // sites and it is an allocation we know is safe to privatize, for now that
7355 // means we only allow alloca instructions.
7356 // TODO: We can additionally analyze the accesses in the callee to create
7357 // the type from that information instead. That is a little more
7358 // involved and will be done in a follow up patch.
7359 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7360 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7361 // Check if a coresponding argument was found or if it is one not
7362 // associated (which can happen for callback calls).
7363 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7364 return false;
7365
7366 // Check that all call sites agree on a type.
7367 auto *PrivCSArgAA =
7368 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7369 if (!PrivCSArgAA)
7370 return false;
7371 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7372
7373 LLVM_DEBUG({
7374 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7375 if (CSTy && *CSTy)
7376 (*CSTy)->print(dbgs());
7377 else if (CSTy)
7378 dbgs() << "<nullptr>";
7379 else
7380 dbgs() << "<none>";
7381 });
7382
7383 Ty = combineTypes(Ty, CSTy);
7384
7385 LLVM_DEBUG({
7386 dbgs() << " : New Type: ";
7387 if (Ty && *Ty)
7388 (*Ty)->print(dbgs());
7389 else if (Ty)
7390 dbgs() << "<nullptr>";
7391 else
7392 dbgs() << "<none>";
7393 dbgs() << "\n";
7394 });
7395
7396 return !Ty || *Ty;
7397 };
7398
7399 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7400 UsedAssumedInformation))
7401 return nullptr;
7402 return Ty;
7403 }
7404
7405 /// See AbstractAttribute::updateImpl(...).
7406 ChangeStatus updateImpl(Attributor &A) override {
7407 PrivatizableType = identifyPrivatizableType(A);
7408 if (!PrivatizableType)
7409 return ChangeStatus::UNCHANGED;
7410 if (!*PrivatizableType)
7411 return indicatePessimisticFixpoint();
7412
7413 // The dependence is optional so we don't give up once we give up on the
7414 // alignment.
7415 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7416 DepClassTy::OPTIONAL);
7417
7418 // Avoid arguments with padding for now.
7419 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7420 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7421 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7422 return indicatePessimisticFixpoint();
7423 }
7424
7425 // Collect the types that will replace the privatizable type in the function
7426 // signature.
7427 SmallVector<Type *, 16> ReplacementTypes;
7428 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7429
7430 // Verify callee and caller agree on how the promoted argument would be
7431 // passed.
7432 Function &Fn = *getIRPosition().getAnchorScope();
7433 const auto *TTI =
7434 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7435 if (!TTI) {
7436 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7437 << Fn.getName() << "\n");
7438 return indicatePessimisticFixpoint();
7439 }
7440
7441 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7442 CallBase *CB = ACS.getInstruction();
7443 return TTI->areTypesABICompatible(
7444 CB->getCaller(),
7446 ReplacementTypes);
7447 };
7448 bool UsedAssumedInformation = false;
7449 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7450 UsedAssumedInformation)) {
7451 LLVM_DEBUG(
7452 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7453 << Fn.getName() << "\n");
7454 return indicatePessimisticFixpoint();
7455 }
7456
7457 // Register a rewrite of the argument.
7458 Argument *Arg = getAssociatedArgument();
7459 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7460 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7461 return indicatePessimisticFixpoint();
7462 }
7463
7464 unsigned ArgNo = Arg->getArgNo();
7465
7466 // Helper to check if for the given call site the associated argument is
7467 // passed to a callback where the privatization would be different.
7468 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7469 SmallVector<const Use *, 4> CallbackUses;
7470 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7471 for (const Use *U : CallbackUses) {
7472 AbstractCallSite CBACS(U);
7473 assert(CBACS && CBACS.isCallbackCall());
7474 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7475 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7476
7477 LLVM_DEBUG({
7478 dbgs()
7479 << "[AAPrivatizablePtr] Argument " << *Arg
7480 << "check if can be privatized in the context of its parent ("
7481 << Arg->getParent()->getName()
7482 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7483 "callback ("
7484 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7485 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7486 << CBACS.getCallArgOperand(CBArg) << " vs "
7487 << CB.getArgOperand(ArgNo) << "\n"
7488 << "[AAPrivatizablePtr] " << CBArg << " : "
7489 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7490 });
7491
7492 if (CBArgNo != int(ArgNo))
7493 continue;
7494 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7495 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7496 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7497 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7498 if (!CBArgPrivTy)
7499 continue;
7500 if (*CBArgPrivTy == PrivatizableType)
7501 continue;
7502 }
7503
7504 LLVM_DEBUG({
7505 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7506 << " cannot be privatized in the context of its parent ("
7507 << Arg->getParent()->getName()
7508 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7509 "callback ("
7510 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7511 << ").\n[AAPrivatizablePtr] for which the argument "
7512 "privatization is not compatible.\n";
7513 });
7514 return false;
7515 }
7516 }
7517 return true;
7518 };
7519
7520 // Helper to check if for the given call site the associated argument is
7521 // passed to a direct call where the privatization would be different.
7522 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7523 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7524 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7525 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7526 "Expected a direct call operand for callback call operand");
7527
7528 Function *DCCallee =
7530 LLVM_DEBUG({
7531 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7532 << " check if be privatized in the context of its parent ("
7533 << Arg->getParent()->getName()
7534 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7535 "direct call of ("
7536 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7537 });
7538
7539 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7540 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7541 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7542 DepClassTy::REQUIRED);
7543 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7544 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7545 if (!DCArgPrivTy)
7546 return true;
7547 if (*DCArgPrivTy == PrivatizableType)
7548 return true;
7549 }
7550 }
7551
7552 LLVM_DEBUG({
7553 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7554 << " cannot be privatized in the context of its parent ("
7555 << Arg->getParent()->getName()
7556 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7557 "direct call of ("
7559 << ").\n[AAPrivatizablePtr] for which the argument "
7560 "privatization is not compatible.\n";
7561 });
7562 return false;
7563 };
7564
7565 // Helper to check if the associated argument is used at the given abstract
7566 // call site in a way that is incompatible with the privatization assumed
7567 // here.
7568 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7569 if (ACS.isDirectCall())
7570 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7571 if (ACS.isCallbackCall())
7572 return IsCompatiblePrivArgOfDirectCS(ACS);
7573 return false;
7574 };
7575
7576 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7577 UsedAssumedInformation))
7578 return indicatePessimisticFixpoint();
7579
7580 return ChangeStatus::UNCHANGED;
7581 }
7582
7583 /// Given a type to private \p PrivType, collect the constituates (which are
7584 /// used) in \p ReplacementTypes.
7585 static void
7586 identifyReplacementTypes(Type *PrivType,
7587 SmallVectorImpl<Type *> &ReplacementTypes) {
7588 // TODO: For now we expand the privatization type to the fullest which can
7589 // lead to dead arguments that need to be removed later.
7590 assert(PrivType && "Expected privatizable type!");
7591
7592 // Traverse the type, extract constituate types on the outermost level.
7593 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7594 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7595 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7596 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7597 ReplacementTypes.append(PrivArrayType->getNumElements(),
7598 PrivArrayType->getElementType());
7599 } else {
7600 ReplacementTypes.push_back(PrivType);
7601 }
7602 }
7603
7604 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7605 /// The values needed are taken from the arguments of \p F starting at
7606 /// position \p ArgNo.
7607 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7608 unsigned ArgNo, BasicBlock::iterator IP) {
7609 assert(PrivType && "Expected privatizable type!");
7610
7611 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7612 const DataLayout &DL = F.getDataLayout();
7613
7614 // Traverse the type, build GEPs and stores.
7615 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7616 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7617 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7618 Value *Ptr =
7619 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7620 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7621 }
7622 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7623 Type *PointeeTy = PrivArrayType->getElementType();
7624 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7625 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7626 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7627 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7628 }
7629 } else {
7630 new StoreInst(F.getArg(ArgNo), &Base, IP);
7631 }
7632 }
7633
7634 /// Extract values from \p Base according to the type \p PrivType at the
7635 /// call position \p ACS. The values are appended to \p ReplacementValues.
7636 void createReplacementValues(Align Alignment, Type *PrivType,
7637 AbstractCallSite ACS, Value *Base,
7638 SmallVectorImpl<Value *> &ReplacementValues) {
7639 assert(Base && "Expected base value!");
7640 assert(PrivType && "Expected privatizable type!");
7641 Instruction *IP = ACS.getInstruction();
7642
7643 IRBuilder<NoFolder> IRB(IP);
7644 const DataLayout &DL = IP->getDataLayout();
7645
7646 // Traverse the type, build GEPs and loads.
7647 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7648 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7649 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7650 Type *PointeeTy = PrivStructType->getElementType(u);
7651 Value *Ptr =
7652 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7653 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7654 L->setAlignment(Alignment);
7655 ReplacementValues.push_back(L);
7656 }
7657 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7658 Type *PointeeTy = PrivArrayType->getElementType();
7659 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7660 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7661 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7662 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7663 L->setAlignment(Alignment);
7664 ReplacementValues.push_back(L);
7665 }
7666 } else {
7667 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7668 L->setAlignment(Alignment);
7669 ReplacementValues.push_back(L);
7670 }
7671 }
7672
7673 /// See AbstractAttribute::manifest(...)
7674 ChangeStatus manifest(Attributor &A) override {
7675 if (!PrivatizableType)
7676 return ChangeStatus::UNCHANGED;
7677 assert(*PrivatizableType && "Expected privatizable type!");
7678
7679 // Collect all tail calls in the function as we cannot allow new allocas to
7680 // escape into tail recursion.
7681 // TODO: Be smarter about new allocas escaping into tail calls.
7683 bool UsedAssumedInformation = false;
7684 if (!A.checkForAllInstructions(
7685 [&](Instruction &I) {
7686 CallInst &CI = cast<CallInst>(I);
7687 if (CI.isTailCall())
7688 TailCalls.push_back(&CI);
7689 return true;
7690 },
7691 *this, {Instruction::Call}, UsedAssumedInformation))
7692 return ChangeStatus::UNCHANGED;
7693
7694 Argument *Arg = getAssociatedArgument();
7695 // Query AAAlign attribute for alignment of associated argument to
7696 // determine the best alignment of loads.
7697 const auto *AlignAA =
7698 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7699
7700 // Callback to repair the associated function. A new alloca is placed at the
7701 // beginning and initialized with the values passed through arguments. The
7702 // new alloca replaces the use of the old pointer argument.
7704 [=](const Attributor::ArgumentReplacementInfo &ARI,
7705 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7706 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7708 const DataLayout &DL = IP->getDataLayout();
7709 unsigned AS = DL.getAllocaAddrSpace();
7710 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7711 Arg->getName() + ".priv", IP);
7712 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7713 ArgIt->getArgNo(), IP);
7714
7715 if (AI->getType() != Arg->getType())
7716 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7717 AI, Arg->getType(), "", IP);
7718 Arg->replaceAllUsesWith(AI);
7719
7720 for (CallInst *CI : TailCalls)
7721 CI->setTailCall(false);
7722 };
7723
7724 // Callback to repair a call site of the associated function. The elements
7725 // of the privatizable type are loaded prior to the call and passed to the
7726 // new function version.
7728 [=](const Attributor::ArgumentReplacementInfo &ARI,
7729 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7730 // When no alignment is specified for the load instruction,
7731 // natural alignment is assumed.
7732 createReplacementValues(
7733 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7734 *PrivatizableType, ACS,
7735 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7736 NewArgOperands);
7737 };
7738
7739 // Collect the types that will replace the privatizable type in the function
7740 // signature.
7741 SmallVector<Type *, 16> ReplacementTypes;
7742 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7743
7744 // Register a rewrite of the argument.
7745 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7746 std::move(FnRepairCB),
7747 std::move(ACSRepairCB)))
7748 return ChangeStatus::CHANGED;
7749 return ChangeStatus::UNCHANGED;
7750 }
7751
7752 /// See AbstractAttribute::trackStatistics()
7753 void trackStatistics() const override {
7754 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7755 }
7756};
7757
7758struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7759 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7760 : AAPrivatizablePtrImpl(IRP, A) {}
7761
7762 /// See AbstractAttribute::initialize(...).
7763 void initialize(Attributor &A) override {
7764 // TODO: We can privatize more than arguments.
7765 indicatePessimisticFixpoint();
7766 }
7767
7768 ChangeStatus updateImpl(Attributor &A) override {
7769 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7770 "updateImpl will not be called");
7771 }
7772
7773 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7774 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7775 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7776 if (!Obj) {
7777 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7778 return nullptr;
7779 }
7780
7781 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7782 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7783 if (CI->isOne())
7784 return AI->getAllocatedType();
7785 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7786 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7787 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7788 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7789 return PrivArgAA->getPrivatizableType();
7790 }
7791
7792 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7793 "alloca nor privatizable argument: "
7794 << *Obj << "!\n");
7795 return nullptr;
7796 }
7797
7798 /// See AbstractAttribute::trackStatistics()
7799 void trackStatistics() const override {
7800 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7801 }
7802};
7803
7804struct AAPrivatizablePtrCallSiteArgument final
7805 : public AAPrivatizablePtrFloating {
7806 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7807 : AAPrivatizablePtrFloating(IRP, A) {}
7808
7809 /// See AbstractAttribute::initialize(...).
7810 void initialize(Attributor &A) override {
7811 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7812 indicateOptimisticFixpoint();
7813 }
7814
7815 /// See AbstractAttribute::updateImpl(...).
7816 ChangeStatus updateImpl(Attributor &A) override {
7817 PrivatizableType = identifyPrivatizableType(A);
7818 if (!PrivatizableType)
7819 return ChangeStatus::UNCHANGED;
7820 if (!*PrivatizableType)
7821 return indicatePessimisticFixpoint();
7822
7823 const IRPosition &IRP = getIRPosition();
7824 bool IsKnownNoCapture;
7825 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7826 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7827 if (!IsAssumedNoCapture) {
7828 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7829 return indicatePessimisticFixpoint();
7830 }
7831
7832 bool IsKnownNoAlias;
7834 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7835 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7836 return indicatePessimisticFixpoint();
7837 }
7838
7839 bool IsKnown;
7840 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7841 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7842 return indicatePessimisticFixpoint();
7843 }
7844
7845 return ChangeStatus::UNCHANGED;
7846 }
7847
7848 /// See AbstractAttribute::trackStatistics()
7849 void trackStatistics() const override {
7850 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7851 }
7852};
7853
7854struct AAPrivatizablePtrCallSiteReturned final
7855 : public AAPrivatizablePtrFloating {
7856 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7857 : AAPrivatizablePtrFloating(IRP, A) {}
7858
7859 /// See AbstractAttribute::initialize(...).
7860 void initialize(Attributor &A) override {
7861 // TODO: We can privatize more than arguments.
7862 indicatePessimisticFixpoint();
7863 }
7864
7865 /// See AbstractAttribute::trackStatistics()
7866 void trackStatistics() const override {
7867 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7868 }
7869};
7870
7871struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7872 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7873 : AAPrivatizablePtrFloating(IRP, A) {}
7874
7875 /// See AbstractAttribute::initialize(...).
7876 void initialize(Attributor &A) override {
7877 // TODO: We can privatize more than arguments.
7878 indicatePessimisticFixpoint();
7879 }
7880
7881 /// See AbstractAttribute::trackStatistics()
7882 void trackStatistics() const override {
7883 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7884 }
7885};
7886} // namespace
7887
7888/// -------------------- Memory Behavior Attributes ----------------------------
7889/// Includes read-none, read-only, and write-only.
7890/// ----------------------------------------------------------------------------
7891namespace {
7892struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7893 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7894 : AAMemoryBehavior(IRP, A) {}
7895
7896 /// See AbstractAttribute::initialize(...).
7897 void initialize(Attributor &A) override {
7898 intersectAssumedBits(BEST_STATE);
7899 getKnownStateFromValue(A, getIRPosition(), getState());
7900 AAMemoryBehavior::initialize(A);
7901 }
7902
7903 /// Return the memory behavior information encoded in the IR for \p IRP.
7904 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7905 BitIntegerState &State,
7906 bool IgnoreSubsumingPositions = false) {
7908 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7909 for (const Attribute &Attr : Attrs) {
7910 switch (Attr.getKindAsEnum()) {
7911 case Attribute::ReadNone:
7912 State.addKnownBits(NO_ACCESSES);
7913 break;
7914 case Attribute::ReadOnly:
7915 State.addKnownBits(NO_WRITES);
7916 break;
7917 case Attribute::WriteOnly:
7918 State.addKnownBits(NO_READS);
7919 break;
7920 default:
7921 llvm_unreachable("Unexpected attribute!");
7922 }
7923 }
7924
7925 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7926 if (!I->mayReadFromMemory())
7927 State.addKnownBits(NO_READS);
7928 if (!I->mayWriteToMemory())
7929 State.addKnownBits(NO_WRITES);
7930 }
7931 }
7932
7933 /// See AbstractAttribute::getDeducedAttributes(...).
7934 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7935 SmallVectorImpl<Attribute> &Attrs) const override {
7936 assert(Attrs.size() == 0);
7937 if (isAssumedReadNone())
7938 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7939 else if (isAssumedReadOnly())
7940 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7941 else if (isAssumedWriteOnly())
7942 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7943 assert(Attrs.size() <= 1);
7944 }
7945
7946 /// See AbstractAttribute::manifest(...).
7947 ChangeStatus manifest(Attributor &A) override {
7948 const IRPosition &IRP = getIRPosition();
7949
7950 if (A.hasAttr(IRP, Attribute::ReadNone,
7951 /* IgnoreSubsumingPositions */ true))
7952 return ChangeStatus::UNCHANGED;
7953
7954 // Check if we would improve the existing attributes first.
7955 SmallVector<Attribute, 4> DeducedAttrs;
7956 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7957 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7958 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7959 /* IgnoreSubsumingPositions */ true);
7960 }))
7961 return ChangeStatus::UNCHANGED;
7962
7963 // Clear existing attributes.
7964 A.removeAttrs(IRP, AttrKinds);
7965 // Clear conflicting writable attribute.
7966 if (isAssumedReadOnly())
7967 A.removeAttrs(IRP, Attribute::Writable);
7968
7969 // Use the generic manifest method.
7970 return IRAttribute::manifest(A);
7971 }
7972
7973 /// See AbstractState::getAsStr().
7974 const std::string getAsStr(Attributor *A) const override {
7975 if (isAssumedReadNone())
7976 return "readnone";
7977 if (isAssumedReadOnly())
7978 return "readonly";
7979 if (isAssumedWriteOnly())
7980 return "writeonly";
7981 return "may-read/write";
7982 }
7983
7984 /// The set of IR attributes AAMemoryBehavior deals with.
7985 static const Attribute::AttrKind AttrKinds[3];
7986};
7987
7988const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7989 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7990
7991/// Memory behavior attribute for a floating value.
7992struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7993 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7994 : AAMemoryBehaviorImpl(IRP, A) {}
7995
7996 /// See AbstractAttribute::updateImpl(...).
7997 ChangeStatus updateImpl(Attributor &A) override;
7998
7999 /// See AbstractAttribute::trackStatistics()
8000 void trackStatistics() const override {
8001 if (isAssumedReadNone())
8003 else if (isAssumedReadOnly())
8005 else if (isAssumedWriteOnly())
8007 }
8008
8009private:
8010 /// Return true if users of \p UserI might access the underlying
8011 /// variable/location described by \p U and should therefore be analyzed.
8012 bool followUsersOfUseIn(Attributor &A, const Use &U,
8013 const Instruction *UserI);
8014
8015 /// Update the state according to the effect of use \p U in \p UserI.
8016 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8017};
8018
8019/// Memory behavior attribute for function argument.
8020struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8021 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8022 : AAMemoryBehaviorFloating(IRP, A) {}
8023
8024 /// See AbstractAttribute::initialize(...).
8025 void initialize(Attributor &A) override {
8026 intersectAssumedBits(BEST_STATE);
8027 const IRPosition &IRP = getIRPosition();
8028 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8029 // can query it when we use has/getAttr. That would allow us to reuse the
8030 // initialize of the base class here.
8031 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8032 /* IgnoreSubsumingPositions */ true);
8033 getKnownStateFromValue(A, IRP, getState(),
8034 /* IgnoreSubsumingPositions */ HasByVal);
8035 }
8036
8037 ChangeStatus manifest(Attributor &A) override {
8038 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8039 if (!getAssociatedValue().getType()->isPointerTy())
8040 return ChangeStatus::UNCHANGED;
8041
8042 // TODO: From readattrs.ll: "inalloca parameters are always
8043 // considered written"
8044 if (A.hasAttr(getIRPosition(),
8045 {Attribute::InAlloca, Attribute::Preallocated})) {
8046 removeKnownBits(NO_WRITES);
8047 removeAssumedBits(NO_WRITES);
8048 }
8049 A.removeAttrs(getIRPosition(), AttrKinds);
8050 return AAMemoryBehaviorFloating::manifest(A);
8051 }
8052
8053 /// See AbstractAttribute::trackStatistics()
8054 void trackStatistics() const override {
8055 if (isAssumedReadNone())
8056 STATS_DECLTRACK_ARG_ATTR(readnone)
8057 else if (isAssumedReadOnly())
8058 STATS_DECLTRACK_ARG_ATTR(readonly)
8059 else if (isAssumedWriteOnly())
8060 STATS_DECLTRACK_ARG_ATTR(writeonly)
8061 }
8062};
8063
8064struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8065 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8066 : AAMemoryBehaviorArgument(IRP, A) {}
8067
8068 /// See AbstractAttribute::initialize(...).
8069 void initialize(Attributor &A) override {
8070 // If we don't have an associated attribute this is either a variadic call
8071 // or an indirect call, either way, nothing to do here.
8072 Argument *Arg = getAssociatedArgument();
8073 if (!Arg) {
8074 indicatePessimisticFixpoint();
8075 return;
8076 }
8077 if (Arg->hasByValAttr()) {
8078 addKnownBits(NO_WRITES);
8079 removeKnownBits(NO_READS);
8080 removeAssumedBits(NO_READS);
8081 }
8082 AAMemoryBehaviorArgument::initialize(A);
8083 if (getAssociatedFunction()->isDeclaration())
8084 indicatePessimisticFixpoint();
8085 }
8086
8087 /// See AbstractAttribute::updateImpl(...).
8088 ChangeStatus updateImpl(Attributor &A) override {
8089 // TODO: Once we have call site specific value information we can provide
8090 // call site specific liveness liveness information and then it makes
8091 // sense to specialize attributes for call sites arguments instead of
8092 // redirecting requests to the callee argument.
8093 Argument *Arg = getAssociatedArgument();
8094 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8095 auto *ArgAA =
8096 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8097 if (!ArgAA)
8098 return indicatePessimisticFixpoint();
8099 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8100 }
8101
8102 /// See AbstractAttribute::trackStatistics()
8103 void trackStatistics() const override {
8104 if (isAssumedReadNone())
8106 else if (isAssumedReadOnly())
8108 else if (isAssumedWriteOnly())
8110 }
8111};
8112
8113/// Memory behavior attribute for a call site return position.
8114struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8115 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8116 : AAMemoryBehaviorFloating(IRP, A) {}
8117
8118 /// See AbstractAttribute::initialize(...).
8119 void initialize(Attributor &A) override {
8120 AAMemoryBehaviorImpl::initialize(A);
8121 }
8122 /// See AbstractAttribute::manifest(...).
8123 ChangeStatus manifest(Attributor &A) override {
8124 // We do not annotate returned values.
8125 return ChangeStatus::UNCHANGED;
8126 }
8127
8128 /// See AbstractAttribute::trackStatistics()
8129 void trackStatistics() const override {}
8130};
8131
8132/// An AA to represent the memory behavior function attributes.
8133struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8134 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8135 : AAMemoryBehaviorImpl(IRP, A) {}
8136
8137 /// See AbstractAttribute::updateImpl(Attributor &A).
8138 ChangeStatus updateImpl(Attributor &A) override;
8139
8140 /// See AbstractAttribute::manifest(...).
8141 ChangeStatus manifest(Attributor &A) override {
8142 // TODO: It would be better to merge this with AAMemoryLocation, so that
8143 // we could determine read/write per location. This would also have the
8144 // benefit of only one place trying to manifest the memory attribute.
8145 Function &F = cast<Function>(getAnchorValue());
8147 if (isAssumedReadNone())
8148 ME = MemoryEffects::none();
8149 else if (isAssumedReadOnly())
8151 else if (isAssumedWriteOnly())
8153
8154 A.removeAttrs(getIRPosition(), AttrKinds);
8155 // Clear conflicting writable attribute.
8156 if (ME.onlyReadsMemory())
8157 for (Argument &Arg : F.args())
8158 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8159 return A.manifestAttrs(getIRPosition(),
8160 Attribute::getWithMemoryEffects(F.getContext(), ME));
8161 }
8162
8163 /// See AbstractAttribute::trackStatistics()
8164 void trackStatistics() const override {
8165 if (isAssumedReadNone())
8166 STATS_DECLTRACK_FN_ATTR(readnone)
8167 else if (isAssumedReadOnly())
8168 STATS_DECLTRACK_FN_ATTR(readonly)
8169 else if (isAssumedWriteOnly())
8170 STATS_DECLTRACK_FN_ATTR(writeonly)
8171 }
8172};
8173
8174/// AAMemoryBehavior attribute for call sites.
8175struct AAMemoryBehaviorCallSite final
8176 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8177 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8178 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8179
8180 /// See AbstractAttribute::manifest(...).
8181 ChangeStatus manifest(Attributor &A) override {
8182 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8183 CallBase &CB = cast<CallBase>(getAnchorValue());
8185 if (isAssumedReadNone())
8186 ME = MemoryEffects::none();
8187 else if (isAssumedReadOnly())
8189 else if (isAssumedWriteOnly())
8191
8192 A.removeAttrs(getIRPosition(), AttrKinds);
8193 // Clear conflicting writable attribute.
8194 if (ME.onlyReadsMemory())
8195 for (Use &U : CB.args())
8196 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8197 Attribute::Writable);
8198 return A.manifestAttrs(
8199 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8200 }
8201
8202 /// See AbstractAttribute::trackStatistics()
8203 void trackStatistics() const override {
8204 if (isAssumedReadNone())
8205 STATS_DECLTRACK_CS_ATTR(readnone)
8206 else if (isAssumedReadOnly())
8207 STATS_DECLTRACK_CS_ATTR(readonly)
8208 else if (isAssumedWriteOnly())
8209 STATS_DECLTRACK_CS_ATTR(writeonly)
8210 }
8211};
8212
8213ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8214
8215 // The current assumed state used to determine a change.
8216 auto AssumedState = getAssumed();
8217
8218 auto CheckRWInst = [&](Instruction &I) {
8219 // If the instruction has an own memory behavior state, use it to restrict
8220 // the local state. No further analysis is required as the other memory
8221 // state is as optimistic as it gets.
8222 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8223 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8225 if (MemBehaviorAA) {
8226 intersectAssumedBits(MemBehaviorAA->getAssumed());
8227 return !isAtFixpoint();
8228 }
8229 }
8230
8231 // Remove access kind modifiers if necessary.
8232 if (I.mayReadFromMemory())
8233 removeAssumedBits(NO_READS);
8234 if (I.mayWriteToMemory())
8235 removeAssumedBits(NO_WRITES);
8236 return !isAtFixpoint();
8237 };
8238
8239 bool UsedAssumedInformation = false;
8240 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8241 UsedAssumedInformation))
8242 return indicatePessimisticFixpoint();
8243
8244 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8246}
8247
8248ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8249
8250 const IRPosition &IRP = getIRPosition();
8251 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8252 AAMemoryBehavior::StateType &S = getState();
8253
8254 // First, check the function scope. We take the known information and we avoid
8255 // work if the assumed information implies the current assumed information for
8256 // this attribute. This is a valid for all but byval arguments.
8257 Argument *Arg = IRP.getAssociatedArgument();
8258 AAMemoryBehavior::base_t FnMemAssumedState =
8260 if (!Arg || !Arg->hasByValAttr()) {
8261 const auto *FnMemAA =
8262 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8263 if (FnMemAA) {
8264 FnMemAssumedState = FnMemAA->getAssumed();
8265 S.addKnownBits(FnMemAA->getKnown());
8266 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8268 }
8269 }
8270
8271 // The current assumed state used to determine a change.
8272 auto AssumedState = S.getAssumed();
8273
8274 // Make sure the value is not captured (except through "return"), if
8275 // it is, any information derived would be irrelevant anyway as we cannot
8276 // check the potential aliases introduced by the capture. However, no need
8277 // to fall back to anythign less optimistic than the function state.
8278 bool IsKnownNoCapture;
8279 const AANoCapture *ArgNoCaptureAA = nullptr;
8280 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8281 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8282 &ArgNoCaptureAA);
8283
8284 if (!IsAssumedNoCapture &&
8285 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8286 S.intersectAssumedBits(FnMemAssumedState);
8287 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8289 }
8290
8291 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8292 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8293 Instruction *UserI = cast<Instruction>(U.getUser());
8294 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8295 << " \n");
8296
8297 // Droppable users, e.g., llvm::assume does not actually perform any action.
8298 if (UserI->isDroppable())
8299 return true;
8300
8301 // Check if the users of UserI should also be visited.
8302 Follow = followUsersOfUseIn(A, U, UserI);
8303
8304 // If UserI might touch memory we analyze the use in detail.
8305 if (UserI->mayReadOrWriteMemory())
8306 analyzeUseIn(A, U, UserI);
8307
8308 return !isAtFixpoint();
8309 };
8310
8311 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8312 return indicatePessimisticFixpoint();
8313
8314 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8316}
8317
8318bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8319 const Instruction *UserI) {
8320 // The loaded value is unrelated to the pointer argument, no need to
8321 // follow the users of the load.
8322 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8323 return false;
8324
8325 // By default we follow all uses assuming UserI might leak information on U,
8326 // we have special handling for call sites operands though.
8327 const auto *CB = dyn_cast<CallBase>(UserI);
8328 if (!CB || !CB->isArgOperand(&U))
8329 return true;
8330
8331 // If the use is a call argument known not to be captured, the users of
8332 // the call do not need to be visited because they have to be unrelated to
8333 // the input. Note that this check is not trivial even though we disallow
8334 // general capturing of the underlying argument. The reason is that the
8335 // call might the argument "through return", which we allow and for which we
8336 // need to check call users.
8337 if (U.get()->getType()->isPointerTy()) {
8338 unsigned ArgNo = CB->getArgOperandNo(&U);
8339 bool IsKnownNoCapture;
8341 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8342 DepClassTy::OPTIONAL, IsKnownNoCapture);
8343 }
8344
8345 return true;
8346}
8347
8348void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8349 const Instruction *UserI) {
8350 assert(UserI->mayReadOrWriteMemory());
8351
8352 switch (UserI->getOpcode()) {
8353 default:
8354 // TODO: Handle all atomics and other side-effect operations we know of.
8355 break;
8356 case Instruction::Load:
8357 // Loads cause the NO_READS property to disappear.
8358 removeAssumedBits(NO_READS);
8359 return;
8360
8361 case Instruction::Store:
8362 // Stores cause the NO_WRITES property to disappear if the use is the
8363 // pointer operand. Note that while capturing was taken care of somewhere
8364 // else we need to deal with stores of the value that is not looked through.
8365 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8366 removeAssumedBits(NO_WRITES);
8367 else
8368 indicatePessimisticFixpoint();
8369 return;
8370
8371 case Instruction::Call:
8372 case Instruction::CallBr:
8373 case Instruction::Invoke: {
8374 // For call sites we look at the argument memory behavior attribute (this
8375 // could be recursive!) in order to restrict our own state.
8376 const auto *CB = cast<CallBase>(UserI);
8377
8378 // Give up on operand bundles.
8379 if (CB->isBundleOperand(&U)) {
8380 indicatePessimisticFixpoint();
8381 return;
8382 }
8383
8384 // Calling a function does read the function pointer, maybe write it if the
8385 // function is self-modifying.
8386 if (CB->isCallee(&U)) {
8387 removeAssumedBits(NO_READS);
8388 break;
8389 }
8390
8391 // Adjust the possible access behavior based on the information on the
8392 // argument.
8393 IRPosition Pos;
8394 if (U.get()->getType()->isPointerTy())
8396 else
8398 const auto *MemBehaviorAA =
8399 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8400 if (!MemBehaviorAA)
8401 break;
8402 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8403 // and at least "known".
8404 intersectAssumedBits(MemBehaviorAA->getAssumed());
8405 return;
8406 }
8407 };
8408
8409 // Generally, look at the "may-properties" and adjust the assumed state if we
8410 // did not trigger special handling before.
8411 if (UserI->mayReadFromMemory())
8412 removeAssumedBits(NO_READS);
8413 if (UserI->mayWriteToMemory())
8414 removeAssumedBits(NO_WRITES);
8415}
8416} // namespace
8417
8418/// -------------------- Memory Locations Attributes ---------------------------
8419/// Includes read-none, argmemonly, inaccessiblememonly,
8420/// inaccessiblememorargmemonly
8421/// ----------------------------------------------------------------------------
8422
8425 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8426 return "all memory";
8428 return "no memory";
8429 std::string S = "memory:";
8430 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8431 S += "stack,";
8432 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8433 S += "constant,";
8435 S += "internal global,";
8437 S += "external global,";
8438 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8439 S += "argument,";
8441 S += "inaccessible,";
8442 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8443 S += "malloced,";
8444 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8445 S += "unknown,";
8446 S.pop_back();
8447 return S;
8448}
8449
8450namespace {
8451struct AAMemoryLocationImpl : public AAMemoryLocation {
8452
8453 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8454 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8455 AccessKind2Accesses.fill(nullptr);
8456 }
8457
8458 ~AAMemoryLocationImpl() override {
8459 // The AccessSets are allocated via a BumpPtrAllocator, we call
8460 // the destructor manually.
8461 for (AccessSet *AS : AccessKind2Accesses)
8462 if (AS)
8463 AS->~AccessSet();
8464 }
8465
8466 /// See AbstractAttribute::initialize(...).
8467 void initialize(Attributor &A) override {
8468 intersectAssumedBits(BEST_STATE);
8469 getKnownStateFromValue(A, getIRPosition(), getState());
8470 AAMemoryLocation::initialize(A);
8471 }
8472
8473 /// Return the memory behavior information encoded in the IR for \p IRP.
8474 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8475 BitIntegerState &State,
8476 bool IgnoreSubsumingPositions = false) {
8477 // For internal functions we ignore `argmemonly` and
8478 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8479 // constant propagation. It is unclear if this is the best way but it is
8480 // unlikely this will cause real performance problems. If we are deriving
8481 // attributes for the anchor function we even remove the attribute in
8482 // addition to ignoring it.
8483 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8484 // MemoryEffects::Other as a possible location.
8485 bool UseArgMemOnly = true;
8486 Function *AnchorFn = IRP.getAnchorScope();
8487 if (AnchorFn && A.isRunOn(*AnchorFn))
8488 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8489
8491 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8492 for (const Attribute &Attr : Attrs) {
8493 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8494 MemoryEffects ME = Attr.getMemoryEffects();
8495 if (ME.doesNotAccessMemory()) {
8496 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8497 continue;
8498 }
8499 if (ME.onlyAccessesInaccessibleMem()) {
8500 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8501 continue;
8502 }
8503 if (ME.onlyAccessesArgPointees()) {
8504 if (UseArgMemOnly)
8505 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8506 else {
8507 // Remove location information, only keep read/write info.
8508 ME = MemoryEffects(ME.getModRef());
8509 A.manifestAttrs(IRP,
8510 Attribute::getWithMemoryEffects(
8511 IRP.getAnchorValue().getContext(), ME),
8512 /*ForceReplace*/ true);
8513 }
8514 continue;
8515 }
8517 if (UseArgMemOnly)
8518 State.addKnownBits(inverseLocation(
8519 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8520 else {
8521 // Remove location information, only keep read/write info.
8522 ME = MemoryEffects(ME.getModRef());
8523 A.manifestAttrs(IRP,
8524 Attribute::getWithMemoryEffects(
8525 IRP.getAnchorValue().getContext(), ME),
8526 /*ForceReplace*/ true);
8527 }
8528 continue;
8529 }
8530 }
8531 }
8532
8533 /// See AbstractAttribute::getDeducedAttributes(...).
8534 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8535 SmallVectorImpl<Attribute> &Attrs) const override {
8536 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8537 assert(Attrs.size() == 0);
8538 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8539 if (isAssumedReadNone())
8540 Attrs.push_back(
8541 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8542 else if (isAssumedInaccessibleMemOnly())
8543 Attrs.push_back(Attribute::getWithMemoryEffects(
8545 else if (isAssumedArgMemOnly())
8546 Attrs.push_back(
8547 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8548 else if (isAssumedInaccessibleOrArgMemOnly())
8549 Attrs.push_back(Attribute::getWithMemoryEffects(
8551 }
8552 assert(Attrs.size() <= 1);
8553 }
8554
8555 /// See AbstractAttribute::manifest(...).
8556 ChangeStatus manifest(Attributor &A) override {
8557 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8558 // provide per-location modref information here.
8559 const IRPosition &IRP = getIRPosition();
8560
8561 SmallVector<Attribute, 1> DeducedAttrs;
8562 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8563 if (DeducedAttrs.size() != 1)
8564 return ChangeStatus::UNCHANGED;
8565 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8566
8567 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8568 IRP.getAnchorValue().getContext(), ME));
8569 }
8570
8571 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8572 bool checkForAllAccessesToMemoryKind(
8573 function_ref<bool(const Instruction *, const Value *, AccessKind,
8574 MemoryLocationsKind)>
8575 Pred,
8576 MemoryLocationsKind RequestedMLK) const override {
8577 if (!isValidState())
8578 return false;
8579
8580 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8581 if (AssumedMLK == NO_LOCATIONS)
8582 return true;
8583
8584 unsigned Idx = 0;
8585 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8586 CurMLK *= 2, ++Idx) {
8587 if (CurMLK & RequestedMLK)
8588 continue;
8589
8590 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8591 for (const AccessInfo &AI : *Accesses)
8592 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8593 return false;
8594 }
8595
8596 return true;
8597 }
8598
8599 ChangeStatus indicatePessimisticFixpoint() override {
8600 // If we give up and indicate a pessimistic fixpoint this instruction will
8601 // become an access for all potential access kinds:
8602 // TODO: Add pointers for argmemonly and globals to improve the results of
8603 // checkForAllAccessesToMemoryKind.
8604 bool Changed = false;
8605 MemoryLocationsKind KnownMLK = getKnown();
8606 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8607 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8608 if (!(CurMLK & KnownMLK))
8609 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8610 getAccessKindFromInst(I));
8611 return AAMemoryLocation::indicatePessimisticFixpoint();
8612 }
8613
8614protected:
8615 /// Helper struct to tie together an instruction that has a read or write
8616 /// effect with the pointer it accesses (if any).
8617 struct AccessInfo {
8618
8619 /// The instruction that caused the access.
8620 const Instruction *I;
8621
8622 /// The base pointer that is accessed, or null if unknown.
8623 const Value *Ptr;
8624
8625 /// The kind of access (read/write/read+write).
8627
8628 bool operator==(const AccessInfo &RHS) const {
8629 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8630 }
8631 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8632 if (LHS.I != RHS.I)
8633 return LHS.I < RHS.I;
8634 if (LHS.Ptr != RHS.Ptr)
8635 return LHS.Ptr < RHS.Ptr;
8636 if (LHS.Kind != RHS.Kind)
8637 return LHS.Kind < RHS.Kind;
8638 return false;
8639 }
8640 };
8641
8642 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8643 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8644 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8645 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8646 AccessKind2Accesses;
8647
8648 /// Categorize the pointer arguments of CB that might access memory in
8649 /// AccessedLoc and update the state and access map accordingly.
8650 void
8651 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8652 AAMemoryLocation::StateType &AccessedLocs,
8653 bool &Changed);
8654
8655 /// Return the kind(s) of location that may be accessed by \p V.
8657 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8658
8659 /// Return the access kind as determined by \p I.
8660 AccessKind getAccessKindFromInst(const Instruction *I) {
8661 AccessKind AK = READ_WRITE;
8662 if (I) {
8663 AK = I->mayReadFromMemory() ? READ : NONE;
8664 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8665 }
8666 return AK;
8667 }
8668
8669 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8670 /// an access of kind \p AK to a \p MLK memory location with the access
8671 /// pointer \p Ptr.
8672 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8673 MemoryLocationsKind MLK, const Instruction *I,
8674 const Value *Ptr, bool &Changed,
8675 AccessKind AK = READ_WRITE) {
8676
8677 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8678 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8679 if (!Accesses)
8680 Accesses = new (Allocator) AccessSet();
8681 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8682 if (MLK == NO_UNKOWN_MEM)
8683 MLK = NO_LOCATIONS;
8684 State.removeAssumedBits(MLK);
8685 }
8686
8687 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8688 /// arguments, and update the state and access map accordingly.
8689 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8690 AAMemoryLocation::StateType &State, bool &Changed,
8691 unsigned AccessAS = 0);
8692
8693 /// Used to allocate access sets.
8695};
8696
8697void AAMemoryLocationImpl::categorizePtrValue(
8698 Attributor &A, const Instruction &I, const Value &Ptr,
8699 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8700 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8701 << Ptr << " ["
8702 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8703
8704 auto Pred = [&](Value &Obj) {
8705 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8706 // TODO: recognize the TBAA used for constant accesses.
8707 MemoryLocationsKind MLK = NO_LOCATIONS;
8708
8709 // Filter accesses to constant (GPU) memory if we have an AS at the access
8710 // site or the object is known to actually have the associated AS.
8711 if (AA::isGPU(A.getModule())) {
8712 if (AA::isGPUConstantAddressSpace(A.getModule(), AccessAS) ||
8713 (AA::isGPUConstantAddressSpace(A.getModule(), ObjectAS) &&
8714 isIdentifiedObject(&Obj)))
8715 return true;
8716 }
8717
8718 if (isa<UndefValue>(&Obj))
8719 return true;
8720 if (isa<Argument>(&Obj)) {
8721 // TODO: For now we do not treat byval arguments as local copies performed
8722 // on the call edge, though, we should. To make that happen we need to
8723 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8724 // would also allow us to mark functions only accessing byval arguments as
8725 // readnone again, arguably their accesses have no effect outside of the
8726 // function, like accesses to allocas.
8727 MLK = NO_ARGUMENT_MEM;
8728 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8729 // Reading constant memory is not treated as a read "effect" by the
8730 // function attr pass so we won't neither. Constants defined by TBAA are
8731 // similar. (We know we do not write it because it is constant.)
8732 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8733 if (GVar->isConstant())
8734 return true;
8735
8736 if (GV->hasLocalLinkage())
8737 MLK = NO_GLOBAL_INTERNAL_MEM;
8738 else
8739 MLK = NO_GLOBAL_EXTERNAL_MEM;
8740 } else if (isa<ConstantPointerNull>(&Obj) &&
8741 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8742 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8743 return true;
8744 } else if (isa<AllocaInst>(&Obj)) {
8745 MLK = NO_LOCAL_MEM;
8746 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8747 bool IsKnownNoAlias;
8750 IsKnownNoAlias))
8751 MLK = NO_MALLOCED_MEM;
8752 else
8753 MLK = NO_UNKOWN_MEM;
8754 } else {
8755 MLK = NO_UNKOWN_MEM;
8756 }
8757
8758 assert(MLK != NO_LOCATIONS && "No location specified!");
8759 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8760 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8761 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8762 getAccessKindFromInst(&I));
8763
8764 return true;
8765 };
8766
8767 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8769 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8770 LLVM_DEBUG(
8771 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8772 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8773 getAccessKindFromInst(&I));
8774 return;
8775 }
8776
8777 LLVM_DEBUG(
8778 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8779 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8780}
8781
8782void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8783 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8784 bool &Changed) {
8785 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8786
8787 // Skip non-pointer arguments.
8788 const Value *ArgOp = CB.getArgOperand(ArgNo);
8789 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8790 continue;
8791
8792 // Skip readnone arguments.
8793 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8794 const auto *ArgOpMemLocationAA =
8795 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8796
8797 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8798 continue;
8799
8800 // Categorize potentially accessed pointer arguments as if there was an
8801 // access instruction with them as pointer.
8802 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8803 }
8804}
8805
8807AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8808 bool &Changed) {
8809 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8810 << I << "\n");
8811
8812 AAMemoryLocation::StateType AccessedLocs;
8813 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8814
8815 if (auto *CB = dyn_cast<CallBase>(&I)) {
8816
8817 // First check if we assume any memory is access is visible.
8818 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8820 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8821 << " [" << CBMemLocationAA << "]\n");
8822 if (!CBMemLocationAA) {
8823 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8824 Changed, getAccessKindFromInst(&I));
8825 return NO_UNKOWN_MEM;
8826 }
8827
8828 if (CBMemLocationAA->isAssumedReadNone())
8829 return NO_LOCATIONS;
8830
8831 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8832 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8833 Changed, getAccessKindFromInst(&I));
8834 return AccessedLocs.getAssumed();
8835 }
8836
8837 uint32_t CBAssumedNotAccessedLocs =
8838 CBMemLocationAA->getAssumedNotAccessedLocation();
8839
8840 // Set the argmemonly and global bit as we handle them separately below.
8841 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8842 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8843
8844 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8845 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8846 continue;
8847 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8848 getAccessKindFromInst(&I));
8849 }
8850
8851 // Now handle global memory if it might be accessed. This is slightly tricky
8852 // as NO_GLOBAL_MEM has multiple bits set.
8853 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8854 if (HasGlobalAccesses) {
8855 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8856 AccessKind Kind, MemoryLocationsKind MLK) {
8857 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8858 getAccessKindFromInst(&I));
8859 return true;
8860 };
8861 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8862 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8863 return AccessedLocs.getWorstState();
8864 }
8865
8866 LLVM_DEBUG(
8867 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8868 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8869
8870 // Now handle argument memory if it might be accessed.
8871 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8872 if (HasArgAccesses)
8873 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8874
8875 LLVM_DEBUG(
8876 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8877 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8878
8879 return AccessedLocs.getAssumed();
8880 }
8881
8882 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8883 LLVM_DEBUG(
8884 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8885 << I << " [" << *Ptr << "]\n");
8886 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8887 Ptr->getType()->getPointerAddressSpace());
8888 return AccessedLocs.getAssumed();
8889 }
8890
8891 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8892 << I << "\n");
8893 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8894 getAccessKindFromInst(&I));
8895 return AccessedLocs.getAssumed();
8896}
8897
8898/// An AA to represent the memory behavior function attributes.
8899struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8900 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8901 : AAMemoryLocationImpl(IRP, A) {}
8902
8903 /// See AbstractAttribute::updateImpl(Attributor &A).
8904 ChangeStatus updateImpl(Attributor &A) override {
8905
8906 const auto *MemBehaviorAA =
8907 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8908 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8909 if (MemBehaviorAA->isKnownReadNone())
8910 return indicateOptimisticFixpoint();
8912 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8913 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8914 return ChangeStatus::UNCHANGED;
8915 }
8916
8917 // The current assumed state used to determine a change.
8918 auto AssumedState = getAssumed();
8919 bool Changed = false;
8920
8921 auto CheckRWInst = [&](Instruction &I) {
8922 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8923 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8924 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8925 removeAssumedBits(inverseLocation(MLK, false, false));
8926 // Stop once only the valid bit set in the *not assumed location*, thus
8927 // once we don't actually exclude any memory locations in the state.
8928 return getAssumedNotAccessedLocation() != VALID_STATE;
8929 };
8930
8931 bool UsedAssumedInformation = false;
8932 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8933 UsedAssumedInformation))
8934 return indicatePessimisticFixpoint();
8935
8936 Changed |= AssumedState != getAssumed();
8937 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8938 }
8939
8940 /// See AbstractAttribute::trackStatistics()
8941 void trackStatistics() const override {
8942 if (isAssumedReadNone())
8943 STATS_DECLTRACK_FN_ATTR(readnone)
8944 else if (isAssumedArgMemOnly())
8945 STATS_DECLTRACK_FN_ATTR(argmemonly)
8946 else if (isAssumedInaccessibleMemOnly())
8947 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8948 else if (isAssumedInaccessibleOrArgMemOnly())
8949 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8950 }
8951};
8952
8953/// AAMemoryLocation attribute for call sites.
8954struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8955 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8956 : AAMemoryLocationImpl(IRP, A) {}
8957
8958 /// See AbstractAttribute::updateImpl(...).
8959 ChangeStatus updateImpl(Attributor &A) override {
8960 // TODO: Once we have call site specific value information we can provide
8961 // call site specific liveness liveness information and then it makes
8962 // sense to specialize attributes for call sites arguments instead of
8963 // redirecting requests to the callee argument.
8964 Function *F = getAssociatedFunction();
8965 const IRPosition &FnPos = IRPosition::function(*F);
8966 auto *FnAA =
8967 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8968 if (!FnAA)
8969 return indicatePessimisticFixpoint();
8970 bool Changed = false;
8971 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8972 AccessKind Kind, MemoryLocationsKind MLK) {
8973 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8974 getAccessKindFromInst(I));
8975 return true;
8976 };
8977 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8978 return indicatePessimisticFixpoint();
8979 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8980 }
8981
8982 /// See AbstractAttribute::trackStatistics()
8983 void trackStatistics() const override {
8984 if (isAssumedReadNone())
8985 STATS_DECLTRACK_CS_ATTR(readnone)
8986 }
8987};
8988} // namespace
8989
8990/// ------------------ denormal-fp-math Attribute -------------------------
8991
8992namespace {
8993struct AADenormalFPMathImpl : public AADenormalFPMath {
8994 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8995 : AADenormalFPMath(IRP, A) {}
8996
8997 const std::string getAsStr(Attributor *A) const override {
8998 std::string Str("AADenormalFPMath[");
8999 raw_string_ostream OS(Str);
9000
9001 DenormalState Known = getKnown();
9002 if (Known.Mode.isValid())
9003 OS << "denormal-fp-math=" << Known.Mode;
9004 else
9005 OS << "invalid";
9006
9007 if (Known.ModeF32.isValid())
9008 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9009 OS << ']';
9010 return Str;
9011 }
9012};
9013
9014struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9015 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9016 : AADenormalFPMathImpl(IRP, A) {}
9017
9018 void initialize(Attributor &A) override {
9019 const Function *F = getAnchorScope();
9020 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9021
9022 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9023 if (isModeFixed())
9024 indicateFixpoint();
9025 }
9026
9027 ChangeStatus updateImpl(Attributor &A) override {
9028 ChangeStatus Change = ChangeStatus::UNCHANGED;
9029
9030 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9031 Function *Caller = CS.getInstruction()->getFunction();
9032 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9033 << "->" << getAssociatedFunction()->getName() << '\n');
9034
9035 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9036 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9037 if (!CallerInfo)
9038 return false;
9039
9040 Change = Change | clampStateAndIndicateChange(this->getState(),
9041 CallerInfo->getState());
9042 return true;
9043 };
9044
9045 bool AllCallSitesKnown = true;
9046 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9047 return indicatePessimisticFixpoint();
9048
9049 if (Change == ChangeStatus::CHANGED && isModeFixed())
9050 indicateFixpoint();
9051 return Change;
9052 }
9053
9054 ChangeStatus manifest(Attributor &A) override {
9055 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9056
9057 SmallVector<Attribute, 2> AttrToAdd;
9059
9060 // TODO: Change to use DenormalFPEnv everywhere.
9061 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9062
9063 if (KnownEnv == DenormalFPEnv::getDefault()) {
9064 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9065 } else {
9066 AttrToAdd.push_back(Attribute::get(
9067 Ctx, Attribute::DenormalFPEnv,
9068 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9069 }
9070
9071 auto &IRP = getIRPosition();
9072
9073 // TODO: There should be a combined add and remove API.
9074 return A.removeAttrs(IRP, AttrToRemove) |
9075 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9076 }
9077
9078 void trackStatistics() const override {
9079 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9080 }
9081};
9082} // namespace
9083
9084/// ------------------ Value Constant Range Attribute -------------------------
9085
9086namespace {
9087struct AAValueConstantRangeImpl : AAValueConstantRange {
9088 using StateType = IntegerRangeState;
9089 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9090 : AAValueConstantRange(IRP, A) {}
9091
9092 /// See AbstractAttribute::initialize(..).
9093 void initialize(Attributor &A) override {
9094 if (A.hasSimplificationCallback(getIRPosition())) {
9095 indicatePessimisticFixpoint();
9096 return;
9097 }
9098
9099 // Intersect a range given by SCEV.
9100 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9101
9102 // Intersect a range given by LVI.
9103 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9104 }
9105
9106 /// See AbstractAttribute::getAsStr().
9107 const std::string getAsStr(Attributor *A) const override {
9108 std::string Str;
9109 llvm::raw_string_ostream OS(Str);
9110 OS << "range(" << getBitWidth() << ")<";
9111 getKnown().print(OS);
9112 OS << " / ";
9113 getAssumed().print(OS);
9114 OS << ">";
9115 return Str;
9116 }
9117
9118 /// Helper function to get a SCEV expr for the associated value at program
9119 /// point \p I.
9120 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9121 if (!getAnchorScope())
9122 return nullptr;
9123
9124 ScalarEvolution *SE =
9125 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9126 *getAnchorScope());
9127
9128 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9129 *getAnchorScope());
9130
9131 if (!SE || !LI)
9132 return nullptr;
9133
9134 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9135 if (!I)
9136 return S;
9137
9138 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9139 }
9140
9141 /// Helper function to get a range from SCEV for the associated value at
9142 /// program point \p I.
9143 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9144 const Instruction *I = nullptr) const {
9145 if (!getAnchorScope())
9146 return getWorstState(getBitWidth());
9147
9148 ScalarEvolution *SE =
9149 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9150 *getAnchorScope());
9151
9152 const SCEV *S = getSCEV(A, I);
9153 if (!SE || !S)
9154 return getWorstState(getBitWidth());
9155
9156 return SE->getUnsignedRange(S);
9157 }
9158
9159 /// Helper function to get a range from LVI for the associated value at
9160 /// program point \p I.
9161 ConstantRange
9162 getConstantRangeFromLVI(Attributor &A,
9163 const Instruction *CtxI = nullptr) const {
9164 if (!getAnchorScope())
9165 return getWorstState(getBitWidth());
9166
9167 LazyValueInfo *LVI =
9168 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9169 *getAnchorScope());
9170
9171 if (!LVI || !CtxI)
9172 return getWorstState(getBitWidth());
9173 return LVI->getConstantRange(&getAssociatedValue(),
9174 const_cast<Instruction *>(CtxI),
9175 /*UndefAllowed*/ false);
9176 }
9177
9178 /// Return true if \p CtxI is valid for querying outside analyses.
9179 /// This basically makes sure we do not ask intra-procedural analysis
9180 /// about a context in the wrong function or a context that violates
9181 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9182 /// if the original context of this AA is OK or should be considered invalid.
9183 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9184 const Instruction *CtxI,
9185 bool AllowAACtxI) const {
9186 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9187 return false;
9188
9189 // Our context might be in a different function, neither intra-procedural
9190 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9191 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9192 return false;
9193
9194 // If the context is not dominated by the value there are paths to the
9195 // context that do not define the value. This cannot be handled by
9196 // LazyValueInfo so we need to bail.
9197 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9198 InformationCache &InfoCache = A.getInfoCache();
9199 const DominatorTree *DT =
9200 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9201 *I->getFunction());
9202 return DT && DT->dominates(I, CtxI);
9203 }
9204
9205 return true;
9206 }
9207
9208 /// See AAValueConstantRange::getKnownConstantRange(..).
9209 ConstantRange
9210 getKnownConstantRange(Attributor &A,
9211 const Instruction *CtxI = nullptr) const override {
9212 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9213 /* AllowAACtxI */ false))
9214 return getKnown();
9215
9216 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9217 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9218 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9219 }
9220
9221 /// See AAValueConstantRange::getAssumedConstantRange(..).
9222 ConstantRange
9223 getAssumedConstantRange(Attributor &A,
9224 const Instruction *CtxI = nullptr) const override {
9225 // TODO: Make SCEV use Attributor assumption.
9226 // We may be able to bound a variable range via assumptions in
9227 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9228 // evolve to x^2 + x, then we can say that y is in [2, 12].
9229 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9230 /* AllowAACtxI */ false))
9231 return getAssumed();
9232
9233 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9234 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9235 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9236 }
9237
9238 /// Helper function to create MDNode for range metadata.
9239 static MDNode *
9240 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9241 const ConstantRange &AssumedConstantRange) {
9242 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9243 Ty, AssumedConstantRange.getLower())),
9244 ConstantAsMetadata::get(ConstantInt::get(
9245 Ty, AssumedConstantRange.getUpper()))};
9246 return MDNode::get(Ctx, LowAndHigh);
9247 }
9248
9249 /// Return true if \p Assumed is included in ranges from instruction \p I.
9250 static bool isBetterRange(const ConstantRange &Assumed,
9251 const Instruction &I) {
9252 if (Assumed.isFullSet())
9253 return false;
9254
9255 std::optional<ConstantRange> Known;
9256
9257 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9258 Known = CB->getRange();
9259 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9260 // If multiple ranges are annotated in IR, we give up to annotate assumed
9261 // range for now.
9262
9263 // TODO: If there exists a known range which containts assumed range, we
9264 // can say assumed range is better.
9265 if (KnownRanges->getNumOperands() > 2)
9266 return false;
9267
9268 ConstantInt *Lower =
9269 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9270 ConstantInt *Upper =
9271 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9272
9273 Known.emplace(Lower->getValue(), Upper->getValue());
9274 }
9275 return !Known || (*Known != Assumed && Known->contains(Assumed));
9276 }
9277
9278 /// Helper function to set range metadata.
9279 static bool
9280 setRangeMetadataIfisBetterRange(Instruction *I,
9281 const ConstantRange &AssumedConstantRange) {
9282 if (isBetterRange(AssumedConstantRange, *I)) {
9283 I->setMetadata(LLVMContext::MD_range,
9284 getMDNodeForConstantRange(I->getType(), I->getContext(),
9285 AssumedConstantRange));
9286 return true;
9287 }
9288 return false;
9289 }
9290 /// Helper function to set range return attribute.
9291 static bool
9292 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9293 Instruction *I,
9294 const ConstantRange &AssumedConstantRange) {
9295 if (isBetterRange(AssumedConstantRange, *I)) {
9296 A.manifestAttrs(IRP,
9297 Attribute::get(I->getContext(), Attribute::Range,
9298 AssumedConstantRange),
9299 /*ForceReplace*/ true);
9300 return true;
9301 }
9302 return false;
9303 }
9304
9305 /// See AbstractAttribute::manifest()
9306 ChangeStatus manifest(Attributor &A) override {
9307 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9308 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9309 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9310
9311 auto &V = getAssociatedValue();
9312 if (!AssumedConstantRange.isEmptySet() &&
9313 !AssumedConstantRange.isSingleElement()) {
9314 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9315 assert(I == getCtxI() && "Should not annotate an instruction which is "
9316 "not the context instruction");
9317 if (isa<LoadInst>(I))
9318 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9319 Changed = ChangeStatus::CHANGED;
9320 if (isa<CallInst>(I))
9321 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9322 AssumedConstantRange))
9323 Changed = ChangeStatus::CHANGED;
9324 }
9325 }
9326
9327 return Changed;
9328 }
9329};
9330
9331struct AAValueConstantRangeArgument final
9332 : AAArgumentFromCallSiteArguments<
9333 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9334 true /* BridgeCallBaseContext */> {
9335 using Base = AAArgumentFromCallSiteArguments<
9336 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9337 true /* BridgeCallBaseContext */>;
9338 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9339 : Base(IRP, A) {}
9340
9341 /// See AbstractAttribute::trackStatistics()
9342 void trackStatistics() const override {
9343 STATS_DECLTRACK_ARG_ATTR(value_range)
9344 }
9345};
9346
9347struct AAValueConstantRangeReturned
9348 : AAReturnedFromReturnedValues<AAValueConstantRange,
9349 AAValueConstantRangeImpl,
9350 AAValueConstantRangeImpl::StateType,
9351 /* PropagateCallBaseContext */ true> {
9352 using Base =
9353 AAReturnedFromReturnedValues<AAValueConstantRange,
9354 AAValueConstantRangeImpl,
9355 AAValueConstantRangeImpl::StateType,
9356 /* PropagateCallBaseContext */ true>;
9357 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9358 : Base(IRP, A) {}
9359
9360 /// See AbstractAttribute::initialize(...).
9361 void initialize(Attributor &A) override {
9362 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9363 indicatePessimisticFixpoint();
9364 }
9365
9366 /// See AbstractAttribute::trackStatistics()
9367 void trackStatistics() const override {
9368 STATS_DECLTRACK_FNRET_ATTR(value_range)
9369 }
9370};
9371
9372struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9373 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9374 : AAValueConstantRangeImpl(IRP, A) {}
9375
9376 /// See AbstractAttribute::initialize(...).
9377 void initialize(Attributor &A) override {
9378 AAValueConstantRangeImpl::initialize(A);
9379 if (isAtFixpoint())
9380 return;
9381
9382 Value &V = getAssociatedValue();
9383
9384 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9385 unionAssumed(ConstantRange(C->getValue()));
9386 indicateOptimisticFixpoint();
9387 return;
9388 }
9389
9390 if (isa<UndefValue>(&V)) {
9391 // Collapse the undef state to 0.
9392 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9393 indicateOptimisticFixpoint();
9394 return;
9395 }
9396
9397 if (isa<CallBase>(&V))
9398 return;
9399
9400 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9401 return;
9402
9403 // If it is a load instruction with range metadata, use it.
9404 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9405 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9406 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9407 return;
9408 }
9409
9410 // We can work with PHI and select instruction as we traverse their operands
9411 // during update.
9412 if (isa<SelectInst>(V) || isa<PHINode>(V))
9413 return;
9414
9415 // Otherwise we give up.
9416 indicatePessimisticFixpoint();
9417
9418 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9419 << getAssociatedValue() << "\n");
9420 }
9421
9422 bool calculateBinaryOperator(
9423 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9424 const Instruction *CtxI,
9425 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9426 Value *LHS = BinOp->getOperand(0);
9427 Value *RHS = BinOp->getOperand(1);
9428
9429 // Simplify the operands first.
9430 bool UsedAssumedInformation = false;
9431 const auto &SimplifiedLHS = A.getAssumedSimplified(
9432 IRPosition::value(*LHS, getCallBaseContext()), *this,
9433 UsedAssumedInformation, AA::Interprocedural);
9434 if (!SimplifiedLHS.has_value())
9435 return true;
9436 if (!*SimplifiedLHS)
9437 return false;
9438 LHS = *SimplifiedLHS;
9439
9440 const auto &SimplifiedRHS = A.getAssumedSimplified(
9441 IRPosition::value(*RHS, getCallBaseContext()), *this,
9442 UsedAssumedInformation, AA::Interprocedural);
9443 if (!SimplifiedRHS.has_value())
9444 return true;
9445 if (!*SimplifiedRHS)
9446 return false;
9447 RHS = *SimplifiedRHS;
9448
9449 // TODO: Allow non integers as well.
9450 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9451 return false;
9452
9453 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9454 *this, IRPosition::value(*LHS, getCallBaseContext()),
9455 DepClassTy::REQUIRED);
9456 if (!LHSAA)
9457 return false;
9458 QuerriedAAs.push_back(LHSAA);
9459 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9460
9461 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9462 *this, IRPosition::value(*RHS, getCallBaseContext()),
9463 DepClassTy::REQUIRED);
9464 if (!RHSAA)
9465 return false;
9466 QuerriedAAs.push_back(RHSAA);
9467 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9468
9469 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9470
9471 T.unionAssumed(AssumedRange);
9472
9473 // TODO: Track a known state too.
9474
9475 return T.isValidState();
9476 }
9477
9478 bool calculateCastInst(
9479 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9480 const Instruction *CtxI,
9481 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9482 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9483 // TODO: Allow non integers as well.
9484 Value *OpV = CastI->getOperand(0);
9485
9486 // Simplify the operand first.
9487 bool UsedAssumedInformation = false;
9488 const auto &SimplifiedOpV = A.getAssumedSimplified(
9489 IRPosition::value(*OpV, getCallBaseContext()), *this,
9490 UsedAssumedInformation, AA::Interprocedural);
9491 if (!SimplifiedOpV.has_value())
9492 return true;
9493 if (!*SimplifiedOpV)
9494 return false;
9495 OpV = *SimplifiedOpV;
9496
9497 if (!OpV->getType()->isIntegerTy())
9498 return false;
9499
9500 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9501 *this, IRPosition::value(*OpV, getCallBaseContext()),
9502 DepClassTy::REQUIRED);
9503 if (!OpAA)
9504 return false;
9505 QuerriedAAs.push_back(OpAA);
9506 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9507 getState().getBitWidth()));
9508 return T.isValidState();
9509 }
9510
9511 bool
9512 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9513 const Instruction *CtxI,
9514 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9515 Value *LHS = CmpI->getOperand(0);
9516 Value *RHS = CmpI->getOperand(1);
9517
9518 // Simplify the operands first.
9519 bool UsedAssumedInformation = false;
9520 const auto &SimplifiedLHS = A.getAssumedSimplified(
9521 IRPosition::value(*LHS, getCallBaseContext()), *this,
9522 UsedAssumedInformation, AA::Interprocedural);
9523 if (!SimplifiedLHS.has_value())
9524 return true;
9525 if (!*SimplifiedLHS)
9526 return false;
9527 LHS = *SimplifiedLHS;
9528
9529 const auto &SimplifiedRHS = A.getAssumedSimplified(
9530 IRPosition::value(*RHS, getCallBaseContext()), *this,
9531 UsedAssumedInformation, AA::Interprocedural);
9532 if (!SimplifiedRHS.has_value())
9533 return true;
9534 if (!*SimplifiedRHS)
9535 return false;
9536 RHS = *SimplifiedRHS;
9537
9538 // TODO: Allow non integers as well.
9539 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9540 return false;
9541
9542 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9543 *this, IRPosition::value(*LHS, getCallBaseContext()),
9544 DepClassTy::REQUIRED);
9545 if (!LHSAA)
9546 return false;
9547 QuerriedAAs.push_back(LHSAA);
9548 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9549 *this, IRPosition::value(*RHS, getCallBaseContext()),
9550 DepClassTy::REQUIRED);
9551 if (!RHSAA)
9552 return false;
9553 QuerriedAAs.push_back(RHSAA);
9554 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9555 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9556
9557 // If one of them is empty set, we can't decide.
9558 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9559 return true;
9560
9561 bool MustTrue = false, MustFalse = false;
9562
9563 auto AllowedRegion =
9565
9566 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9567 MustFalse = true;
9568
9569 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9570 MustTrue = true;
9571
9572 assert((!MustTrue || !MustFalse) &&
9573 "Either MustTrue or MustFalse should be false!");
9574
9575 if (MustTrue)
9576 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9577 else if (MustFalse)
9578 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9579 else
9580 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9581
9582 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9583 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9584 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9585 << *RHSAA);
9586
9587 // TODO: Track a known state too.
9588 return T.isValidState();
9589 }
9590
9591 /// See AbstractAttribute::updateImpl(...).
9592 ChangeStatus updateImpl(Attributor &A) override {
9593
9594 IntegerRangeState T(getBitWidth());
9595 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9597 if (!I || isa<CallBase>(I)) {
9598
9599 // Simplify the operand first.
9600 bool UsedAssumedInformation = false;
9601 const auto &SimplifiedOpV = A.getAssumedSimplified(
9602 IRPosition::value(V, getCallBaseContext()), *this,
9603 UsedAssumedInformation, AA::Interprocedural);
9604 if (!SimplifiedOpV.has_value())
9605 return true;
9606 if (!*SimplifiedOpV)
9607 return false;
9608 Value *VPtr = *SimplifiedOpV;
9609
9610 // If the value is not instruction, we query AA to Attributor.
9611 const auto *AA = A.getAAFor<AAValueConstantRange>(
9612 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9613 DepClassTy::REQUIRED);
9614
9615 // Clamp operator is not used to utilize a program point CtxI.
9616 if (AA)
9617 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9618 else
9619 return false;
9620
9621 return T.isValidState();
9622 }
9623
9625 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9626 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9627 return false;
9628 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9629 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9630 return false;
9631 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9632 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9633 return false;
9634 } else {
9635 // Give up with other instructions.
9636 // TODO: Add other instructions
9637
9638 T.indicatePessimisticFixpoint();
9639 return false;
9640 }
9641
9642 // Catch circular reasoning in a pessimistic way for now.
9643 // TODO: Check how the range evolves and if we stripped anything, see also
9644 // AADereferenceable or AAAlign for similar situations.
9645 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9646 if (QueriedAA != this)
9647 continue;
9648 // If we are in a stady state we do not need to worry.
9649 if (T.getAssumed() == getState().getAssumed())
9650 continue;
9651 T.indicatePessimisticFixpoint();
9652 }
9653
9654 return T.isValidState();
9655 };
9656
9657 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9658 return indicatePessimisticFixpoint();
9659
9660 // Ensure that long def-use chains can't cause circular reasoning either by
9661 // introducing a cutoff below.
9662 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9663 return ChangeStatus::UNCHANGED;
9664 if (++NumChanges > MaxNumChanges) {
9665 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9666 << " but only " << MaxNumChanges
9667 << " are allowed to avoid cyclic reasoning.");
9668 return indicatePessimisticFixpoint();
9669 }
9670 return ChangeStatus::CHANGED;
9671 }
9672
9673 /// See AbstractAttribute::trackStatistics()
9674 void trackStatistics() const override {
9676 }
9677
9678 /// Tracker to bail after too many widening steps of the constant range.
9679 int NumChanges = 0;
9680
9681 /// Upper bound for the number of allowed changes (=widening steps) for the
9682 /// constant range before we give up.
9683 static constexpr int MaxNumChanges = 5;
9684};
9685
9686struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9687 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9688 : AAValueConstantRangeImpl(IRP, A) {}
9689
9690 /// See AbstractAttribute::initialize(...).
9691 ChangeStatus updateImpl(Attributor &A) override {
9692 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9693 "not be called");
9694 }
9695
9696 /// See AbstractAttribute::trackStatistics()
9697 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9698};
9699
9700struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9701 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9702 : AAValueConstantRangeFunction(IRP, A) {}
9703
9704 /// See AbstractAttribute::trackStatistics()
9705 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9706};
9707
9708struct AAValueConstantRangeCallSiteReturned
9709 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9710 AAValueConstantRangeImpl::StateType,
9711 /* IntroduceCallBaseContext */ true> {
9712 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9713 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9714 AAValueConstantRangeImpl::StateType,
9715 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9716
9717 /// See AbstractAttribute::initialize(...).
9718 void initialize(Attributor &A) override {
9719 // If it is a call instruction with range attribute, use the range.
9720 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9721 if (std::optional<ConstantRange> Range = CI->getRange())
9722 intersectKnown(*Range);
9723 }
9724
9725 AAValueConstantRangeImpl::initialize(A);
9726 }
9727
9728 /// See AbstractAttribute::trackStatistics()
9729 void trackStatistics() const override {
9730 STATS_DECLTRACK_CSRET_ATTR(value_range)
9731 }
9732};
9733struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9734 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9735 : AAValueConstantRangeFloating(IRP, A) {}
9736
9737 /// See AbstractAttribute::manifest()
9738 ChangeStatus manifest(Attributor &A) override {
9739 return ChangeStatus::UNCHANGED;
9740 }
9741
9742 /// See AbstractAttribute::trackStatistics()
9743 void trackStatistics() const override {
9744 STATS_DECLTRACK_CSARG_ATTR(value_range)
9745 }
9746};
9747} // namespace
9748
9749/// ------------------ Potential Values Attribute -------------------------
9750
9751namespace {
9752struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9753 using StateType = PotentialConstantIntValuesState;
9754
9755 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9756 : AAPotentialConstantValues(IRP, A) {}
9757
9758 /// See AbstractAttribute::initialize(..).
9759 void initialize(Attributor &A) override {
9760 if (A.hasSimplificationCallback(getIRPosition()))
9761 indicatePessimisticFixpoint();
9762 else
9763 AAPotentialConstantValues::initialize(A);
9764 }
9765
9766 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9767 bool &ContainsUndef, bool ForSelf) {
9769 bool UsedAssumedInformation = false;
9770 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9771 UsedAssumedInformation)) {
9772 // Avoid recursion when the caller is computing constant values for this
9773 // IRP itself.
9774 if (ForSelf)
9775 return false;
9776 if (!IRP.getAssociatedType()->isIntegerTy())
9777 return false;
9778 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9779 *this, IRP, DepClassTy::REQUIRED);
9780 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9781 return false;
9782 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9783 S = PotentialValuesAA->getState().getAssumedSet();
9784 return true;
9785 }
9786
9787 // Copy all the constant values, except UndefValue. ContainsUndef is true
9788 // iff Values contains only UndefValue instances. If there are other known
9789 // constants, then UndefValue is dropped.
9790 ContainsUndef = false;
9791 for (auto &It : Values) {
9792 if (isa<UndefValue>(It.getValue())) {
9793 ContainsUndef = true;
9794 continue;
9795 }
9796 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9797 if (!CI)
9798 return false;
9799 S.insert(CI->getValue());
9800 }
9801 ContainsUndef &= S.empty();
9802
9803 return true;
9804 }
9805
9806 /// See AbstractAttribute::getAsStr().
9807 const std::string getAsStr(Attributor *A) const override {
9808 std::string Str;
9809 llvm::raw_string_ostream OS(Str);
9810 OS << getState();
9811 return Str;
9812 }
9813
9814 /// See AbstractAttribute::updateImpl(...).
9815 ChangeStatus updateImpl(Attributor &A) override {
9816 return indicatePessimisticFixpoint();
9817 }
9818};
9819
9820struct AAPotentialConstantValuesArgument final
9821 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9822 AAPotentialConstantValuesImpl,
9823 PotentialConstantIntValuesState> {
9824 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9825 AAPotentialConstantValuesImpl,
9827 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9828 : Base(IRP, A) {}
9829
9830 /// See AbstractAttribute::trackStatistics()
9831 void trackStatistics() const override {
9832 STATS_DECLTRACK_ARG_ATTR(potential_values)
9833 }
9834};
9835
9836struct AAPotentialConstantValuesReturned
9837 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9838 AAPotentialConstantValuesImpl> {
9839 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9840 AAPotentialConstantValuesImpl>;
9841 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9842 : Base(IRP, A) {}
9843
9844 void initialize(Attributor &A) override {
9845 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9846 indicatePessimisticFixpoint();
9847 Base::initialize(A);
9848 }
9849
9850 /// See AbstractAttribute::trackStatistics()
9851 void trackStatistics() const override {
9852 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9853 }
9854};
9855
9856struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9857 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9858 : AAPotentialConstantValuesImpl(IRP, A) {}
9859
9860 /// See AbstractAttribute::initialize(..).
9861 void initialize(Attributor &A) override {
9862 AAPotentialConstantValuesImpl::initialize(A);
9863 if (isAtFixpoint())
9864 return;
9865
9866 Value &V = getAssociatedValue();
9867
9868 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9869 unionAssumed(C->getValue());
9870 indicateOptimisticFixpoint();
9871 return;
9872 }
9873
9874 if (isa<UndefValue>(&V)) {
9875 unionAssumedWithUndef();
9876 indicateOptimisticFixpoint();
9877 return;
9878 }
9879
9880 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9881 return;
9882
9883 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9884 return;
9885
9886 indicatePessimisticFixpoint();
9887
9888 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9889 << getAssociatedValue() << "\n");
9890 }
9891
9892 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9893 const APInt &RHS) {
9894 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9895 }
9896
9897 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9898 uint32_t ResultBitWidth) {
9899 Instruction::CastOps CastOp = CI->getOpcode();
9900 switch (CastOp) {
9901 default:
9902 llvm_unreachable("unsupported or not integer cast");
9903 case Instruction::Trunc:
9904 return Src.trunc(ResultBitWidth);
9905 case Instruction::SExt:
9906 return Src.sext(ResultBitWidth);
9907 case Instruction::ZExt:
9908 return Src.zext(ResultBitWidth);
9909 case Instruction::BitCast:
9910 return Src;
9911 }
9912 }
9913
9914 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9915 const APInt &LHS, const APInt &RHS,
9916 bool &SkipOperation, bool &Unsupported) {
9917 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9918 // Unsupported is set to true when the binary operator is not supported.
9919 // SkipOperation is set to true when UB occur with the given operand pair
9920 // (LHS, RHS).
9921 // TODO: we should look at nsw and nuw keywords to handle operations
9922 // that create poison or undef value.
9923 switch (BinOpcode) {
9924 default:
9925 Unsupported = true;
9926 return LHS;
9927 case Instruction::Add:
9928 return LHS + RHS;
9929 case Instruction::Sub:
9930 return LHS - RHS;
9931 case Instruction::Mul:
9932 return LHS * RHS;
9933 case Instruction::UDiv:
9934 if (RHS.isZero()) {
9935 SkipOperation = true;
9936 return LHS;
9937 }
9938 return LHS.udiv(RHS);
9939 case Instruction::SDiv:
9940 if (RHS.isZero()) {
9941 SkipOperation = true;
9942 return LHS;
9943 }
9944 return LHS.sdiv(RHS);
9945 case Instruction::URem:
9946 if (RHS.isZero()) {
9947 SkipOperation = true;
9948 return LHS;
9949 }
9950 return LHS.urem(RHS);
9951 case Instruction::SRem:
9952 if (RHS.isZero()) {
9953 SkipOperation = true;
9954 return LHS;
9955 }
9956 return LHS.srem(RHS);
9957 case Instruction::Shl:
9958 return LHS.shl(RHS);
9959 case Instruction::LShr:
9960 return LHS.lshr(RHS);
9961 case Instruction::AShr:
9962 return LHS.ashr(RHS);
9963 case Instruction::And:
9964 return LHS & RHS;
9965 case Instruction::Or:
9966 return LHS | RHS;
9967 case Instruction::Xor:
9968 return LHS ^ RHS;
9969 }
9970 }
9971
9972 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9973 const APInt &LHS, const APInt &RHS) {
9974 bool SkipOperation = false;
9975 bool Unsupported = false;
9976 APInt Result =
9977 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9978 if (Unsupported)
9979 return false;
9980 // If SkipOperation is true, we can ignore this operand pair (L, R).
9981 if (!SkipOperation)
9982 unionAssumed(Result);
9983 return isValidState();
9984 }
9985
9986 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9987 auto AssumedBefore = getAssumed();
9988 Value *LHS = ICI->getOperand(0);
9989 Value *RHS = ICI->getOperand(1);
9990
9991 bool LHSContainsUndef = false, RHSContainsUndef = false;
9992 SetTy LHSAAPVS, RHSAAPVS;
9993 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9994 LHSContainsUndef, /* ForSelf */ false) ||
9995 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9996 RHSContainsUndef, /* ForSelf */ false))
9997 return indicatePessimisticFixpoint();
9998
9999 // TODO: make use of undef flag to limit potential values aggressively.
10000 bool MaybeTrue = false, MaybeFalse = false;
10001 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10002 if (LHSContainsUndef && RHSContainsUndef) {
10003 // The result of any comparison between undefs can be soundly replaced
10004 // with undef.
10005 unionAssumedWithUndef();
10006 } else if (LHSContainsUndef) {
10007 for (const APInt &R : RHSAAPVS) {
10008 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10009 MaybeTrue |= CmpResult;
10010 MaybeFalse |= !CmpResult;
10011 if (MaybeTrue & MaybeFalse)
10012 return indicatePessimisticFixpoint();
10013 }
10014 } else if (RHSContainsUndef) {
10015 for (const APInt &L : LHSAAPVS) {
10016 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10017 MaybeTrue |= CmpResult;
10018 MaybeFalse |= !CmpResult;
10019 if (MaybeTrue & MaybeFalse)
10020 return indicatePessimisticFixpoint();
10021 }
10022 } else {
10023 for (const APInt &L : LHSAAPVS) {
10024 for (const APInt &R : RHSAAPVS) {
10025 bool CmpResult = calculateICmpInst(ICI, L, R);
10026 MaybeTrue |= CmpResult;
10027 MaybeFalse |= !CmpResult;
10028 if (MaybeTrue & MaybeFalse)
10029 return indicatePessimisticFixpoint();
10030 }
10031 }
10032 }
10033 if (MaybeTrue)
10034 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10035 if (MaybeFalse)
10036 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10037 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10038 : ChangeStatus::CHANGED;
10039 }
10040
10041 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10042 auto AssumedBefore = getAssumed();
10043 Value *LHS = SI->getTrueValue();
10044 Value *RHS = SI->getFalseValue();
10045
10046 bool UsedAssumedInformation = false;
10047 std::optional<Constant *> C = A.getAssumedConstant(
10048 *SI->getCondition(), *this, UsedAssumedInformation);
10049
10050 // Check if we only need one operand.
10051 bool OnlyLeft = false, OnlyRight = false;
10052 if (C && *C && (*C)->isOneValue())
10053 OnlyLeft = true;
10054 else if (C && *C && (*C)->isNullValue())
10055 OnlyRight = true;
10056
10057 bool LHSContainsUndef = false, RHSContainsUndef = false;
10058 SetTy LHSAAPVS, RHSAAPVS;
10059 if (!OnlyRight &&
10060 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10061 LHSContainsUndef, /* ForSelf */ false))
10062 return indicatePessimisticFixpoint();
10063
10064 if (!OnlyLeft &&
10065 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10066 RHSContainsUndef, /* ForSelf */ false))
10067 return indicatePessimisticFixpoint();
10068
10069 if (OnlyLeft || OnlyRight) {
10070 // select (true/false), lhs, rhs
10071 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10072 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10073
10074 if (Undef)
10075 unionAssumedWithUndef();
10076 else {
10077 for (const auto &It : *OpAA)
10078 unionAssumed(It);
10079 }
10080
10081 } else if (LHSContainsUndef && RHSContainsUndef) {
10082 // select i1 *, undef , undef => undef
10083 unionAssumedWithUndef();
10084 } else {
10085 for (const auto &It : LHSAAPVS)
10086 unionAssumed(It);
10087 for (const auto &It : RHSAAPVS)
10088 unionAssumed(It);
10089 }
10090 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10091 : ChangeStatus::CHANGED;
10092 }
10093
10094 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10095 auto AssumedBefore = getAssumed();
10096 if (!CI->isIntegerCast())
10097 return indicatePessimisticFixpoint();
10098 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10099 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10100 Value *Src = CI->getOperand(0);
10101
10102 bool SrcContainsUndef = false;
10103 SetTy SrcPVS;
10104 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10105 SrcContainsUndef, /* ForSelf */ false))
10106 return indicatePessimisticFixpoint();
10107
10108 if (SrcContainsUndef)
10109 unionAssumedWithUndef();
10110 else {
10111 for (const APInt &S : SrcPVS) {
10112 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10113 unionAssumed(T);
10114 }
10115 }
10116 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10117 : ChangeStatus::CHANGED;
10118 }
10119
10120 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10121 auto AssumedBefore = getAssumed();
10122 Value *LHS = BinOp->getOperand(0);
10123 Value *RHS = BinOp->getOperand(1);
10124
10125 bool LHSContainsUndef = false, RHSContainsUndef = false;
10126 SetTy LHSAAPVS, RHSAAPVS;
10127 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10128 LHSContainsUndef, /* ForSelf */ false) ||
10129 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10130 RHSContainsUndef, /* ForSelf */ false))
10131 return indicatePessimisticFixpoint();
10132
10133 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10134
10135 // TODO: make use of undef flag to limit potential values aggressively.
10136 if (LHSContainsUndef && RHSContainsUndef) {
10137 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10138 return indicatePessimisticFixpoint();
10139 } else if (LHSContainsUndef) {
10140 for (const APInt &R : RHSAAPVS) {
10141 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10142 return indicatePessimisticFixpoint();
10143 }
10144 } else if (RHSContainsUndef) {
10145 for (const APInt &L : LHSAAPVS) {
10146 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10147 return indicatePessimisticFixpoint();
10148 }
10149 } else {
10150 for (const APInt &L : LHSAAPVS) {
10151 for (const APInt &R : RHSAAPVS) {
10152 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10153 return indicatePessimisticFixpoint();
10154 }
10155 }
10156 }
10157 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10158 : ChangeStatus::CHANGED;
10159 }
10160
10161 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10162 auto AssumedBefore = getAssumed();
10163 SetTy Incoming;
10164 bool ContainsUndef;
10165 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10166 ContainsUndef, /* ForSelf */ true))
10167 return indicatePessimisticFixpoint();
10168 if (ContainsUndef) {
10169 unionAssumedWithUndef();
10170 } else {
10171 for (const auto &It : Incoming)
10172 unionAssumed(It);
10173 }
10174 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10175 : ChangeStatus::CHANGED;
10176 }
10177
10178 /// See AbstractAttribute::updateImpl(...).
10179 ChangeStatus updateImpl(Attributor &A) override {
10180 Value &V = getAssociatedValue();
10182
10183 if (auto *ICI = dyn_cast<ICmpInst>(I))
10184 return updateWithICmpInst(A, ICI);
10185
10186 if (auto *SI = dyn_cast<SelectInst>(I))
10187 return updateWithSelectInst(A, SI);
10188
10189 if (auto *CI = dyn_cast<CastInst>(I))
10190 return updateWithCastInst(A, CI);
10191
10192 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10193 return updateWithBinaryOperator(A, BinOp);
10194
10195 if (isa<PHINode>(I) || isa<LoadInst>(I))
10196 return updateWithInstruction(A, I);
10197
10198 return indicatePessimisticFixpoint();
10199 }
10200
10201 /// See AbstractAttribute::trackStatistics()
10202 void trackStatistics() const override {
10203 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10204 }
10205};
10206
10207struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10208 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10209 : AAPotentialConstantValuesImpl(IRP, A) {}
10210
10211 /// See AbstractAttribute::initialize(...).
10212 ChangeStatus updateImpl(Attributor &A) override {
10214 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10215 "not be called");
10216 }
10217
10218 /// See AbstractAttribute::trackStatistics()
10219 void trackStatistics() const override {
10220 STATS_DECLTRACK_FN_ATTR(potential_values)
10221 }
10222};
10223
10224struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10225 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10226 : AAPotentialConstantValuesFunction(IRP, A) {}
10227
10228 /// See AbstractAttribute::trackStatistics()
10229 void trackStatistics() const override {
10230 STATS_DECLTRACK_CS_ATTR(potential_values)
10231 }
10232};
10233
10234struct AAPotentialConstantValuesCallSiteReturned
10235 : AACalleeToCallSite<AAPotentialConstantValues,
10236 AAPotentialConstantValuesImpl> {
10237 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10238 Attributor &A)
10239 : AACalleeToCallSite<AAPotentialConstantValues,
10240 AAPotentialConstantValuesImpl>(IRP, A) {}
10241
10242 /// See AbstractAttribute::trackStatistics()
10243 void trackStatistics() const override {
10244 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10245 }
10246};
10247
10248struct AAPotentialConstantValuesCallSiteArgument
10249 : AAPotentialConstantValuesFloating {
10250 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10251 Attributor &A)
10252 : AAPotentialConstantValuesFloating(IRP, A) {}
10253
10254 /// See AbstractAttribute::initialize(..).
10255 void initialize(Attributor &A) override {
10256 AAPotentialConstantValuesImpl::initialize(A);
10257 if (isAtFixpoint())
10258 return;
10259
10260 Value &V = getAssociatedValue();
10261
10262 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10263 unionAssumed(C->getValue());
10264 indicateOptimisticFixpoint();
10265 return;
10266 }
10267
10268 if (isa<UndefValue>(&V)) {
10269 unionAssumedWithUndef();
10270 indicateOptimisticFixpoint();
10271 return;
10272 }
10273 }
10274
10275 /// See AbstractAttribute::updateImpl(...).
10276 ChangeStatus updateImpl(Attributor &A) override {
10277 Value &V = getAssociatedValue();
10278 auto AssumedBefore = getAssumed();
10279 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10280 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10281 if (!AA)
10282 return indicatePessimisticFixpoint();
10283 const auto &S = AA->getAssumed();
10284 unionAssumed(S);
10285 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10286 : ChangeStatus::CHANGED;
10287 }
10288
10289 /// See AbstractAttribute::trackStatistics()
10290 void trackStatistics() const override {
10291 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10292 }
10293};
10294} // namespace
10295
10296/// ------------------------ NoUndef Attribute ---------------------------------
10298 Attribute::AttrKind ImpliedAttributeKind,
10299 bool IgnoreSubsumingPositions) {
10300 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10301 "Unexpected attribute kind");
10302 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10303 Attribute::NoUndef))
10304 return true;
10305
10306 Value &Val = IRP.getAssociatedValue();
10309 LLVMContext &Ctx = Val.getContext();
10310 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10311 return true;
10312 }
10313
10314 return false;
10315}
10316
10317namespace {
10318struct AANoUndefImpl : AANoUndef {
10319 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10320
10321 /// See AbstractAttribute::initialize(...).
10322 void initialize(Attributor &A) override {
10323 Value &V = getAssociatedValue();
10324 if (isa<UndefValue>(V))
10325 indicatePessimisticFixpoint();
10326 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10327 }
10328
10329 /// See followUsesInMBEC
10330 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10331 AANoUndef::StateType &State) {
10332 const Value *UseV = U->get();
10333 const DominatorTree *DT = nullptr;
10334 AssumptionCache *AC = nullptr;
10335 InformationCache &InfoCache = A.getInfoCache();
10336 if (Function *F = getAnchorScope()) {
10337 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10338 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10339 }
10340 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10341 bool TrackUse = false;
10342 // Track use for instructions which must produce undef or poison bits when
10343 // at least one operand contains such bits.
10345 TrackUse = true;
10346 return TrackUse;
10347 }
10348
10349 /// See AbstractAttribute::getAsStr().
10350 const std::string getAsStr(Attributor *A) const override {
10351 return getAssumed() ? "noundef" : "may-undef-or-poison";
10352 }
10353
10354 ChangeStatus manifest(Attributor &A) override {
10355 // We don't manifest noundef attribute for dead positions because the
10356 // associated values with dead positions would be replaced with undef
10357 // values.
10358 bool UsedAssumedInformation = false;
10359 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10360 UsedAssumedInformation))
10361 return ChangeStatus::UNCHANGED;
10362 // A position whose simplified value does not have any value is
10363 // considered to be dead. We don't manifest noundef in such positions for
10364 // the same reason above.
10365 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10367 .has_value())
10368 return ChangeStatus::UNCHANGED;
10369 return AANoUndef::manifest(A);
10370 }
10371};
10372
10373struct AANoUndefFloating : public AANoUndefImpl {
10374 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10375 : AANoUndefImpl(IRP, A) {}
10376
10377 /// See AbstractAttribute::initialize(...).
10378 void initialize(Attributor &A) override {
10379 AANoUndefImpl::initialize(A);
10380 if (!getState().isAtFixpoint() && getAnchorScope() &&
10381 !getAnchorScope()->isDeclaration())
10382 if (Instruction *CtxI = getCtxI())
10383 followUsesInMBEC(*this, A, getState(), *CtxI);
10384 }
10385
10386 /// See AbstractAttribute::updateImpl(...).
10387 ChangeStatus updateImpl(Attributor &A) override {
10388 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10389 bool IsKnownNoUndef;
10391 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10392 };
10393
10394 bool Stripped;
10395 bool UsedAssumedInformation = false;
10396 Value *AssociatedValue = &getAssociatedValue();
10398 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10399 AA::AnyScope, UsedAssumedInformation))
10400 Stripped = false;
10401 else
10402 Stripped =
10403 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10404
10405 if (!Stripped) {
10406 // If we haven't stripped anything we might still be able to use a
10407 // different AA, but only if the IRP changes. Effectively when we
10408 // interpret this not as a call site value but as a floating/argument
10409 // value.
10410 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10411 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10412 return indicatePessimisticFixpoint();
10413 return ChangeStatus::UNCHANGED;
10414 }
10415
10416 for (const auto &VAC : Values)
10417 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10418 return indicatePessimisticFixpoint();
10419
10420 return ChangeStatus::UNCHANGED;
10421 }
10422
10423 /// See AbstractAttribute::trackStatistics()
10424 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10425};
10426
10427struct AANoUndefReturned final
10428 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10429 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10430 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10431
10432 /// See AbstractAttribute::trackStatistics()
10433 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10434};
10435
10436struct AANoUndefArgument final
10437 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10438 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10439 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10440
10441 /// See AbstractAttribute::trackStatistics()
10442 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10443};
10444
10445struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10446 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10447 : AANoUndefFloating(IRP, A) {}
10448
10449 /// See AbstractAttribute::trackStatistics()
10450 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10451};
10452
10453struct AANoUndefCallSiteReturned final
10454 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10455 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10456 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10457
10458 /// See AbstractAttribute::trackStatistics()
10459 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10460};
10461
10462/// ------------------------ NoFPClass Attribute -------------------------------
10463
10464struct AANoFPClassImpl : AANoFPClass {
10465 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10466
10467 void initialize(Attributor &A) override {
10468 const IRPosition &IRP = getIRPosition();
10469
10470 Value &V = IRP.getAssociatedValue();
10471 if (isa<UndefValue>(V)) {
10472 indicateOptimisticFixpoint();
10473 return;
10474 }
10475
10477 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10478 for (const auto &Attr : Attrs) {
10479 addKnownBits(Attr.getNoFPClass());
10480 }
10481
10482 Instruction *CtxI = getCtxI();
10483
10484 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10485 const DataLayout &DL = A.getDataLayout();
10486 InformationCache &InfoCache = A.getInfoCache();
10487
10488 const DominatorTree *DT = nullptr;
10489 AssumptionCache *AC = nullptr;
10490 const TargetLibraryInfo *TLI = nullptr;
10491 Function *F = getAnchorScope();
10492 if (F) {
10493 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10494 if (!F->isDeclaration()) {
10495 DT =
10496 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10497 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10498 }
10499 }
10500
10501 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10502
10503 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10504 addKnownBits(~KnownFPClass.KnownFPClasses);
10505 }
10506
10507 if (CtxI)
10508 followUsesInMBEC(*this, A, getState(), *CtxI);
10509 }
10510
10511 /// See followUsesInMBEC
10512 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10513 AANoFPClass::StateType &State) {
10514 // TODO: Determine what instructions can be looked through.
10515 auto *CB = dyn_cast<CallBase>(I);
10516 if (!CB)
10517 return false;
10518
10519 if (!CB->isArgOperand(U))
10520 return false;
10521
10522 unsigned ArgNo = CB->getArgOperandNo(U);
10523 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10524 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10525 State.addKnownBits(NoFPAA->getState().getKnown());
10526 return false;
10527 }
10528
10529 const std::string getAsStr(Attributor *A) const override {
10530 std::string Result = "nofpclass";
10531 raw_string_ostream OS(Result);
10532 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10533 return Result;
10534 }
10535
10536 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10537 SmallVectorImpl<Attribute> &Attrs) const override {
10538 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10539 }
10540};
10541
10542struct AANoFPClassFloating : public AANoFPClassImpl {
10543 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10544 : AANoFPClassImpl(IRP, A) {}
10545
10546 /// See AbstractAttribute::updateImpl(...).
10547 ChangeStatus updateImpl(Attributor &A) override {
10549 bool UsedAssumedInformation = false;
10550 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10551 AA::AnyScope, UsedAssumedInformation)) {
10552 Values.push_back({getAssociatedValue(), getCtxI()});
10553 }
10554
10555 StateType T;
10556 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10557 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10558 DepClassTy::REQUIRED);
10559 if (!AA || this == AA) {
10560 T.indicatePessimisticFixpoint();
10561 } else {
10562 const AANoFPClass::StateType &S =
10563 static_cast<const AANoFPClass::StateType &>(AA->getState());
10564 T ^= S;
10565 }
10566 return T.isValidState();
10567 };
10568
10569 for (const auto &VAC : Values)
10570 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10571 return indicatePessimisticFixpoint();
10572
10573 return clampStateAndIndicateChange(getState(), T);
10574 }
10575
10576 /// See AbstractAttribute::trackStatistics()
10577 void trackStatistics() const override {
10579 }
10580};
10581
10582struct AANoFPClassReturned final
10583 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10584 AANoFPClassImpl::StateType, false,
10585 Attribute::None, false> {
10586 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10587 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10588 AANoFPClassImpl::StateType, false,
10589 Attribute::None, false>(IRP, A) {}
10590
10591 /// See AbstractAttribute::trackStatistics()
10592 void trackStatistics() const override {
10594 }
10595};
10596
10597struct AANoFPClassArgument final
10598 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10599 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10600 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10601
10602 /// See AbstractAttribute::trackStatistics()
10603 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10604};
10605
10606struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10607 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10608 : AANoFPClassFloating(IRP, A) {}
10609
10610 /// See AbstractAttribute::trackStatistics()
10611 void trackStatistics() const override {
10613 }
10614};
10615
10616struct AANoFPClassCallSiteReturned final
10617 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10618 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10619 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10620
10621 /// See AbstractAttribute::trackStatistics()
10622 void trackStatistics() const override {
10624 }
10625};
10626
10627struct AACallEdgesImpl : public AACallEdges {
10628 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10629
10630 const SetVector<Function *> &getOptimisticEdges() const override {
10631 return CalledFunctions;
10632 }
10633
10634 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10635
10636 bool hasNonAsmUnknownCallee() const override {
10637 return HasUnknownCalleeNonAsm;
10638 }
10639
10640 const std::string getAsStr(Attributor *A) const override {
10641 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10642 std::to_string(CalledFunctions.size()) + "]";
10643 }
10644
10645 void trackStatistics() const override {}
10646
10647protected:
10648 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10649 if (CalledFunctions.insert(Fn)) {
10650 Change = ChangeStatus::CHANGED;
10651 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10652 << "\n");
10653 }
10654 }
10655
10656 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10657 if (!HasUnknownCallee)
10658 Change = ChangeStatus::CHANGED;
10659 if (NonAsm && !HasUnknownCalleeNonAsm)
10660 Change = ChangeStatus::CHANGED;
10661 HasUnknownCalleeNonAsm |= NonAsm;
10662 HasUnknownCallee = true;
10663 }
10664
10665private:
10666 /// Optimistic set of functions that might be called by this position.
10667 SetVector<Function *> CalledFunctions;
10668
10669 /// Is there any call with a unknown callee.
10670 bool HasUnknownCallee = false;
10671
10672 /// Is there any call with a unknown callee, excluding any inline asm.
10673 bool HasUnknownCalleeNonAsm = false;
10674};
10675
10676struct AACallEdgesCallSite : public AACallEdgesImpl {
10677 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10678 : AACallEdgesImpl(IRP, A) {}
10679 /// See AbstractAttribute::updateImpl(...).
10680 ChangeStatus updateImpl(Attributor &A) override {
10681 ChangeStatus Change = ChangeStatus::UNCHANGED;
10682
10683 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10684 if (Function *Fn = dyn_cast<Function>(&V)) {
10685 addCalledFunction(Fn, Change);
10686 } else {
10687 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10688 setHasUnknownCallee(true, Change);
10689 }
10690
10691 // Explore all values.
10692 return true;
10693 };
10694
10696 // Process any value that we might call.
10697 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10698 if (isa<Constant>(V)) {
10699 VisitValue(*V, CtxI);
10700 return;
10701 }
10702
10703 bool UsedAssumedInformation = false;
10704 Values.clear();
10705 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10706 AA::AnyScope, UsedAssumedInformation)) {
10707 Values.push_back({*V, CtxI});
10708 }
10709 for (auto &VAC : Values)
10710 VisitValue(*VAC.getValue(), VAC.getCtxI());
10711 };
10712
10713 CallBase *CB = cast<CallBase>(getCtxI());
10714
10715 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10716 if (IA->hasSideEffects() &&
10717 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10718 !hasAssumption(*CB, "ompx_no_call_asm")) {
10719 setHasUnknownCallee(false, Change);
10720 }
10721 return Change;
10722 }
10723
10724 if (CB->isIndirectCall())
10725 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10726 *this, getIRPosition(), DepClassTy::OPTIONAL))
10727 if (IndirectCallAA->foreachCallee(
10728 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10729 return Change;
10730
10731 // The most simple case.
10732 ProcessCalledOperand(CB->getCalledOperand(), CB);
10733
10734 // Process callback functions.
10735 SmallVector<const Use *, 4u> CallbackUses;
10736 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10737 for (const Use *U : CallbackUses)
10738 ProcessCalledOperand(U->get(), CB);
10739
10740 return Change;
10741 }
10742};
10743
10744struct AACallEdgesFunction : public AACallEdgesImpl {
10745 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10746 : AACallEdgesImpl(IRP, A) {}
10747
10748 /// See AbstractAttribute::updateImpl(...).
10749 ChangeStatus updateImpl(Attributor &A) override {
10750 ChangeStatus Change = ChangeStatus::UNCHANGED;
10751
10752 auto ProcessCallInst = [&](Instruction &Inst) {
10753 CallBase &CB = cast<CallBase>(Inst);
10754
10755 auto *CBEdges = A.getAAFor<AACallEdges>(
10756 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10757 if (!CBEdges)
10758 return false;
10759 if (CBEdges->hasNonAsmUnknownCallee())
10760 setHasUnknownCallee(true, Change);
10761 if (CBEdges->hasUnknownCallee())
10762 setHasUnknownCallee(false, Change);
10763
10764 for (Function *F : CBEdges->getOptimisticEdges())
10765 addCalledFunction(F, Change);
10766
10767 return true;
10768 };
10769
10770 // Visit all callable instructions.
10771 bool UsedAssumedInformation = false;
10772 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10773 UsedAssumedInformation,
10774 /* CheckBBLivenessOnly */ true)) {
10775 // If we haven't looked at all call like instructions, assume that there
10776 // are unknown callees.
10777 setHasUnknownCallee(true, Change);
10778 }
10779
10780 return Change;
10781 }
10782};
10783
10784/// -------------------AAInterFnReachability Attribute--------------------------
10785
10786struct AAInterFnReachabilityFunction
10787 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10788 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10789 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10790 : Base(IRP, A) {}
10791
10792 bool instructionCanReach(
10793 Attributor &A, const Instruction &From, const Function &To,
10794 const AA::InstExclusionSetTy *ExclusionSet) const override {
10795 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10796 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10797
10798 RQITy StackRQI(A, From, To, ExclusionSet, false);
10799 RQITy::Reachable Result;
10800 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10801 return NonConstThis->isReachableImpl(A, StackRQI,
10802 /*IsTemporaryRQI=*/true);
10803 return Result == RQITy::Reachable::Yes;
10804 }
10805
10806 bool isReachableImpl(Attributor &A, RQITy &RQI,
10807 bool IsTemporaryRQI) override {
10808 const Instruction *EntryI =
10809 &RQI.From->getFunction()->getEntryBlock().front();
10810 if (EntryI != RQI.From &&
10811 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10812 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10813 IsTemporaryRQI);
10814
10815 auto CheckReachableCallBase = [&](CallBase *CB) {
10816 auto *CBEdges = A.getAAFor<AACallEdges>(
10817 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10818 if (!CBEdges || !CBEdges->getState().isValidState())
10819 return false;
10820 // TODO Check To backwards in this case.
10821 if (CBEdges->hasUnknownCallee())
10822 return false;
10823
10824 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10825 if (Fn == RQI.To)
10826 return false;
10827
10828 if (Fn->isDeclaration()) {
10829 if (Fn->hasFnAttribute(Attribute::NoCallback))
10830 continue;
10831 // TODO Check To backwards in this case.
10832 return false;
10833 }
10834
10835 if (Fn == getAnchorScope()) {
10836 if (EntryI == RQI.From)
10837 continue;
10838 return false;
10839 }
10840
10841 const AAInterFnReachability *InterFnReachability =
10842 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10843 DepClassTy::OPTIONAL);
10844
10845 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10846 if (!InterFnReachability ||
10847 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10848 RQI.ExclusionSet))
10849 return false;
10850 }
10851 return true;
10852 };
10853
10854 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10855 *this, IRPosition::function(*RQI.From->getFunction()),
10856 DepClassTy::OPTIONAL);
10857
10858 // Determine call like instructions that we can reach from the inst.
10859 auto CheckCallBase = [&](Instruction &CBInst) {
10860 // There are usually less nodes in the call graph, check inter function
10861 // reachability first.
10862 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10863 return true;
10864 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10865 A, *RQI.From, CBInst, RQI.ExclusionSet);
10866 };
10867
10868 bool UsedExclusionSet = /* conservative */ true;
10869 bool UsedAssumedInformation = false;
10870 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10871 UsedAssumedInformation,
10872 /* CheckBBLivenessOnly */ true))
10873 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10874 IsTemporaryRQI);
10875
10876 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10877 IsTemporaryRQI);
10878 }
10879
10880 void trackStatistics() const override {}
10881};
10882} // namespace
10883
10884template <typename AAType>
10885static std::optional<Constant *>
10887 const IRPosition &IRP, Type &Ty) {
10888 if (!Ty.isIntegerTy())
10889 return nullptr;
10890
10891 // This will also pass the call base context.
10892 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10893 if (!AA)
10894 return nullptr;
10895
10896 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10897
10898 if (!COpt.has_value()) {
10899 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10900 return std::nullopt;
10901 }
10902 if (auto *C = *COpt) {
10903 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10904 return C;
10905 }
10906 return nullptr;
10907}
10908
10910 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10912 Type &Ty = *IRP.getAssociatedType();
10913 std::optional<Value *> V;
10914 for (auto &It : Values) {
10915 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10916 if (V.has_value() && !*V)
10917 break;
10918 }
10919 if (!V.has_value())
10920 return UndefValue::get(&Ty);
10921 return *V;
10922}
10923
10924namespace {
10925struct AAPotentialValuesImpl : AAPotentialValues {
10926 using StateType = PotentialLLVMValuesState;
10927
10928 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10929 : AAPotentialValues(IRP, A) {}
10930
10931 /// See AbstractAttribute::initialize(..).
10932 void initialize(Attributor &A) override {
10933 if (A.hasSimplificationCallback(getIRPosition())) {
10934 indicatePessimisticFixpoint();
10935 return;
10936 }
10937 Value *Stripped = getAssociatedValue().stripPointerCasts();
10938 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10939 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10940 getAnchorScope());
10941 indicateOptimisticFixpoint();
10942 return;
10943 }
10944 AAPotentialValues::initialize(A);
10945 }
10946
10947 /// See AbstractAttribute::getAsStr().
10948 const std::string getAsStr(Attributor *A) const override {
10949 std::string Str;
10950 llvm::raw_string_ostream OS(Str);
10951 OS << getState();
10952 return Str;
10953 }
10954
10955 template <typename AAType>
10956 static std::optional<Value *> askOtherAA(Attributor &A,
10957 const AbstractAttribute &AA,
10958 const IRPosition &IRP, Type &Ty) {
10960 return &IRP.getAssociatedValue();
10961 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10962 if (!C)
10963 return std::nullopt;
10964 if (*C)
10965 if (auto *CC = AA::getWithType(**C, Ty))
10966 return CC;
10967 return nullptr;
10968 }
10969
10970 virtual void addValue(Attributor &A, StateType &State, Value &V,
10971 const Instruction *CtxI, AA::ValueScope S,
10972 Function *AnchorScope) const {
10973
10974 IRPosition ValIRP = IRPosition::value(V);
10975 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10976 for (const auto &U : CB->args()) {
10977 if (U.get() != &V)
10978 continue;
10979 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10980 break;
10981 }
10982 }
10983
10984 Value *VPtr = &V;
10985 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10986 Type &Ty = *getAssociatedType();
10987 std::optional<Value *> SimpleV =
10988 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10989 if (SimpleV.has_value() && !*SimpleV) {
10990 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10991 *this, ValIRP, DepClassTy::OPTIONAL);
10992 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10993 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10994 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10995 if (PotentialConstantsAA->undefIsContained())
10996 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10997 return;
10998 }
10999 }
11000 if (!SimpleV.has_value())
11001 return;
11002
11003 if (*SimpleV)
11004 VPtr = *SimpleV;
11005 }
11006
11007 if (isa<ConstantInt>(VPtr))
11008 CtxI = nullptr;
11009 if (!AA::isValidInScope(*VPtr, AnchorScope))
11011
11012 State.unionAssumed({{*VPtr, CtxI}, S});
11013 }
11014
11015 /// Helper struct to tie a value+context pair together with the scope for
11016 /// which this is the simplified version.
11017 struct ItemInfo {
11018 AA::ValueAndContext I;
11020
11021 bool operator==(const ItemInfo &II) const {
11022 return II.I == I && II.S == S;
11023 };
11024 bool operator<(const ItemInfo &II) const {
11025 return std::tie(I, S) < std::tie(II.I, II.S);
11026 };
11027 };
11028
11029 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11030 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11031 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11032 if (!(CS & S))
11033 continue;
11034
11035 bool UsedAssumedInformation = false;
11037 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11038 UsedAssumedInformation))
11039 return false;
11040
11041 for (auto &It : Values)
11042 ValueScopeMap[It] += CS;
11043 }
11044 for (auto &It : ValueScopeMap)
11045 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11046 AA::ValueScope(It.second), getAnchorScope());
11047
11048 return true;
11049 }
11050
11051 void giveUpOnIntraprocedural(Attributor &A) {
11052 auto NewS = StateType::getBestState(getState());
11053 for (const auto &It : getAssumedSet()) {
11054 if (It.second == AA::Intraprocedural)
11055 continue;
11056 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11057 AA::Interprocedural, getAnchorScope());
11058 }
11059 assert(!undefIsContained() && "Undef should be an explicit value!");
11060 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11061 getAnchorScope());
11062 getState() = NewS;
11063 }
11064
11065 /// See AbstractState::indicatePessimisticFixpoint(...).
11066 ChangeStatus indicatePessimisticFixpoint() override {
11067 getState() = StateType::getBestState(getState());
11068 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11069 AAPotentialValues::indicateOptimisticFixpoint();
11070 return ChangeStatus::CHANGED;
11071 }
11072
11073 /// See AbstractAttribute::updateImpl(...).
11074 ChangeStatus updateImpl(Attributor &A) override {
11075 return indicatePessimisticFixpoint();
11076 }
11077
11078 /// See AbstractAttribute::manifest(...).
11079 ChangeStatus manifest(Attributor &A) override {
11082 Values.clear();
11083 if (!getAssumedSimplifiedValues(A, Values, S))
11084 continue;
11085 Value &OldV = getAssociatedValue();
11086 if (isa<UndefValue>(OldV))
11087 continue;
11088 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11089 if (!NewV || NewV == &OldV)
11090 continue;
11091 if (getCtxI() &&
11092 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11093 continue;
11094 if (A.changeAfterManifest(getIRPosition(), *NewV))
11095 return ChangeStatus::CHANGED;
11096 }
11097 return ChangeStatus::UNCHANGED;
11098 }
11099
11100 bool getAssumedSimplifiedValues(
11101 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11102 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11103 if (!isValidState())
11104 return false;
11105 bool UsedAssumedInformation = false;
11106 for (const auto &It : getAssumedSet())
11107 if (It.second & S) {
11108 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11109 isa<SelectInst>(It.first.getValue()))) {
11110 if (A.getAssumedSimplifiedValues(
11111 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11112 this, Values, S, UsedAssumedInformation))
11113 continue;
11114 }
11115 Values.push_back(It.first);
11116 }
11117 assert(!undefIsContained() && "Undef should be an explicit value!");
11118 return true;
11119 }
11120};
11121
11122struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11123 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11124 : AAPotentialValuesImpl(IRP, A) {}
11125
11126 /// See AbstractAttribute::updateImpl(...).
11127 ChangeStatus updateImpl(Attributor &A) override {
11128 auto AssumedBefore = getAssumed();
11129
11130 genericValueTraversal(A, &getAssociatedValue());
11131
11132 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11133 : ChangeStatus::CHANGED;
11134 }
11135
11136 /// Helper struct to remember which AAIsDead instances we actually used.
11137 struct LivenessInfo {
11138 const AAIsDead *LivenessAA = nullptr;
11139 bool AnyDead = false;
11140 };
11141
11142 /// Check if \p Cmp is a comparison we can simplify.
11143 ///
11144 /// We handle multiple cases, one in which at least one operand is an
11145 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11146 /// operand. Return true if successful, in that case Worklist will be updated.
11147 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11148 CmpInst::Predicate Pred, ItemInfo II,
11149 SmallVectorImpl<ItemInfo> &Worklist) {
11150
11151 // Simplify the operands first.
11152 bool UsedAssumedInformation = false;
11153 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11154 auto GetSimplifiedValues = [&](Value &V,
11156 if (!A.getAssumedSimplifiedValues(
11157 IRPosition::value(V, getCallBaseContext()), this, Values,
11158 AA::Intraprocedural, UsedAssumedInformation)) {
11159 Values.clear();
11160 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11161 }
11162 return Values.empty();
11163 };
11164 if (GetSimplifiedValues(*LHS, LHSValues))
11165 return true;
11166 if (GetSimplifiedValues(*RHS, RHSValues))
11167 return true;
11168
11169 LLVMContext &Ctx = LHS->getContext();
11170
11171 InformationCache &InfoCache = A.getInfoCache();
11172 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11173 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11174 const auto *DT =
11175 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11176 : nullptr;
11177 const auto *TLI =
11178 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11179 auto *AC =
11180 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11181 : nullptr;
11182
11183 const DataLayout &DL = A.getDataLayout();
11184 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11185
11186 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11187 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11188 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11189 /* CtxI */ nullptr, II.S, getAnchorScope());
11190 return true;
11191 }
11192
11193 // Handle the trivial case first in which we don't even need to think
11194 // about null or non-null.
11195 if (&LHSV == &RHSV &&
11197 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11199 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11200 getAnchorScope());
11201 return true;
11202 }
11203
11204 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11205 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11206 if (TypedLHS && TypedRHS) {
11207 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11208 if (NewV && NewV != &Cmp) {
11209 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11210 getAnchorScope());
11211 return true;
11212 }
11213 }
11214
11215 // From now on we only handle equalities (==, !=).
11216 if (!CmpInst::isEquality(Pred))
11217 return false;
11218
11219 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11220 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11221 if (!LHSIsNull && !RHSIsNull)
11222 return false;
11223
11224 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11225 // non-nullptr operand and if we assume it's non-null we can conclude the
11226 // result of the comparison.
11227 assert((LHSIsNull || RHSIsNull) &&
11228 "Expected nullptr versus non-nullptr comparison at this point");
11229
11230 // The index is the operand that we assume is not null.
11231 unsigned PtrIdx = LHSIsNull;
11232 bool IsKnownNonNull;
11233 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11234 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11235 DepClassTy::REQUIRED, IsKnownNonNull);
11236 if (!IsAssumedNonNull)
11237 return false;
11238
11239 // The new value depends on the predicate, true for != and false for ==.
11240 Constant *NewV =
11241 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11242 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11243 getAnchorScope());
11244 return true;
11245 };
11246
11247 for (auto &LHSValue : LHSValues)
11248 for (auto &RHSValue : RHSValues)
11249 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11250 return false;
11251 return true;
11252 }
11253
11254 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11255 SmallVectorImpl<ItemInfo> &Worklist) {
11256 const Instruction *CtxI = II.I.getCtxI();
11257 bool UsedAssumedInformation = false;
11258
11259 std::optional<Constant *> C =
11260 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11261 bool NoValueYet = !C.has_value();
11262 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11263 return true;
11264 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11265 if (CI->isZero())
11266 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11267 else
11268 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11269 } else if (&SI == &getAssociatedValue()) {
11270 // We could not simplify the condition, assume both values.
11271 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11272 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11273 } else {
11274 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11275 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11276 if (!SimpleV.has_value())
11277 return true;
11278 if (*SimpleV) {
11279 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11280 return true;
11281 }
11282 return false;
11283 }
11284 return true;
11285 }
11286
11287 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11288 SmallVectorImpl<ItemInfo> &Worklist) {
11289 SmallSetVector<Value *, 4> PotentialCopies;
11290 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11291 bool UsedAssumedInformation = false;
11292 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11293 PotentialValueOrigins, *this,
11294 UsedAssumedInformation,
11295 /* OnlyExact */ true)) {
11296 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11297 "loaded values for load instruction "
11298 << LI << "\n");
11299 return false;
11300 }
11301
11302 // Do not simplify loads that are only used in llvm.assume if we cannot also
11303 // remove all stores that may feed into the load. The reason is that the
11304 // assume is probably worth something as long as the stores are around.
11305 InformationCache &InfoCache = A.getInfoCache();
11306 if (InfoCache.isOnlyUsedByAssume(LI)) {
11307 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11308 if (!I || isa<AssumeInst>(I))
11309 return true;
11310 if (auto *SI = dyn_cast<StoreInst>(I))
11311 return A.isAssumedDead(SI->getOperandUse(0), this,
11312 /* LivenessAA */ nullptr,
11313 UsedAssumedInformation,
11314 /* CheckBBLivenessOnly */ false);
11315 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11316 UsedAssumedInformation,
11317 /* CheckBBLivenessOnly */ false);
11318 })) {
11319 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11320 "and we cannot delete all the stores: "
11321 << LI << "\n");
11322 return false;
11323 }
11324 }
11325
11326 // Values have to be dynamically unique or we loose the fact that a
11327 // single llvm::Value might represent two runtime values (e.g.,
11328 // stack locations in different recursive calls).
11329 const Instruction *CtxI = II.I.getCtxI();
11330 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11331 bool AllLocal = ScopeIsLocal;
11332 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11333 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11334 return AA::isDynamicallyUnique(A, *this, *PC);
11335 });
11336 if (!DynamicallyUnique) {
11337 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11338 "values are dynamically unique: "
11339 << LI << "\n");
11340 return false;
11341 }
11342
11343 for (auto *PotentialCopy : PotentialCopies) {
11344 if (AllLocal) {
11345 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11346 } else {
11347 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11348 }
11349 }
11350 if (!AllLocal && ScopeIsLocal)
11351 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11352 return true;
11353 }
11354
11355 bool handlePHINode(
11356 Attributor &A, PHINode &PHI, ItemInfo II,
11357 SmallVectorImpl<ItemInfo> &Worklist,
11358 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11359 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11360 LivenessInfo &LI = LivenessAAs[&F];
11361 if (!LI.LivenessAA)
11362 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11363 DepClassTy::NONE);
11364 return LI;
11365 };
11366
11367 if (&PHI == &getAssociatedValue()) {
11368 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11369 const auto *CI =
11370 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11371 *PHI.getFunction());
11372
11373 Cycle *C = nullptr;
11374 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11375 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11376 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11377 if (LI.LivenessAA &&
11378 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11379 LI.AnyDead = true;
11380 continue;
11381 }
11382 Value *V = PHI.getIncomingValue(u);
11383 if (V == &PHI)
11384 continue;
11385
11386 // If the incoming value is not the PHI but an instruction in the same
11387 // cycle we might have multiple versions of it flying around.
11388 if (CyclePHI && isa<Instruction>(V) &&
11389 (!C || C->contains(cast<Instruction>(V)->getParent())))
11390 return false;
11391
11392 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11393 }
11394 return true;
11395 }
11396
11397 bool UsedAssumedInformation = false;
11398 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11399 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11400 if (!SimpleV.has_value())
11401 return true;
11402 if (!(*SimpleV))
11403 return false;
11404 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11405 return true;
11406 }
11407
11408 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11409 /// simplify any operand of the instruction \p I. Return true if successful,
11410 /// in that case Worklist will be updated.
11411 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11412 SmallVectorImpl<ItemInfo> &Worklist) {
11413 bool SomeSimplified = false;
11414 bool UsedAssumedInformation = false;
11415
11416 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11417 int Idx = 0;
11418 for (Value *Op : I.operands()) {
11419 const auto &SimplifiedOp = A.getAssumedSimplified(
11420 IRPosition::value(*Op, getCallBaseContext()), *this,
11421 UsedAssumedInformation, AA::Intraprocedural);
11422 // If we are not sure about any operand we are not sure about the entire
11423 // instruction, we'll wait.
11424 if (!SimplifiedOp.has_value())
11425 return true;
11426
11427 if (*SimplifiedOp)
11428 NewOps[Idx] = *SimplifiedOp;
11429 else
11430 NewOps[Idx] = Op;
11431
11432 SomeSimplified |= (NewOps[Idx] != Op);
11433 ++Idx;
11434 }
11435
11436 // We won't bother with the InstSimplify interface if we didn't simplify any
11437 // operand ourselves.
11438 if (!SomeSimplified)
11439 return false;
11440
11441 InformationCache &InfoCache = A.getInfoCache();
11442 Function *F = I.getFunction();
11443 const auto *DT =
11444 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11445 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11446 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11447
11448 const DataLayout &DL = I.getDataLayout();
11449 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11450 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11451 if (!NewV || NewV == &I)
11452 return false;
11453
11454 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11455 << *NewV << "\n");
11456 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11457 return true;
11458 }
11459
11461 Attributor &A, Instruction &I, ItemInfo II,
11462 SmallVectorImpl<ItemInfo> &Worklist,
11463 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11464 if (auto *CI = dyn_cast<CmpInst>(&I))
11465 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11466 CI->getPredicate(), II, Worklist);
11467
11468 switch (I.getOpcode()) {
11469 case Instruction::Select:
11470 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11471 case Instruction::PHI:
11472 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11473 case Instruction::Load:
11474 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11475 default:
11476 return handleGenericInst(A, I, II, Worklist);
11477 };
11478 return false;
11479 }
11480
11481 void genericValueTraversal(Attributor &A, Value *InitialV) {
11482 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11483
11484 SmallSet<ItemInfo, 16> Visited;
11486 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11487
11488 int Iteration = 0;
11489 do {
11490 ItemInfo II = Worklist.pop_back_val();
11491 Value *V = II.I.getValue();
11492 assert(V);
11493 const Instruction *CtxI = II.I.getCtxI();
11494 AA::ValueScope S = II.S;
11495
11496 // Check if we should process the current value. To prevent endless
11497 // recursion keep a record of the values we followed!
11498 if (!Visited.insert(II).second)
11499 continue;
11500
11501 // Make sure we limit the compile time for complex expressions.
11502 if (Iteration++ >= MaxPotentialValuesIterations) {
11503 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11504 << Iteration << "!\n");
11505 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11506 continue;
11507 }
11508
11509 // Explicitly look through calls with a "returned" attribute if we do
11510 // not have a pointer as stripPointerCasts only works on them.
11511 Value *NewV = nullptr;
11512 if (V->getType()->isPointerTy()) {
11513 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11514 } else {
11515 if (auto *CB = dyn_cast<CallBase>(V))
11516 if (auto *Callee =
11518 for (Argument &Arg : Callee->args())
11519 if (Arg.hasReturnedAttr()) {
11520 NewV = CB->getArgOperand(Arg.getArgNo());
11521 break;
11522 }
11523 }
11524 }
11525 if (NewV && NewV != V) {
11526 Worklist.push_back({{*NewV, CtxI}, S});
11527 continue;
11528 }
11529
11530 if (auto *I = dyn_cast<Instruction>(V)) {
11531 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11532 continue;
11533 }
11534
11535 if (V != InitialV || isa<Argument>(V))
11536 if (recurseForValue(A, IRPosition::value(*V), II.S))
11537 continue;
11538
11539 // If we haven't stripped anything we give up.
11540 if (V == InitialV && CtxI == getCtxI()) {
11541 indicatePessimisticFixpoint();
11542 return;
11543 }
11544
11545 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11546 } while (!Worklist.empty());
11547
11548 // If we actually used liveness information so we have to record a
11549 // dependence.
11550 for (auto &It : LivenessAAs)
11551 if (It.second.AnyDead)
11552 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11553 }
11554
11555 /// See AbstractAttribute::trackStatistics()
11556 void trackStatistics() const override {
11557 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11558 }
11559};
11560
11561struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11562 using Base = AAPotentialValuesImpl;
11563 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11564 : Base(IRP, A) {}
11565
11566 /// See AbstractAttribute::initialize(..).
11567 void initialize(Attributor &A) override {
11568 auto &Arg = cast<Argument>(getAssociatedValue());
11570 indicatePessimisticFixpoint();
11571 }
11572
11573 /// See AbstractAttribute::updateImpl(...).
11574 ChangeStatus updateImpl(Attributor &A) override {
11575 auto AssumedBefore = getAssumed();
11576
11577 unsigned ArgNo = getCalleeArgNo();
11578
11579 bool UsedAssumedInformation = false;
11581 auto CallSitePred = [&](AbstractCallSite ACS) {
11582 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11583 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11584 return false;
11585
11586 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11588 UsedAssumedInformation))
11589 return false;
11590
11591 return isValidState();
11592 };
11593
11594 if (!A.checkForAllCallSites(CallSitePred, *this,
11595 /* RequireAllCallSites */ true,
11596 UsedAssumedInformation))
11597 return indicatePessimisticFixpoint();
11598
11599 Function *Fn = getAssociatedFunction();
11600 bool AnyNonLocal = false;
11601 for (auto &It : Values) {
11602 if (isa<Constant>(It.getValue())) {
11603 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11604 getAnchorScope());
11605 continue;
11606 }
11607 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11608 return indicatePessimisticFixpoint();
11609
11610 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11611 if (Arg->getParent() == Fn) {
11612 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11613 getAnchorScope());
11614 continue;
11615 }
11616 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11617 getAnchorScope());
11618 AnyNonLocal = true;
11619 }
11620 assert(!undefIsContained() && "Undef should be an explicit value!");
11621 if (AnyNonLocal)
11622 giveUpOnIntraprocedural(A);
11623
11624 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11625 : ChangeStatus::CHANGED;
11626 }
11627
11628 /// See AbstractAttribute::trackStatistics()
11629 void trackStatistics() const override {
11630 STATS_DECLTRACK_ARG_ATTR(potential_values)
11631 }
11632};
11633
11634struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11635 using Base = AAPotentialValuesFloating;
11636 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11637 : Base(IRP, A) {}
11638
11639 /// See AbstractAttribute::initialize(..).
11640 void initialize(Attributor &A) override {
11641 Function *F = getAssociatedFunction();
11642 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11643 indicatePessimisticFixpoint();
11644 return;
11645 }
11646
11647 for (Argument &Arg : F->args())
11648 if (Arg.hasReturnedAttr()) {
11649 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11650 ReturnedArg = &Arg;
11651 break;
11652 }
11653 if (!A.isFunctionIPOAmendable(*F) ||
11654 A.hasSimplificationCallback(getIRPosition())) {
11655 if (!ReturnedArg)
11656 indicatePessimisticFixpoint();
11657 else
11658 indicateOptimisticFixpoint();
11659 }
11660 }
11661
11662 /// See AbstractAttribute::updateImpl(...).
11663 ChangeStatus updateImpl(Attributor &A) override {
11664 auto AssumedBefore = getAssumed();
11665 bool UsedAssumedInformation = false;
11666
11668 Function *AnchorScope = getAnchorScope();
11669 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11670 bool AddValues) {
11672 Values.clear();
11673 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11674 UsedAssumedInformation,
11675 /* RecurseForSelectAndPHI */ true))
11676 return false;
11677 if (!AddValues)
11678 continue;
11679
11680 bool AllInterAreIntra = false;
11681 if (S == AA::Interprocedural)
11682 AllInterAreIntra =
11683 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11684 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11685 });
11686
11687 for (const AA::ValueAndContext &VAC : Values) {
11688 addValue(A, getState(), *VAC.getValue(),
11689 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11690 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11691 }
11692 if (AllInterAreIntra)
11693 break;
11694 }
11695 return true;
11696 };
11697
11698 if (ReturnedArg) {
11699 HandleReturnedValue(*ReturnedArg, nullptr, true);
11700 } else {
11701 auto RetInstPred = [&](Instruction &RetI) {
11702 bool AddValues = true;
11703 if (isa<PHINode>(RetI.getOperand(0)) ||
11704 isa<SelectInst>(RetI.getOperand(0))) {
11705 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11706 AnchorScope);
11707 AddValues = false;
11708 }
11709 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11710 };
11711
11712 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11713 UsedAssumedInformation,
11714 /* CheckBBLivenessOnly */ true))
11715 return indicatePessimisticFixpoint();
11716 }
11717
11718 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11719 : ChangeStatus::CHANGED;
11720 }
11721
11722 ChangeStatus manifest(Attributor &A) override {
11723 if (ReturnedArg)
11724 return ChangeStatus::UNCHANGED;
11726 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11727 /* RecurseForSelectAndPHI */ true))
11728 return ChangeStatus::UNCHANGED;
11729 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11730 if (!NewVal)
11731 return ChangeStatus::UNCHANGED;
11732
11733 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11734 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11735 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11736 "Number of function with unique return");
11737 Changed |= A.manifestAttrs(
11739 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11740 STATS_DECLTRACK_ARG_ATTR(returned);
11741 }
11742
11743 auto RetInstPred = [&](Instruction &RetI) {
11744 Value *RetOp = RetI.getOperand(0);
11745 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11746 return true;
11747 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11748 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11749 Changed = ChangeStatus::CHANGED;
11750 return true;
11751 };
11752 bool UsedAssumedInformation = false;
11753 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11754 UsedAssumedInformation,
11755 /* CheckBBLivenessOnly */ true);
11756 return Changed;
11757 }
11758
11759 ChangeStatus indicatePessimisticFixpoint() override {
11760 return AAPotentialValues::indicatePessimisticFixpoint();
11761 }
11762
11763 /// See AbstractAttribute::trackStatistics()
11764 void trackStatistics() const override{
11765 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11766
11767 /// The argumented with an existing `returned` attribute.
11768 Argument *ReturnedArg = nullptr;
11769};
11770
11771struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11772 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11773 : AAPotentialValuesImpl(IRP, A) {}
11774
11775 /// See AbstractAttribute::updateImpl(...).
11776 ChangeStatus updateImpl(Attributor &A) override {
11777 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11778 "not be called");
11779 }
11780
11781 /// See AbstractAttribute::trackStatistics()
11782 void trackStatistics() const override {
11783 STATS_DECLTRACK_FN_ATTR(potential_values)
11784 }
11785};
11786
11787struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11788 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11789 : AAPotentialValuesFunction(IRP, A) {}
11790
11791 /// See AbstractAttribute::trackStatistics()
11792 void trackStatistics() const override {
11793 STATS_DECLTRACK_CS_ATTR(potential_values)
11794 }
11795};
11796
11797struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11798 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11799 : AAPotentialValuesImpl(IRP, A) {}
11800
11801 /// See AbstractAttribute::updateImpl(...).
11802 ChangeStatus updateImpl(Attributor &A) override {
11803 auto AssumedBefore = getAssumed();
11804
11805 Function *Callee = getAssociatedFunction();
11806 if (!Callee)
11807 return indicatePessimisticFixpoint();
11808
11809 bool UsedAssumedInformation = false;
11810 auto *CB = cast<CallBase>(getCtxI());
11811 if (CB->isMustTailCall() &&
11812 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11813 UsedAssumedInformation))
11814 return indicatePessimisticFixpoint();
11815
11816 Function *Caller = CB->getCaller();
11817
11818 auto AddScope = [&](AA::ValueScope S) {
11820 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11821 Values, S, UsedAssumedInformation))
11822 return false;
11823
11824 for (auto &It : Values) {
11825 Value *V = It.getValue();
11826 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11827 V, *CB, *this, UsedAssumedInformation);
11828 if (!CallerV.has_value()) {
11829 // Nothing to do as long as no value was determined.
11830 continue;
11831 }
11832 V = *CallerV ? *CallerV : V;
11833 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11834 if (recurseForValue(A, IRPosition::value(*V), S))
11835 continue;
11836 }
11837 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11838 giveUpOnIntraprocedural(A);
11839 return true;
11840 }
11841 addValue(A, getState(), *V, CB, S, getAnchorScope());
11842 }
11843 return true;
11844 };
11845 if (!AddScope(AA::Intraprocedural))
11846 return indicatePessimisticFixpoint();
11847 if (!AddScope(AA::Interprocedural))
11848 return indicatePessimisticFixpoint();
11849 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11850 : ChangeStatus::CHANGED;
11851 }
11852
11853 ChangeStatus indicatePessimisticFixpoint() override {
11854 return AAPotentialValues::indicatePessimisticFixpoint();
11855 }
11856
11857 /// See AbstractAttribute::trackStatistics()
11858 void trackStatistics() const override {
11859 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11860 }
11861};
11862
11863struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11864 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11865 : AAPotentialValuesFloating(IRP, A) {}
11866
11867 /// See AbstractAttribute::trackStatistics()
11868 void trackStatistics() const override {
11869 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11870 }
11871};
11872} // namespace
11873
11874/// ---------------------- Assumption Propagation ------------------------------
11875namespace {
11876struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11877 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11878 const DenseSet<StringRef> &Known)
11879 : AAAssumptionInfo(IRP, A, Known) {}
11880
11881 /// See AbstractAttribute::manifest(...).
11882 ChangeStatus manifest(Attributor &A) override {
11883 // Don't manifest a universal set if it somehow made it here.
11884 if (getKnown().isUniversal())
11885 return ChangeStatus::UNCHANGED;
11886
11887 const IRPosition &IRP = getIRPosition();
11888 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11889 getAssumed().getSet().end());
11890 llvm::sort(Set);
11891 return A.manifestAttrs(IRP,
11892 Attribute::get(IRP.getAnchorValue().getContext(),
11894 llvm::join(Set, ",")),
11895 /*ForceReplace=*/true);
11896 }
11897
11898 bool hasAssumption(const StringRef Assumption) const override {
11899 return isValidState() && setContains(Assumption);
11900 }
11901
11902 /// See AbstractAttribute::getAsStr()
11903 const std::string getAsStr(Attributor *A) const override {
11904 const SetContents &Known = getKnown();
11905 const SetContents &Assumed = getAssumed();
11906
11907 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11908 llvm::sort(Set);
11909 const std::string KnownStr = llvm::join(Set, ",");
11910
11911 std::string AssumedStr = "Universal";
11912 if (!Assumed.isUniversal()) {
11913 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11914 AssumedStr = llvm::join(Set, ",");
11915 }
11916 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11917 }
11918};
11919
11920/// Propagates assumption information from parent functions to all of their
11921/// successors. An assumption can be propagated if the containing function
11922/// dominates the called function.
11923///
11924/// We start with a "known" set of assumptions already valid for the associated
11925/// function and an "assumed" set that initially contains all possible
11926/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11927/// contents as concrete values are known. The concrete values are seeded by the
11928/// first nodes that are either entries into the call graph, or contains no
11929/// assumptions. Each node is updated as the intersection of the assumed state
11930/// with all of its predecessors.
11931struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11932 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11933 : AAAssumptionInfoImpl(IRP, A,
11934 getAssumptions(*IRP.getAssociatedFunction())) {}
11935
11936 /// See AbstractAttribute::updateImpl(...).
11937 ChangeStatus updateImpl(Attributor &A) override {
11938 bool Changed = false;
11939
11940 auto CallSitePred = [&](AbstractCallSite ACS) {
11941 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11942 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11943 DepClassTy::REQUIRED);
11944 if (!AssumptionAA)
11945 return false;
11946 // Get the set of assumptions shared by all of this function's callers.
11947 Changed |= getIntersection(AssumptionAA->getAssumed());
11948 return !getAssumed().empty() || !getKnown().empty();
11949 };
11950
11951 bool UsedAssumedInformation = false;
11952 // Get the intersection of all assumptions held by this node's predecessors.
11953 // If we don't know all the call sites then this is either an entry into the
11954 // call graph or an empty node. This node is known to only contain its own
11955 // assumptions and can be propagated to its successors.
11956 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11957 UsedAssumedInformation))
11958 return indicatePessimisticFixpoint();
11959
11960 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11961 }
11962
11963 void trackStatistics() const override {}
11964};
11965
11966/// Assumption Info defined for call sites.
11967struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11968
11969 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11970 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11971
11972 /// See AbstractAttribute::initialize(...).
11973 void initialize(Attributor &A) override {
11974 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11975 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11976 }
11977
11978 /// See AbstractAttribute::updateImpl(...).
11979 ChangeStatus updateImpl(Attributor &A) override {
11980 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11981 auto *AssumptionAA =
11982 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11983 if (!AssumptionAA)
11984 return indicatePessimisticFixpoint();
11985 bool Changed = getIntersection(AssumptionAA->getAssumed());
11986 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11987 }
11988
11989 /// See AbstractAttribute::trackStatistics()
11990 void trackStatistics() const override {}
11991
11992private:
11993 /// Helper to initialized the known set as all the assumptions this call and
11994 /// the callee contain.
11995 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11996 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11997 auto Assumptions = getAssumptions(CB);
11998 if (const Function *F = CB.getCaller())
11999 set_union(Assumptions, getAssumptions(*F));
12000 if (Function *F = IRP.getAssociatedFunction())
12001 set_union(Assumptions, getAssumptions(*F));
12002 return Assumptions;
12003 }
12004};
12005} // namespace
12006
12008 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12009 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12010}
12011
12013
12014/// ------------------------ UnderlyingObjects ---------------------------------
12015
12016namespace {
12017struct AAUnderlyingObjectsImpl
12018 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12020 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12021
12022 /// See AbstractAttribute::getAsStr().
12023 const std::string getAsStr(Attributor *A) const override {
12024 if (!isValidState())
12025 return "<invalid>";
12026 std::string Str;
12028 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12029 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12030 << " objects.\n";
12031 if (!InterAssumedUnderlyingObjects.empty()) {
12032 OS << "inter objects:\n";
12033 for (auto *Obj : InterAssumedUnderlyingObjects)
12034 OS << *Obj << '\n';
12035 }
12036 if (!IntraAssumedUnderlyingObjects.empty()) {
12037 OS << "intra objects:\n";
12038 for (auto *Obj : IntraAssumedUnderlyingObjects)
12039 OS << *Obj << '\n';
12040 }
12041 return Str;
12042 }
12043
12044 /// See AbstractAttribute::trackStatistics()
12045 void trackStatistics() const override {}
12046
12047 /// See AbstractAttribute::updateImpl(...).
12048 ChangeStatus updateImpl(Attributor &A) override {
12049 auto &Ptr = getAssociatedValue();
12050
12051 bool UsedAssumedInformation = false;
12052 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12054 SmallPtrSet<Value *, 8> SeenObjects;
12056
12057 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12058 Scope, UsedAssumedInformation))
12059 return UnderlyingObjects.insert(&Ptr);
12060
12061 bool Changed = false;
12062
12063 for (unsigned I = 0; I < Values.size(); ++I) {
12064 auto &VAC = Values[I];
12065 auto *Obj = VAC.getValue();
12066 Value *UO = getUnderlyingObject(Obj);
12067 if (!SeenObjects.insert(UO ? UO : Obj).second)
12068 continue;
12069 if (UO && UO != Obj) {
12070 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12071 Changed |= UnderlyingObjects.insert(UO);
12072 continue;
12073 }
12074
12075 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12076 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12077 auto Pred = [&](Value &V) {
12078 if (&V == UO)
12079 Changed |= UnderlyingObjects.insert(UO);
12080 else
12081 Values.emplace_back(V, nullptr);
12082 return true;
12083 };
12084
12085 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12087 "The forall call should not return false at this position");
12088 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12089 continue;
12090 }
12091
12092 if (isa<SelectInst>(Obj)) {
12093 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12094 UsedAssumedInformation);
12095 continue;
12096 }
12097 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12098 // Explicitly look through PHIs as we do not care about dynamically
12099 // uniqueness.
12100 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12101 Changed |=
12102 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12103 Scope, UsedAssumedInformation);
12104 }
12105 continue;
12106 }
12107
12108 Changed |= UnderlyingObjects.insert(Obj);
12109 }
12110
12111 return Changed;
12112 };
12113
12114 bool Changed = false;
12115 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12116 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12117 if (!UsedAssumedInformation)
12118 indicateOptimisticFixpoint();
12119 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12120 }
12121
12122 bool forallUnderlyingObjects(
12123 function_ref<bool(Value &)> Pred,
12124 AA::ValueScope Scope = AA::Interprocedural) const override {
12125 if (!isValidState())
12126 return Pred(getAssociatedValue());
12127
12128 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12129 ? IntraAssumedUnderlyingObjects
12130 : InterAssumedUnderlyingObjects;
12131 for (Value *Obj : AssumedUnderlyingObjects)
12132 if (!Pred(*Obj))
12133 return false;
12134
12135 return true;
12136 }
12137
12138private:
12139 /// Handle the case where the value is not the actual underlying value, such
12140 /// as a phi node or a select instruction.
12141 bool handleIndirect(Attributor &A, Value &V,
12142 SmallSetVector<Value *, 8> &UnderlyingObjects,
12143 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12144 bool Changed = false;
12145 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12146 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12147 auto Pred = [&](Value &V) {
12148 Changed |= UnderlyingObjects.insert(&V);
12149 return true;
12150 };
12151 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12153 "The forall call should not return false at this position");
12154 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12155 return Changed;
12156 }
12157
12158 /// All the underlying objects collected so far via intra procedural scope.
12159 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12160 /// All the underlying objects collected so far via inter procedural scope.
12161 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12162};
12163
12164struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12165 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12166 : AAUnderlyingObjectsImpl(IRP, A) {}
12167};
12168
12169struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12170 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12171 : AAUnderlyingObjectsImpl(IRP, A) {}
12172};
12173
12174struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12175 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12176 : AAUnderlyingObjectsImpl(IRP, A) {}
12177};
12178
12179struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12180 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12181 : AAUnderlyingObjectsImpl(IRP, A) {}
12182};
12183
12184struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12185 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12186 : AAUnderlyingObjectsImpl(IRP, A) {}
12187};
12188
12189struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12190 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12191 : AAUnderlyingObjectsImpl(IRP, A) {}
12192};
12193
12194struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12195 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12196 : AAUnderlyingObjectsImpl(IRP, A) {}
12197};
12198} // namespace
12199
12200/// ------------------------ Global Value Info -------------------------------
12201namespace {
12202struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12203 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12204 : AAGlobalValueInfo(IRP, A) {}
12205
12206 /// See AbstractAttribute::initialize(...).
12207 void initialize(Attributor &A) override {}
12208
12209 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12210 SmallVectorImpl<const Value *> &Worklist) {
12211 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12212 if (!UInst) {
12213 Follow = true;
12214 return true;
12215 }
12216
12217 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12218 << *UInst << "\n");
12219
12220 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12221 int Idx = &Cmp->getOperandUse(0) == &U;
12222 if (isa<Constant>(Cmp->getOperand(Idx)))
12223 return true;
12224 return U == &getAnchorValue();
12225 }
12226
12227 // Explicitly catch return instructions.
12228 if (isa<ReturnInst>(UInst)) {
12229 auto CallSitePred = [&](AbstractCallSite ACS) {
12230 Worklist.push_back(ACS.getInstruction());
12231 return true;
12232 };
12233 bool UsedAssumedInformation = false;
12234 // TODO: We should traverse the uses or add a "non-call-site" CB.
12235 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12236 /*RequireAllCallSites=*/true, this,
12237 UsedAssumedInformation))
12238 return false;
12239 return true;
12240 }
12241
12242 // For now we only use special logic for call sites. However, the tracker
12243 // itself knows about a lot of other non-capturing cases already.
12244 auto *CB = dyn_cast<CallBase>(UInst);
12245 if (!CB)
12246 return false;
12247 // Direct calls are OK uses.
12248 if (CB->isCallee(&U))
12249 return true;
12250 // Non-argument uses are scary.
12251 if (!CB->isArgOperand(&U))
12252 return false;
12253 // TODO: Iterate callees.
12254 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12255 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12256 return false;
12257
12258 unsigned ArgNo = CB->getArgOperandNo(&U);
12259 Worklist.push_back(Fn->getArg(ArgNo));
12260 return true;
12261 }
12262
12263 ChangeStatus updateImpl(Attributor &A) override {
12264 unsigned NumUsesBefore = Uses.size();
12265
12266 SmallPtrSet<const Value *, 8> Visited;
12268 Worklist.push_back(&getAnchorValue());
12269
12270 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12271 Uses.insert(&U);
12272 // TODO(captures): Make this more precise.
12273 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12274 if (CI.isPassthrough()) {
12275 Follow = true;
12276 return true;
12277 }
12278 return checkUse(A, U, Follow, Worklist);
12279 };
12280 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12281 Uses.insert(&OldU);
12282 return true;
12283 };
12284
12285 while (!Worklist.empty()) {
12286 const Value *V = Worklist.pop_back_val();
12287 if (!Visited.insert(V).second)
12288 continue;
12289 if (!A.checkForAllUses(UsePred, *this, *V,
12290 /* CheckBBLivenessOnly */ true,
12291 DepClassTy::OPTIONAL,
12292 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12293 return indicatePessimisticFixpoint();
12294 }
12295 }
12296
12297 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12298 : ChangeStatus::CHANGED;
12299 }
12300
12301 bool isPotentialUse(const Use &U) const override {
12302 return !isValidState() || Uses.contains(&U);
12303 }
12304
12305 /// See AbstractAttribute::manifest(...).
12306 ChangeStatus manifest(Attributor &A) override {
12307 return ChangeStatus::UNCHANGED;
12308 }
12309
12310 /// See AbstractAttribute::getAsStr().
12311 const std::string getAsStr(Attributor *A) const override {
12312 return "[" + std::to_string(Uses.size()) + " uses]";
12313 }
12314
12315 void trackStatistics() const override {
12316 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12317 }
12318
12319private:
12320 /// Set of (transitive) uses of this GlobalValue.
12321 SmallPtrSet<const Use *, 8> Uses;
12322};
12323} // namespace
12324
12325/// ------------------------ Indirect Call Info -------------------------------
12326namespace {
12327struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12328 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12329 : AAIndirectCallInfo(IRP, A) {}
12330
12331 /// See AbstractAttribute::initialize(...).
12332 void initialize(Attributor &A) override {
12333 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12334 if (!MD && !A.isClosedWorldModule())
12335 return;
12336
12337 if (MD) {
12338 for (const auto &Op : MD->operands())
12339 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12340 PotentialCallees.insert(Callee);
12341 } else if (A.isClosedWorldModule()) {
12342 ArrayRef<Function *> IndirectlyCallableFunctions =
12343 A.getInfoCache().getIndirectlyCallableFunctions(A);
12344 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12345 }
12346
12347 if (PotentialCallees.empty())
12348 indicateOptimisticFixpoint();
12349 }
12350
12351 ChangeStatus updateImpl(Attributor &A) override {
12352 CallBase *CB = cast<CallBase>(getCtxI());
12353 const Use &CalleeUse = CB->getCalledOperandUse();
12354 Value *FP = CB->getCalledOperand();
12355
12356 SmallSetVector<Function *, 4> AssumedCalleesNow;
12357 bool AllCalleesKnownNow = AllCalleesKnown;
12358
12359 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12360 bool &UsedAssumedInformation) {
12361 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12362 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12363 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12364 return true;
12365 UsedAssumedInformation = !GIAA->isAtFixpoint();
12366 return false;
12367 };
12368
12369 auto AddPotentialCallees = [&]() {
12370 for (auto *PotentialCallee : PotentialCallees) {
12371 bool UsedAssumedInformation = false;
12372 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12373 AssumedCalleesNow.insert(PotentialCallee);
12374 }
12375 };
12376
12377 // Use simplification to find potential callees, if !callees was present,
12378 // fallback to that set if necessary.
12379 bool UsedAssumedInformation = false;
12381 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12382 AA::ValueScope::AnyScope,
12383 UsedAssumedInformation)) {
12384 if (PotentialCallees.empty())
12385 return indicatePessimisticFixpoint();
12386 AddPotentialCallees();
12387 }
12388
12389 // Try to find a reason for \p Fn not to be a potential callee. If none was
12390 // found, add it to the assumed callees set.
12391 auto CheckPotentialCallee = [&](Function &Fn) {
12392 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12393 return false;
12394
12395 auto &CachedResult = FilterResults[&Fn];
12396 if (CachedResult.has_value())
12397 return CachedResult.value();
12398
12399 bool UsedAssumedInformation = false;
12400 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12401 if (!UsedAssumedInformation)
12402 CachedResult = false;
12403 return false;
12404 }
12405
12406 int NumFnArgs = Fn.arg_size();
12407 int NumCBArgs = CB->arg_size();
12408
12409 // Check if any excess argument (which we fill up with poison) is known to
12410 // be UB on undef.
12411 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12412 bool IsKnown = false;
12414 A, this, IRPosition::argument(*Fn.getArg(I)),
12415 DepClassTy::OPTIONAL, IsKnown)) {
12416 if (IsKnown)
12417 CachedResult = false;
12418 return false;
12419 }
12420 }
12421
12422 CachedResult = true;
12423 return true;
12424 };
12425
12426 // Check simplification result, prune known UB callees, also restrict it to
12427 // the !callees set, if present.
12428 for (auto &VAC : Values) {
12429 if (isa<UndefValue>(VAC.getValue()))
12430 continue;
12432 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12433 continue;
12434 // TODO: Check for known UB, e.g., poison + noundef.
12435 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12436 if (CheckPotentialCallee(*VACFn))
12437 AssumedCalleesNow.insert(VACFn);
12438 continue;
12439 }
12440 if (!PotentialCallees.empty()) {
12441 AddPotentialCallees();
12442 break;
12443 }
12444 AllCalleesKnownNow = false;
12445 }
12446
12447 if (AssumedCalleesNow == AssumedCallees &&
12448 AllCalleesKnown == AllCalleesKnownNow)
12449 return ChangeStatus::UNCHANGED;
12450
12451 std::swap(AssumedCallees, AssumedCalleesNow);
12452 AllCalleesKnown = AllCalleesKnownNow;
12453 return ChangeStatus::CHANGED;
12454 }
12455
12456 /// See AbstractAttribute::manifest(...).
12457 ChangeStatus manifest(Attributor &A) override {
12458 // If we can't specialize at all, give up now.
12459 if (!AllCalleesKnown && AssumedCallees.empty())
12460 return ChangeStatus::UNCHANGED;
12461
12462 CallBase *CB = cast<CallBase>(getCtxI());
12463 bool UsedAssumedInformation = false;
12464 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12465 UsedAssumedInformation))
12466 return ChangeStatus::UNCHANGED;
12467
12468 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12469 Value *FP = CB->getCalledOperand();
12470 if (FP->getType()->getPointerAddressSpace())
12471 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12472 FP->getName() + ".as0", CB->getIterator());
12473
12474 bool CBIsVoid = CB->getType()->isVoidTy();
12476 FunctionType *CSFT = CB->getFunctionType();
12477 SmallVector<Value *> CSArgs(CB->args());
12478
12479 // If we know all callees and there are none, the call site is (effectively)
12480 // dead (or UB).
12481 if (AssumedCallees.empty()) {
12482 assert(AllCalleesKnown &&
12483 "Expected all callees to be known if there are none.");
12484 A.changeToUnreachableAfterManifest(CB);
12485 return ChangeStatus::CHANGED;
12486 }
12487
12488 // Special handling for the single callee case.
12489 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12490 auto *NewCallee = AssumedCallees.front();
12491 if (isLegalToPromote(*CB, NewCallee)) {
12492 promoteCall(*CB, NewCallee, nullptr);
12493 NumIndirectCallsPromoted++;
12494 return ChangeStatus::CHANGED;
12495 }
12496 Instruction *NewCall =
12497 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12498 CB->getName(), CB->getIterator());
12499 if (!CBIsVoid)
12500 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12501 A.deleteAfterManifest(*CB);
12502 return ChangeStatus::CHANGED;
12503 }
12504
12505 // For each potential value we create a conditional
12506 //
12507 // ```
12508 // if (ptr == value) value(args);
12509 // else ...
12510 // ```
12511 //
12512 bool SpecializedForAnyCallees = false;
12513 bool SpecializedForAllCallees = AllCalleesKnown;
12514 ICmpInst *LastCmp = nullptr;
12515 SmallVector<Function *, 8> SkippedAssumedCallees;
12517 for (Function *NewCallee : AssumedCallees) {
12518 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12519 AssumedCallees.size())) {
12520 SkippedAssumedCallees.push_back(NewCallee);
12521 SpecializedForAllCallees = false;
12522 continue;
12523 }
12524 SpecializedForAnyCallees = true;
12525
12526 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12527 Instruction *ThenTI =
12528 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12529 BasicBlock *CBBB = CB->getParent();
12530 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12531 A.registerManifestAddedBasicBlock(*IP->getParent());
12532 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12533 BasicBlock *ElseBB;
12534 if (&*IP == CB) {
12535 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12536 ThenTI->getFunction(), CBBB);
12537 A.registerManifestAddedBasicBlock(*ElseBB);
12538 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12539 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12540 } else {
12541 ElseBB = IP->getParent();
12542 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12543 }
12544 CastInst *RetBC = nullptr;
12545 CallInst *NewCall = nullptr;
12546 if (isLegalToPromote(*CB, NewCallee)) {
12547 auto *CBClone = cast<CallBase>(CB->clone());
12548 CBClone->insertBefore(ThenTI->getIterator());
12549 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12550 NumIndirectCallsPromoted++;
12551 } else {
12552 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12553 CB->getName(), ThenTI->getIterator());
12554 }
12555 NewCalls.push_back({NewCall, RetBC});
12556 }
12557
12558 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12559 if (!AllCalleesKnown)
12560 return ChangeStatus::UNCHANGED;
12561 MDBuilder MDB(IndirectCB.getContext());
12562 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12563 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12564 return ChangeStatus::CHANGED;
12565 };
12566
12567 if (!SpecializedForAnyCallees)
12568 return AttachCalleeMetadata(*CB);
12569
12570 // Check if we need the fallback indirect call still.
12571 if (SpecializedForAllCallees) {
12573 LastCmp->eraseFromParent();
12574 new UnreachableInst(IP->getContext(), IP);
12575 IP->eraseFromParent();
12576 } else {
12577 auto *CBClone = cast<CallInst>(CB->clone());
12578 CBClone->setName(CB->getName());
12579 CBClone->insertBefore(*IP->getParent(), IP);
12580 NewCalls.push_back({CBClone, nullptr});
12581 AttachCalleeMetadata(*CBClone);
12582 }
12583
12584 // Check if we need a PHI to merge the results.
12585 if (!CBIsVoid) {
12586 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12587 CB->getName() + ".phi",
12588 CB->getParent()->getFirstInsertionPt());
12589 for (auto &It : NewCalls) {
12590 CallBase *NewCall = It.first;
12591 Instruction *CallRet = It.second ? It.second : It.first;
12592 if (CallRet->getType() == CB->getType())
12593 PHI->addIncoming(CallRet, CallRet->getParent());
12594 else if (NewCall->getType()->isVoidTy())
12595 PHI->addIncoming(PoisonValue::get(CB->getType()),
12596 NewCall->getParent());
12597 else
12598 llvm_unreachable("Call return should match or be void!");
12599 }
12600 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12601 }
12602
12603 A.deleteAfterManifest(*CB);
12604 Changed = ChangeStatus::CHANGED;
12605
12606 return Changed;
12607 }
12608
12609 /// See AbstractAttribute::getAsStr().
12610 const std::string getAsStr(Attributor *A) const override {
12611 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12612 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12613 " functions";
12614 }
12615
12616 void trackStatistics() const override {
12617 if (AllCalleesKnown) {
12619 Eliminated, CallSites,
12620 "Number of indirect call sites eliminated via specialization")
12621 } else {
12622 STATS_DECLTRACK(Specialized, CallSites,
12623 "Number of indirect call sites specialized")
12624 }
12625 }
12626
12627 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12628 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12629 }
12630
12631private:
12632 /// Map to remember filter results.
12633 DenseMap<Function *, std::optional<bool>> FilterResults;
12634
12635 /// If the !callee metadata was present, this set will contain all potential
12636 /// callees (superset).
12637 SmallSetVector<Function *, 4> PotentialCallees;
12638
12639 /// This set contains all currently assumed calllees, which might grow over
12640 /// time.
12641 SmallSetVector<Function *, 4> AssumedCallees;
12642
12643 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12644 /// if there could be others.
12645 bool AllCalleesKnown = true;
12646};
12647} // namespace
12648
12649/// --------------------- Invariant Load Pointer -------------------------------
12650namespace {
12651
12652struct AAInvariantLoadPointerImpl
12653 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12654 AAInvariantLoadPointer> {
12655
12656 enum {
12657 // pointer does not alias within the bounds of the function
12658 IS_NOALIAS = 1 << 0,
12659 // pointer is not involved in any effectful instructions within the bounds
12660 // of the function
12661 IS_NOEFFECT = 1 << 1,
12662 // loads are invariant within the bounds of the function
12663 IS_LOCALLY_INVARIANT = 1 << 2,
12664 // memory lifetime is constrained within the bounds of the function
12665 IS_LOCALLY_CONSTRAINED = 1 << 3,
12666
12667 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12668 IS_LOCALLY_CONSTRAINED,
12669 };
12670 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12671
12672 using Base =
12673 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12674
12675 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12676 // pessimistic about IS_KNOWN_INVARIANT
12677 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12678 : Base(IRP) {}
12679
12680 bool isKnownInvariant() const final {
12681 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12682 }
12683
12684 bool isKnownLocallyInvariant() const final {
12685 if (isKnown(IS_LOCALLY_INVARIANT))
12686 return true;
12687 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12688 }
12689
12690 bool isAssumedInvariant() const final {
12691 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12692 }
12693
12694 bool isAssumedLocallyInvariant() const final {
12695 if (isAssumed(IS_LOCALLY_INVARIANT))
12696 return true;
12697 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12698 }
12699
12700 ChangeStatus updateImpl(Attributor &A) override {
12701 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12702
12703 Changed |= updateNoAlias(A);
12704 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12705 return indicatePessimisticFixpoint();
12706
12707 Changed |= updateNoEffect(A);
12708
12709 Changed |= updateLocalInvariance(A);
12710
12711 return Changed;
12712 }
12713
12714 ChangeStatus manifest(Attributor &A) override {
12715 if (!isKnownInvariant())
12716 return ChangeStatus::UNCHANGED;
12717
12718 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12719 const Value *Ptr = &getAssociatedValue();
12720 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12721 if (U.get() != Ptr)
12722 return true;
12723 auto *I = dyn_cast<Instruction>(U.getUser());
12724 if (!I)
12725 return true;
12726
12727 // Ensure that we are only changing uses from the corresponding callgraph
12728 // SSC in the case that the AA isn't run on the entire module
12729 if (!A.isRunOn(I->getFunction()))
12730 return true;
12731
12732 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12733 return true;
12734
12735 if (auto *LI = dyn_cast<LoadInst>(I)) {
12736 LI->setMetadata(LLVMContext::MD_invariant_load,
12737 MDNode::get(LI->getContext(), {}));
12738 Changed = ChangeStatus::CHANGED;
12739 }
12740 return true;
12741 };
12742
12743 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12744 return Changed;
12745 }
12746
12747 /// See AbstractAttribute::getAsStr().
12748 const std::string getAsStr(Attributor *) const override {
12749 if (isKnownInvariant())
12750 return "load-invariant pointer";
12751 return "non-invariant pointer";
12752 }
12753
12754 /// See AbstractAttribute::trackStatistics().
12755 void trackStatistics() const override {}
12756
12757private:
12758 /// Indicate that noalias is required for the pointer to be invariant.
12759 bool requiresNoAlias() const {
12760 switch (getPositionKind()) {
12761 default:
12762 // Conservatively default to require noalias.
12763 return true;
12764 case IRP_FLOAT:
12765 case IRP_RETURNED:
12766 case IRP_CALL_SITE:
12767 return false;
12768 case IRP_CALL_SITE_RETURNED: {
12769 const auto &CB = cast<CallBase>(getAnchorValue());
12771 &CB, /*MustPreserveNullness=*/false);
12772 }
12773 case IRP_ARGUMENT: {
12774 const Function *F = getAssociatedFunction();
12775 assert(F && "no associated function for argument");
12776 return !isCallableCC(F->getCallingConv());
12777 }
12778 }
12779 }
12780
12781 bool isExternal() const {
12782 const Function *F = getAssociatedFunction();
12783 if (!F)
12784 return true;
12785 return isCallableCC(F->getCallingConv()) &&
12786 getPositionKind() != IRP_CALL_SITE_RETURNED;
12787 }
12788
12789 ChangeStatus updateNoAlias(Attributor &A) {
12790 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12791 return ChangeStatus::UNCHANGED;
12792
12793 // Try to use AANoAlias.
12794 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12795 getIRPosition(), this, DepClassTy::REQUIRED)) {
12796 if (ANoAlias->isKnownNoAlias()) {
12797 addKnownBits(IS_NOALIAS);
12798 return ChangeStatus::CHANGED;
12799 }
12800
12801 if (!ANoAlias->isAssumedNoAlias()) {
12802 removeAssumedBits(IS_NOALIAS);
12803 return ChangeStatus::CHANGED;
12804 }
12805
12806 return ChangeStatus::UNCHANGED;
12807 }
12808
12809 // Try to infer noalias from argument attribute, since it is applicable for
12810 // the duration of the function.
12811 if (const Argument *Arg = getAssociatedArgument()) {
12812 if (Arg->hasNoAliasAttr()) {
12813 addKnownBits(IS_NOALIAS);
12814 return ChangeStatus::UNCHANGED;
12815 }
12816
12817 // Noalias information is not provided, and cannot be inferred,
12818 // so we conservatively assume the pointer aliases.
12819 removeAssumedBits(IS_NOALIAS);
12820 return ChangeStatus::CHANGED;
12821 }
12822
12823 return ChangeStatus::UNCHANGED;
12824 }
12825
12826 ChangeStatus updateNoEffect(Attributor &A) {
12827 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12828 return ChangeStatus::UNCHANGED;
12829
12830 if (!getAssociatedFunction())
12831 return indicatePessimisticFixpoint();
12832
12833 if (isa<AllocaInst>(&getAssociatedValue()))
12834 return indicatePessimisticFixpoint();
12835
12836 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12837 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12838 return !LI || !LI->mayHaveSideEffects();
12839 };
12840 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12841 return indicatePessimisticFixpoint();
12842
12843 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12844 getIRPosition(), this, DepClassTy::REQUIRED)) {
12845 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12846 // attribute
12847 if (!AMemoryBehavior->isAssumedReadOnly())
12848 return indicatePessimisticFixpoint();
12849
12850 if (AMemoryBehavior->isKnownReadOnly()) {
12851 addKnownBits(IS_NOEFFECT);
12852 return ChangeStatus::UNCHANGED;
12853 }
12854
12855 return ChangeStatus::UNCHANGED;
12856 }
12857
12858 if (const Argument *Arg = getAssociatedArgument()) {
12859 if (Arg->onlyReadsMemory()) {
12860 addKnownBits(IS_NOEFFECT);
12861 return ChangeStatus::UNCHANGED;
12862 }
12863
12864 // Readonly information is not provided, and cannot be inferred from
12865 // AAMemoryBehavior.
12866 return indicatePessimisticFixpoint();
12867 }
12868
12869 return ChangeStatus::UNCHANGED;
12870 }
12871
12872 ChangeStatus updateLocalInvariance(Attributor &A) {
12873 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12874 return ChangeStatus::UNCHANGED;
12875
12876 // try to infer invariance from underlying objects
12877 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12878 getIRPosition(), this, DepClassTy::REQUIRED);
12879 if (!AUO)
12880 return ChangeStatus::UNCHANGED;
12881
12882 bool UsedAssumedInformation = false;
12883 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12884 if (!V.getType()->isPointerTy())
12885 return true;
12886 const auto *IsInvariantLoadPointer =
12887 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12888 DepClassTy::REQUIRED);
12889 // Conservatively fail if invariance cannot be inferred.
12890 if (!IsInvariantLoadPointer)
12891 return false;
12892
12893 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12894 return true;
12895 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12896 return false;
12897
12898 UsedAssumedInformation = true;
12899 return true;
12900 };
12901 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12902 return indicatePessimisticFixpoint();
12903
12904 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12906 CB, /*MustPreserveNullness=*/false)) {
12907 for (const Value *Arg : CB->args()) {
12908 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12909 return indicatePessimisticFixpoint();
12910 }
12911 }
12912 }
12913
12914 if (!UsedAssumedInformation) {
12915 // Pointer is known and not just assumed to be locally invariant.
12916 addKnownBits(IS_LOCALLY_INVARIANT);
12917 return ChangeStatus::CHANGED;
12918 }
12919
12920 return ChangeStatus::UNCHANGED;
12921 }
12922};
12923
12924struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12925 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12926 : AAInvariantLoadPointerImpl(IRP, A) {}
12927};
12928
12929struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12930 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12931 : AAInvariantLoadPointerImpl(IRP, A) {}
12932
12933 void initialize(Attributor &) override {
12934 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12935 }
12936};
12937
12938struct AAInvariantLoadPointerCallSiteReturned final
12939 : AAInvariantLoadPointerImpl {
12940 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12941 : AAInvariantLoadPointerImpl(IRP, A) {}
12942
12943 void initialize(Attributor &A) override {
12944 const Function *F = getAssociatedFunction();
12945 assert(F && "no associated function for return from call");
12946
12947 if (!F->isDeclaration() && !F->isIntrinsic())
12948 return AAInvariantLoadPointerImpl::initialize(A);
12949
12950 const auto &CB = cast<CallBase>(getAnchorValue());
12952 &CB, /*MustPreserveNullness=*/false))
12953 return AAInvariantLoadPointerImpl::initialize(A);
12954
12955 if (F->onlyReadsMemory() && F->hasNoSync())
12956 return AAInvariantLoadPointerImpl::initialize(A);
12957
12958 // At this point, the function is opaque, so we conservatively assume
12959 // non-invariance.
12960 indicatePessimisticFixpoint();
12961 }
12962};
12963
12964struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12965 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12966 : AAInvariantLoadPointerImpl(IRP, A) {}
12967
12968 void initialize(Attributor &) override {
12969 const Function *F = getAssociatedFunction();
12970 assert(F && "no associated function for argument");
12971
12972 if (!isCallableCC(F->getCallingConv())) {
12973 addKnownBits(IS_LOCALLY_CONSTRAINED);
12974 return;
12975 }
12976
12977 if (!F->hasLocalLinkage())
12978 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12979 }
12980};
12981
12982struct AAInvariantLoadPointerCallSiteArgument final
12983 : AAInvariantLoadPointerImpl {
12984 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12985 : AAInvariantLoadPointerImpl(IRP, A) {}
12986};
12987} // namespace
12988
12989/// ------------------------ Address Space ------------------------------------
12990namespace {
12991
12992template <typename InstType>
12993static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12994 Value *OriginalValue, PointerType *NewPtrTy,
12995 bool UseOriginalValue) {
12996 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12997 return false;
12998
12999 if (MemInst->isVolatile()) {
13000 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13001 *MemInst->getFunction());
13002 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13003 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13004 return false;
13005 }
13006
13007 if (UseOriginalValue) {
13008 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13009 return true;
13010 }
13011
13012 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13013 CastInst->insertBefore(MemInst->getIterator());
13014 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13015 return true;
13016}
13017
13018struct AAAddressSpaceImpl : public AAAddressSpace {
13019 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13020 : AAAddressSpace(IRP, A) {}
13021
13022 uint32_t getAddressSpace() const override {
13023 assert(isValidState() && "the AA is invalid");
13024 return AssumedAddressSpace;
13025 }
13026
13027 /// See AbstractAttribute::initialize(...).
13028 void initialize(Attributor &A) override {
13029 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13030 "Associated value is not a pointer");
13031
13032 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13033 indicatePessimisticFixpoint();
13034 return;
13035 }
13036
13037 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13038 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13039 if (AS != FlatAS) {
13040 [[maybe_unused]] bool R = takeAddressSpace(AS);
13041 assert(R && "The take should happen");
13042 indicateOptimisticFixpoint();
13043 }
13044 }
13045
13046 ChangeStatus updateImpl(Attributor &A) override {
13047 uint32_t OldAddressSpace = AssumedAddressSpace;
13048 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13049
13050 auto CheckAddressSpace = [&](Value &Obj) {
13051 // Ignore undef.
13052 if (isa<UndefValue>(&Obj))
13053 return true;
13054
13055 // If the object already has a non-flat address space, we simply take it.
13056 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13057 if (ObjAS != FlatAS)
13058 return takeAddressSpace(ObjAS);
13059
13060 // At this point, we know Obj is in the flat address space. For a final
13061 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13062 // associated function, if possible.
13063 Function *F = nullptr;
13064 if (auto *Arg = dyn_cast<Argument>(&Obj))
13065 F = Arg->getParent();
13066 else if (auto *I = dyn_cast<Instruction>(&Obj))
13067 F = I->getFunction();
13068
13069 // Use getAssumedAddrSpace if the associated function exists.
13070 if (F) {
13071 auto *TTI =
13072 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13073 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13074 if (AssumedAS != ~0U)
13075 return takeAddressSpace(AssumedAS);
13076 }
13077
13078 // Now we can't do anything else but to take the flat AS.
13079 return takeAddressSpace(FlatAS);
13080 };
13081
13082 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13083 DepClassTy::REQUIRED);
13084 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13085 return indicatePessimisticFixpoint();
13086
13087 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13088 : ChangeStatus::CHANGED;
13089 }
13090
13091 /// See AbstractAttribute::manifest(...).
13092 ChangeStatus manifest(Attributor &A) override {
13093 unsigned NewAS = getAddressSpace();
13094
13095 if (NewAS == InvalidAddressSpace ||
13096 NewAS == getAssociatedType()->getPointerAddressSpace())
13097 return ChangeStatus::UNCHANGED;
13098
13099 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13100
13101 Value *AssociatedValue = &getAssociatedValue();
13102 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13103
13104 PointerType *NewPtrTy =
13105 PointerType::get(getAssociatedType()->getContext(), NewAS);
13106 bool UseOriginalValue =
13107 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13108
13109 bool Changed = false;
13110
13111 auto Pred = [&](const Use &U, bool &) {
13112 if (U.get() != AssociatedValue)
13113 return true;
13114 auto *Inst = dyn_cast<Instruction>(U.getUser());
13115 if (!Inst)
13116 return true;
13117 // This is a WA to make sure we only change uses from the corresponding
13118 // CGSCC if the AA is run on CGSCC instead of the entire module.
13119 if (!A.isRunOn(Inst->getFunction()))
13120 return true;
13121 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13122 Changed |=
13123 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13124 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13125 Changed |=
13126 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13127 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13128 Changed |=
13129 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13130 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13131 Changed |=
13132 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13133 }
13134 return true;
13135 };
13136
13137 // It doesn't matter if we can't check all uses as we can simply
13138 // conservatively ignore those that can not be visited.
13139 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13140 /* CheckBBLivenessOnly */ true);
13141
13142 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13143 }
13144
13145 /// See AbstractAttribute::getAsStr().
13146 const std::string getAsStr(Attributor *A) const override {
13147 if (!isValidState())
13148 return "addrspace(<invalid>)";
13149 return "addrspace(" +
13150 (AssumedAddressSpace == InvalidAddressSpace
13151 ? "none"
13152 : std::to_string(AssumedAddressSpace)) +
13153 ")";
13154 }
13155
13156private:
13157 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13158
13159 bool takeAddressSpace(uint32_t AS) {
13160 if (AssumedAddressSpace == InvalidAddressSpace) {
13161 AssumedAddressSpace = AS;
13162 return true;
13163 }
13164 return AssumedAddressSpace == AS;
13165 }
13166
13167 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13168 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13169 assert(I->getSrcAddressSpace() != FlatAS &&
13170 "there should not be flat AS -> non-flat AS");
13171 return I->getPointerOperand();
13172 }
13173 if (auto *C = dyn_cast<ConstantExpr>(V))
13174 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13175 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13176 FlatAS &&
13177 "there should not be flat AS -> non-flat AS X");
13178 return C->getOperand(0);
13179 }
13180 return V;
13181 }
13182};
13183
13184struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13185 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13186 : AAAddressSpaceImpl(IRP, A) {}
13187
13188 void trackStatistics() const override {
13190 }
13191};
13192
13193struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13194 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13195 : AAAddressSpaceImpl(IRP, A) {}
13196
13197 /// See AbstractAttribute::initialize(...).
13198 void initialize(Attributor &A) override {
13199 // TODO: we don't rewrite function argument for now because it will need to
13200 // rewrite the function signature and all call sites.
13201 (void)indicatePessimisticFixpoint();
13202 }
13203
13204 void trackStatistics() const override {
13205 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13206 }
13207};
13208
13209struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13210 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13211 : AAAddressSpaceImpl(IRP, A) {}
13212
13213 void trackStatistics() const override {
13214 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13215 }
13216};
13217
13218struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13219 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13220 : AAAddressSpaceImpl(IRP, A) {}
13221
13222 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13223};
13224
13225struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13226 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13227 : AAAddressSpaceImpl(IRP, A) {}
13228
13229 /// See AbstractAttribute::initialize(...).
13230 void initialize(Attributor &A) override {
13231 // TODO: we don't rewrite call site argument for now because it will need to
13232 // rewrite the function signature of the callee.
13233 (void)indicatePessimisticFixpoint();
13234 }
13235
13236 void trackStatistics() const override {
13237 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13238 }
13239};
13240} // namespace
13241
13242/// ------------------------ No Alias Address Space ---------------------------
13243// This attribute assumes flat address space can alias all other address space
13244
13245// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13246// But merging it created failing cased on gateway test that cannot be
13247// reproduced locally. So should open a separated PR to handle the merge of
13248// AANoAliasAddrSpace and AAAddressSpace attribute
13249
13250namespace {
13251struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13252 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13253 : AANoAliasAddrSpace(IRP, A) {}
13254
13255 void initialize(Attributor &A) override {
13256 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13257 "Associated value is not a pointer");
13258
13259 resetASRanges(A);
13260
13261 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13262 if (!FlatAS.has_value()) {
13263 indicatePessimisticFixpoint();
13264 return;
13265 }
13266
13267 removeAS(*FlatAS);
13268
13269 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13270 if (AS != *FlatAS) {
13271 removeAS(AS);
13272 indicateOptimisticFixpoint();
13273 }
13274 }
13275
13276 ChangeStatus updateImpl(Attributor &A) override {
13277 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13278 uint32_t OldAssumed = getAssumed();
13279
13280 auto CheckAddressSpace = [&](Value &Obj) {
13281 if (isa<PoisonValue>(&Obj))
13282 return true;
13283
13284 unsigned AS = Obj.getType()->getPointerAddressSpace();
13285 if (AS == FlatAS)
13286 return false;
13287
13288 removeAS(Obj.getType()->getPointerAddressSpace());
13289 return true;
13290 };
13291
13292 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13293 getIRPosition(), this, DepClassTy::REQUIRED);
13294 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13295 return indicatePessimisticFixpoint();
13296
13297 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13298 : ChangeStatus::CHANGED;
13299 }
13300
13301 /// See AbstractAttribute::manifest(...).
13302 ChangeStatus manifest(Attributor &A) override {
13303 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13304
13305 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13306 if (AS != FlatAS || Map.empty())
13307 return ChangeStatus::UNCHANGED;
13308
13309 LLVMContext &Ctx = getAssociatedValue().getContext();
13310 MDNode *NoAliasASNode = nullptr;
13311 MDBuilder MDB(Ctx);
13312 // Has to use iterator to get the range info.
13313 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13314 if (!I.value())
13315 continue;
13316 unsigned Upper = I.stop();
13317 unsigned Lower = I.start();
13318 if (!NoAliasASNode) {
13319 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13320 continue;
13321 }
13322 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13323 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13324 }
13325
13326 Value *AssociatedValue = &getAssociatedValue();
13327 bool Changed = false;
13328
13329 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13330 if (U.get() != AssociatedValue)
13331 return true;
13332 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13333 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13334 return true;
13335 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13337 return true;
13338 if (!A.isRunOn(Inst->getFunction()))
13339 return true;
13340 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13341 Changed = true;
13342 return true;
13343 };
13344 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13345 /*CheckBBLivenessOnly=*/true);
13346 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13347 }
13348
13349 /// See AbstractAttribute::getAsStr().
13350 const std::string getAsStr(Attributor *A) const override {
13351 if (!isValidState())
13352 return "<invalid>";
13353 std::string Str;
13354 raw_string_ostream OS(Str);
13355 OS << "CanNotBeAddrSpace(";
13356 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13357 unsigned Upper = I.stop();
13358 unsigned Lower = I.start();
13359 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13360 }
13361 OS << " )";
13362 return OS.str();
13363 }
13364
13365private:
13366 void removeAS(unsigned AS) {
13367 RangeMap::iterator I = Map.find(AS);
13368
13369 if (I != Map.end()) {
13370 unsigned Upper = I.stop();
13371 unsigned Lower = I.start();
13372 I.erase();
13373 if (Upper == Lower)
13374 return;
13375 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13376 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13377 if (AS != 0 && Lower <= AS - 1)
13378 Map.insert(Lower, AS - 1, true);
13379 }
13380 }
13381
13382 void resetASRanges(Attributor &A) {
13383 Map.clear();
13384 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13385 }
13386};
13387
13388struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13389 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13390 : AANoAliasAddrSpaceImpl(IRP, A) {}
13391
13392 void trackStatistics() const override {
13393 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13394 }
13395};
13396
13397struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13398 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13399 : AANoAliasAddrSpaceImpl(IRP, A) {}
13400
13401 void trackStatistics() const override {
13402 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13403 }
13404};
13405
13406struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13407 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13408 : AANoAliasAddrSpaceImpl(IRP, A) {}
13409
13410 void trackStatistics() const override {
13411 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13412 }
13413};
13414
13415struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13416 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13417 : AANoAliasAddrSpaceImpl(IRP, A) {}
13418
13419 void trackStatistics() const override {
13420 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13421 }
13422};
13423
13424struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13425 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13426 : AANoAliasAddrSpaceImpl(IRP, A) {}
13427
13428 void trackStatistics() const override {
13429 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13430 }
13431};
13432} // namespace
13433/// ----------- Allocation Info ----------
13434namespace {
13435struct AAAllocationInfoImpl : public AAAllocationInfo {
13436 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13437 : AAAllocationInfo(IRP, A) {}
13438
13439 std::optional<TypeSize> getAllocatedSize() const override {
13440 assert(isValidState() && "the AA is invalid");
13441 return AssumedAllocatedSize;
13442 }
13443
13444 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13445 const DataLayout &DL) {
13446
13447 // TODO: implement case for malloc like instructions
13448 switch (I->getOpcode()) {
13449 case Instruction::Alloca: {
13450 AllocaInst *AI = cast<AllocaInst>(I);
13451 return AI->getAllocationSize(DL);
13452 }
13453 default:
13454 return std::nullopt;
13455 }
13456 }
13457
13458 ChangeStatus updateImpl(Attributor &A) override {
13459
13460 const IRPosition &IRP = getIRPosition();
13461 Instruction *I = IRP.getCtxI();
13462
13463 // TODO: update check for malloc like calls
13464 if (!isa<AllocaInst>(I))
13465 return indicatePessimisticFixpoint();
13466
13467 bool IsKnownNoCapture;
13469 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13470 return indicatePessimisticFixpoint();
13471
13472 const AAPointerInfo *PI =
13473 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13474
13475 if (!PI)
13476 return indicatePessimisticFixpoint();
13477
13478 if (!PI->getState().isValidState() || PI->reachesReturn())
13479 return indicatePessimisticFixpoint();
13480
13481 const DataLayout &DL = A.getDataLayout();
13482 const auto AllocationSize = findInitialAllocationSize(I, DL);
13483
13484 // If allocation size is nullopt, we give up.
13485 if (!AllocationSize)
13486 return indicatePessimisticFixpoint();
13487
13488 // For zero sized allocations, we give up.
13489 // Since we can't reduce further
13490 if (*AllocationSize == 0)
13491 return indicatePessimisticFixpoint();
13492
13493 int64_t BinSize = PI->numOffsetBins();
13494
13495 // TODO: implement for multiple bins
13496 if (BinSize > 1)
13497 return indicatePessimisticFixpoint();
13498
13499 if (BinSize == 0) {
13500 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13501 if (!changeAllocationSize(NewAllocationSize))
13502 return ChangeStatus::UNCHANGED;
13503 return ChangeStatus::CHANGED;
13504 }
13505
13506 // TODO: refactor this to be part of multiple bin case
13507 const auto &It = PI->begin();
13508
13509 // TODO: handle if Offset is not zero
13510 if (It->first.Offset != 0)
13511 return indicatePessimisticFixpoint();
13512
13513 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13514
13515 if (SizeOfBin >= *AllocationSize)
13516 return indicatePessimisticFixpoint();
13517
13518 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13519
13520 if (!changeAllocationSize(NewAllocationSize))
13521 return ChangeStatus::UNCHANGED;
13522
13523 return ChangeStatus::CHANGED;
13524 }
13525
13526 /// See AbstractAttribute::manifest(...).
13527 ChangeStatus manifest(Attributor &A) override {
13528
13529 assert(isValidState() &&
13530 "Manifest should only be called if the state is valid.");
13531
13532 Instruction *I = getIRPosition().getCtxI();
13533
13534 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13535
13536 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13537
13538 switch (I->getOpcode()) {
13539 // TODO: add case for malloc like calls
13540 case Instruction::Alloca: {
13541
13542 AllocaInst *AI = cast<AllocaInst>(I);
13543
13544 Type *CharType = Type::getInt8Ty(I->getContext());
13545
13546 auto *NumBytesToValue =
13547 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13548
13549 BasicBlock::iterator insertPt = AI->getIterator();
13550 insertPt = std::next(insertPt);
13551 AllocaInst *NewAllocaInst =
13552 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13553 AI->getAlign(), AI->getName(), insertPt);
13554
13555 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13556 return ChangeStatus::CHANGED;
13557
13558 break;
13559 }
13560 default:
13561 break;
13562 }
13563
13564 return ChangeStatus::UNCHANGED;
13565 }
13566
13567 /// See AbstractAttribute::getAsStr().
13568 const std::string getAsStr(Attributor *A) const override {
13569 if (!isValidState())
13570 return "allocationinfo(<invalid>)";
13571 return "allocationinfo(" +
13572 (AssumedAllocatedSize == HasNoAllocationSize
13573 ? "none"
13574 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13575 ")";
13576 }
13577
13578private:
13579 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13580
13581 // Maintain the computed allocation size of the object.
13582 // Returns (bool) weather the size of the allocation was modified or not.
13583 bool changeAllocationSize(std::optional<TypeSize> Size) {
13584 if (AssumedAllocatedSize == HasNoAllocationSize ||
13585 AssumedAllocatedSize != Size) {
13586 AssumedAllocatedSize = Size;
13587 return true;
13588 }
13589 return false;
13590 }
13591};
13592
13593struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13594 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13595 : AAAllocationInfoImpl(IRP, A) {}
13596
13597 void trackStatistics() const override {
13598 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13599 }
13600};
13601
13602struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13603 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13604 : AAAllocationInfoImpl(IRP, A) {}
13605
13606 /// See AbstractAttribute::initialize(...).
13607 void initialize(Attributor &A) override {
13608 // TODO: we don't rewrite function argument for now because it will need to
13609 // rewrite the function signature and all call sites
13610 (void)indicatePessimisticFixpoint();
13611 }
13612
13613 void trackStatistics() const override {
13614 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13615 }
13616};
13617
13618struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13619 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13620 : AAAllocationInfoImpl(IRP, A) {}
13621
13622 void trackStatistics() const override {
13623 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13624 }
13625};
13626
13627struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13628 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13629 : AAAllocationInfoImpl(IRP, A) {}
13630
13631 void trackStatistics() const override {
13632 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13633 }
13634};
13635
13636struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13637 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13638 : AAAllocationInfoImpl(IRP, A) {}
13639
13640 /// See AbstractAttribute::initialize(...).
13641 void initialize(Attributor &A) override {
13642
13643 (void)indicatePessimisticFixpoint();
13644 }
13645
13646 void trackStatistics() const override {
13647 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13648 }
13649};
13650} // namespace
13651
13652const char AANoUnwind::ID = 0;
13653const char AANoSync::ID = 0;
13654const char AANoFree::ID = 0;
13655const char AANonNull::ID = 0;
13656const char AAMustProgress::ID = 0;
13657const char AANoRecurse::ID = 0;
13658const char AANonConvergent::ID = 0;
13659const char AAWillReturn::ID = 0;
13660const char AAUndefinedBehavior::ID = 0;
13661const char AANoAlias::ID = 0;
13662const char AAIntraFnReachability::ID = 0;
13663const char AANoReturn::ID = 0;
13664const char AAIsDead::ID = 0;
13665const char AADereferenceable::ID = 0;
13666const char AAAlign::ID = 0;
13667const char AAInstanceInfo::ID = 0;
13668const char AANoCapture::ID = 0;
13669const char AAValueSimplify::ID = 0;
13670const char AAHeapToStack::ID = 0;
13671const char AAPrivatizablePtr::ID = 0;
13672const char AAMemoryBehavior::ID = 0;
13673const char AAMemoryLocation::ID = 0;
13674const char AAValueConstantRange::ID = 0;
13675const char AAPotentialConstantValues::ID = 0;
13676const char AAPotentialValues::ID = 0;
13677const char AANoUndef::ID = 0;
13678const char AANoFPClass::ID = 0;
13679const char AACallEdges::ID = 0;
13680const char AAInterFnReachability::ID = 0;
13681const char AAPointerInfo::ID = 0;
13682const char AAAssumptionInfo::ID = 0;
13683const char AAUnderlyingObjects::ID = 0;
13684const char AAInvariantLoadPointer::ID = 0;
13685const char AAAddressSpace::ID = 0;
13686const char AANoAliasAddrSpace::ID = 0;
13687const char AAAllocationInfo::ID = 0;
13688const char AAIndirectCallInfo::ID = 0;
13689const char AAGlobalValueInfo::ID = 0;
13690const char AADenormalFPMath::ID = 0;
13691
13692// Macro magic to create the static generator function for attributes that
13693// follow the naming scheme.
13694
13695#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13696 case IRPosition::PK: \
13697 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13698
13699#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13700 case IRPosition::PK: \
13701 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13702 ++NumAAs; \
13703 break;
13704
13705#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13706 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13707 CLASS *AA = nullptr; \
13708 switch (IRP.getPositionKind()) { \
13709 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13710 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13711 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13712 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13713 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13714 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13715 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13716 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13717 } \
13718 return *AA; \
13719 }
13720
13721#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13722 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13723 CLASS *AA = nullptr; \
13724 switch (IRP.getPositionKind()) { \
13725 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13726 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13727 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13728 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13729 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13730 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13731 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13732 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13733 } \
13734 return *AA; \
13735 }
13736
13737#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13738 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13739 CLASS *AA = nullptr; \
13740 switch (IRP.getPositionKind()) { \
13741 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13742 default: \
13743 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13744 " position!"); \
13745 } \
13746 return *AA; \
13747 }
13748
13749#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13750 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13751 CLASS *AA = nullptr; \
13752 switch (IRP.getPositionKind()) { \
13753 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13754 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13755 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13756 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13757 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13758 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13759 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13760 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13761 } \
13762 return *AA; \
13763 }
13764
13765#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13766 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13767 CLASS *AA = nullptr; \
13768 switch (IRP.getPositionKind()) { \
13769 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13770 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13771 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13772 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13773 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13774 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13775 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13776 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13777 } \
13778 return *AA; \
13779 }
13780
13781#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13782 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13783 CLASS *AA = nullptr; \
13784 switch (IRP.getPositionKind()) { \
13785 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13786 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13787 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13788 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13789 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13790 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13791 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13792 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13793 } \
13794 return *AA; \
13795 }
13796
13806
13824
13829
13834
13841
13843
13844#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13845#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13846#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13847#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13848#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13849#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13850#undef SWITCH_PK_CREATE
13851#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:272
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:308
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:296
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:610
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:617
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:948
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:942
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:254
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:239
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:159
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2091
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:534
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2858
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:79
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static unsigned getPointerOperandIndex()
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:743
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:774
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:779
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:284
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:287
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:808
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:807
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:335
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isGPUConstantAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU constant address space for the target triple...
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
LLVM_ABI bool isGPUSharedAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU shared address space for the target triple i...
LLVM_ABI bool isGPULocalAddressSpace(const Module &M, unsigned AS)
Check if the given address space AS corresponds to a GPU local/private address space for the target t...
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:194
@ Intraprocedural
Definition Attributor.h:195
@ Interprocedural
Definition Attributor.h:196
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:50
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:557
@ Length
Definition DWP.cpp:557
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1738
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1668
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:376
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:328
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1660
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1745
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1635
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:370
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:508
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:520
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:521
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:519
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:876
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.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:253
static constexpr int64_t Unknown
Definition Attributor.h:332
static RangeTy getUnknown()
Definition Attributor.h:259
Value * getValue() const
Definition Attributor.h:206
const Instruction * getCtxI() const
Definition Attributor.h:207
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:605
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:736
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:673
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:655
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:629
CallBase CallBaseContext
Definition Attributor.h:608
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:823
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:641
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:678
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:619
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:615
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:618
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:616
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:617
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:620
@ IRP_INVALID
An invalid position.
Definition Attributor.h:612
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:789
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:662
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:812
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:648
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:951
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:803
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:722
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:832
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:701
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:901
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:933
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:668
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:777
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.