LLVM 22.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.
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
670 if (Br->isConditional())
671 BrInsts.push_back(Br);
672 return true;
673 };
674
675 // Here, accumulate conditional branch instructions in the context. We
676 // explore the child paths and collect the known states. The disjunction of
677 // those states can be merged to its own state. Let ParentState_i be a state
678 // to indicate the known information for an i-th branch instruction in the
679 // context. ChildStates are created for its successors respectively.
680 //
681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
683 // ...
684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
685 //
686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
687 //
688 // FIXME: Currently, recursive branches are not handled. For example, we
689 // can't deduce that ptr must be dereferenced in below function.
690 //
691 // void f(int a, int c, int *ptr) {
692 // if(a)
693 // if (b) {
694 // *ptr = 0;
695 // } else {
696 // *ptr = 1;
697 // }
698 // else {
699 // if (b) {
700 // *ptr = 0;
701 // } else {
702 // *ptr = 1;
703 // }
704 // }
705 // }
706
707 Explorer->checkForAllContext(&CtxI, Pred);
708 for (const BranchInst *Br : BrInsts) {
709 StateType ParentState;
710
711 // The known state of the parent state is a conjunction of children's
712 // known states so it is initialized with a best state.
713 ParentState.indicateOptimisticFixpoint();
714
715 for (const BasicBlock *BB : Br->successors()) {
716 StateType ChildState;
717
718 size_t BeforeSize = Uses.size();
719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
720
721 // Erase uses which only appear in the child.
722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
723 It = Uses.erase(It);
724
725 ParentState &= ChildState;
726 }
727
728 // Use only known state.
729 S += ParentState;
730 }
731}
732} // namespace
733
734/// ------------------------ PointerInfo ---------------------------------------
735
736namespace llvm {
737namespace AA {
738namespace PointerInfo {
739
740struct State;
741
742} // namespace PointerInfo
743} // namespace AA
744
745/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
746template <>
749 static inline Access getEmptyKey();
750 static inline Access getTombstoneKey();
751 static unsigned getHashValue(const Access &A);
752 static bool isEqual(const Access &LHS, const Access &RHS);
753};
754
755/// Helper that allows RangeTy as a key in a DenseMap.
756template <> struct DenseMapInfo<AA::RangeTy> {
757 static inline AA::RangeTy getEmptyKey() {
758 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
759 return AA::RangeTy{EmptyKey, EmptyKey};
760 }
761
762 static inline AA::RangeTy getTombstoneKey() {
763 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
764 return AA::RangeTy{TombstoneKey, TombstoneKey};
765 }
766
772
773 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
774 return A == B;
775 }
776};
777
778/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
779/// but the instruction
780struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
783 static inline Access getEmptyKey();
784 static inline Access getTombstoneKey();
785 static unsigned getHashValue(const Access &A);
786 static bool isEqual(const Access &LHS, const Access &RHS);
787};
788
789} // namespace llvm
790
791/// A type to track pointer/struct usage and accesses for AAPointerInfo.
793 /// Return the best possible representable state.
794 static State getBestState(const State &SIS) { return State(); }
795
796 /// Return the worst possible representable state.
797 static State getWorstState(const State &SIS) {
798 State R;
799 R.indicatePessimisticFixpoint();
800 return R;
801 }
802
803 State() = default;
804 State(State &&SIS) = default;
805
806 const State &getAssumed() const { return *this; }
807
808 /// See AbstractState::isValidState().
809 bool isValidState() const override { return BS.isValidState(); }
810
811 /// See AbstractState::isAtFixpoint().
812 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
813
814 /// See AbstractState::indicateOptimisticFixpoint().
816 BS.indicateOptimisticFixpoint();
818 }
819
820 /// See AbstractState::indicatePessimisticFixpoint().
822 BS.indicatePessimisticFixpoint();
824 }
825
826 State &operator=(const State &R) {
827 if (this == &R)
828 return *this;
829 BS = R.BS;
830 AccessList = R.AccessList;
831 OffsetBins = R.OffsetBins;
832 RemoteIMap = R.RemoteIMap;
833 ReturnedOffsets = R.ReturnedOffsets;
834 return *this;
835 }
836
838 if (this == &R)
839 return *this;
840 std::swap(BS, R.BS);
841 std::swap(AccessList, R.AccessList);
842 std::swap(OffsetBins, R.OffsetBins);
843 std::swap(RemoteIMap, R.RemoteIMap);
844 std::swap(ReturnedOffsets, R.ReturnedOffsets);
845 return *this;
846 }
847
848 /// Add a new Access to the state at offset \p Offset and with size \p Size.
849 /// The access is associated with \p I, writes \p Content (if anything), and
850 /// is of kind \p Kind. If an Access already exists for the same \p I and same
851 /// \p RemoteI, the two are combined, potentially losing information about
852 /// offset and size. The resulting access must now be moved from its original
853 /// OffsetBin to the bin for its new offset.
854 ///
855 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
857 Instruction &I, std::optional<Value *> Content,
859 Instruction *RemoteI = nullptr);
860
863 int64_t numOffsetBins() const { return OffsetBins.size(); }
864
865 const AAPointerInfo::Access &getAccess(unsigned Index) const {
866 return AccessList[Index];
867 }
868
869protected:
870 // Every memory instruction results in an Access object. We maintain a list of
871 // all Access objects that we own, along with the following maps:
872 //
873 // - OffsetBins: RangeTy -> { Access }
874 // - RemoteIMap: RemoteI x LocalI -> Access
875 //
876 // A RemoteI is any instruction that accesses memory. RemoteI is different
877 // from LocalI if and only if LocalI is a call; then RemoteI is some
878 // instruction in the callgraph starting from LocalI. Multiple paths in the
879 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
880 // are all combined into a single Access object. This may result in loss of
881 // information in RangeTy in the Access object.
885
886 /// Flag to determine if the underlying pointer is reaching a return statement
887 /// in the associated function or not. Returns in other functions cause
888 /// invalidation.
890
891 /// See AAPointerInfo::forallInterferingAccesses.
892 template <typename F>
894 if (!isValidState() || !ReturnedOffsets.isUnassigned())
895 return false;
896
897 for (const auto &It : OffsetBins) {
898 AA::RangeTy ItRange = It.getFirst();
899 if (!Range.mayOverlap(ItRange))
900 continue;
901 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
902 for (auto Index : It.getSecond()) {
903 auto &Access = AccessList[Index];
904 if (!CB(Access, IsExact))
905 return false;
906 }
907 }
908 return true;
909 }
910
911 /// See AAPointerInfo::forallInterferingAccesses.
912 template <typename F>
914 AA::RangeTy &Range) const {
915 if (!isValidState() || !ReturnedOffsets.isUnassigned())
916 return false;
917
918 auto LocalList = RemoteIMap.find(&I);
919 if (LocalList == RemoteIMap.end()) {
920 return true;
921 }
922
923 for (unsigned Index : LocalList->getSecond()) {
924 for (auto &R : AccessList[Index]) {
925 Range &= R;
926 if (Range.offsetAndSizeAreUnknown())
927 break;
928 }
929 }
931 }
932
933private:
934 /// State to track fixpoint and validity.
935 BooleanState BS;
936};
937
940 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
941 Instruction *RemoteI) {
942 RemoteI = RemoteI ? RemoteI : &I;
943
944 // Check if we have an access for this instruction, if not, simply add it.
945 auto &LocalList = RemoteIMap[RemoteI];
946 bool AccExists = false;
947 unsigned AccIndex = AccessList.size();
948 for (auto Index : LocalList) {
949 auto &A = AccessList[Index];
950 if (A.getLocalInst() == &I) {
951 AccExists = true;
952 AccIndex = Index;
953 break;
954 }
955 }
956
957 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
958 LLVM_DEBUG(if (ToAdd.size()) dbgs()
959 << "[AAPointerInfo] Inserting access in new offset bins\n";);
960
961 for (auto Key : ToAdd) {
962 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
963 OffsetBins[Key].insert(AccIndex);
964 }
965 };
966
967 if (!AccExists) {
968 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
969 assert((AccessList.size() == AccIndex + 1) &&
970 "New Access should have been at AccIndex");
971 LocalList.push_back(AccIndex);
972 AddToBins(AccessList[AccIndex].getRanges());
974 }
975
976 // Combine the new Access with the existing Access, and then update the
977 // mapping in the offset bins.
978 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
979 auto &Current = AccessList[AccIndex];
980 auto Before = Current;
981 Current &= Acc;
982 if (Current == Before)
984
985 auto &ExistingRanges = Before.getRanges();
986 auto &NewRanges = Current.getRanges();
987
988 // Ranges that are in the old access but not the new access need to be removed
989 // from the offset bins.
991 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
992 LLVM_DEBUG(if (ToRemove.size()) dbgs()
993 << "[AAPointerInfo] Removing access from old offset bins\n";);
994
995 for (auto Key : ToRemove) {
996 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
997 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
998 auto &Bin = OffsetBins[Key];
999 assert(Bin.count(AccIndex) &&
1000 "Expected bin to actually contain the Access.");
1001 Bin.erase(AccIndex);
1002 }
1003
1004 // Ranges that are in the new access but not the old access need to be added
1005 // to the offset bins.
1007 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1008 AddToBins(ToAdd);
1009 return ChangeStatus::CHANGED;
1010}
1011
1012namespace {
1013
1014#ifndef NDEBUG
1016 const AAPointerInfo::OffsetInfo &OI) {
1017 OS << llvm::interleaved_array(OI);
1018 return OS;
1019}
1020#endif // NDEBUG
1021
1022struct AAPointerInfoImpl
1023 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1025 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1026
1027 /// See AbstractAttribute::getAsStr().
1028 const std::string getAsStr(Attributor *A) const override {
1029 return std::string("PointerInfo ") +
1030 (isValidState() ? (std::string("#") +
1031 std::to_string(OffsetBins.size()) + " bins")
1032 : "<invalid>") +
1033 (reachesReturn()
1034 ? (" (returned:" +
1035 join(map_range(ReturnedOffsets,
1036 [](int64_t O) { return std::to_string(O); }),
1037 ", ") +
1038 ")")
1039 : "");
1040 }
1041
1042 /// See AbstractAttribute::manifest(...).
1043 ChangeStatus manifest(Attributor &A) override {
1044 return AAPointerInfo::manifest(A);
1045 }
1046
1047 virtual const_bin_iterator begin() const override { return State::begin(); }
1048 virtual const_bin_iterator end() const override { return State::end(); }
1049 virtual int64_t numOffsetBins() const override {
1050 return State::numOffsetBins();
1051 }
1052 virtual bool reachesReturn() const override {
1053 return !ReturnedOffsets.isUnassigned();
1054 }
1055 virtual void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1056 if (ReturnedOffsets.isUnknown()) {
1057 OI.setUnknown();
1058 return;
1059 }
1060
1061 OffsetInfo MergedOI;
1062 for (auto Offset : ReturnedOffsets) {
1063 OffsetInfo TmpOI = OI;
1064 TmpOI.addToAll(Offset);
1065 MergedOI.merge(TmpOI);
1066 }
1067 OI = std::move(MergedOI);
1068 }
1069
1070 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1071 if (ReturnedOffsets.isUnknown())
1072 return ChangeStatus::UNCHANGED;
1073 if (ReachedReturnedOffsets.isUnknown()) {
1074 ReturnedOffsets.setUnknown();
1075 return ChangeStatus::CHANGED;
1076 }
1077 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1078 return ChangeStatus::CHANGED;
1079 return ChangeStatus::UNCHANGED;
1080 }
1081
1082 bool forallInterferingAccesses(
1083 AA::RangeTy Range,
1084 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1085 const override {
1086 return State::forallInterferingAccesses(Range, CB);
1087 }
1088
1089 bool forallInterferingAccesses(
1090 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1091 bool FindInterferingWrites, bool FindInterferingReads,
1092 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1093 AA::RangeTy &Range,
1094 function_ref<bool(const Access &)> SkipCB) const override {
1095 HasBeenWrittenTo = false;
1096
1097 SmallPtrSet<const Access *, 8> DominatingWrites;
1098 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1099
1100 Function &Scope = *I.getFunction();
1101 bool IsKnownNoSync;
1102 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1103 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1104 IsKnownNoSync);
1105 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1106 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1107 bool AllInSameNoSyncFn = IsAssumedNoSync;
1108 bool InstIsExecutedByInitialThreadOnly =
1109 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1110
1111 // If the function is not ending in aligned barriers, we need the stores to
1112 // be in aligned barriers. The load being in one is not sufficient since the
1113 // store might be executed by a thread that disappears after, causing the
1114 // aligned barrier guarding the load to unblock and the load to read a value
1115 // that has no CFG path to the load.
1116 bool InstIsExecutedInAlignedRegion =
1117 FindInterferingReads && ExecDomainAA &&
1118 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1119
1120 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1121 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1122
1123 InformationCache &InfoCache = A.getInfoCache();
1124 bool IsThreadLocalObj =
1125 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1126
1127 // Helper to determine if we need to consider threading, which we cannot
1128 // right now. However, if the function is (assumed) nosync or the thread
1129 // executing all instructions is the main thread only we can ignore
1130 // threading. Also, thread-local objects do not require threading reasoning.
1131 // Finally, we can ignore threading if either access is executed in an
1132 // aligned region.
1133 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1134 if (IsThreadLocalObj || AllInSameNoSyncFn)
1135 return true;
1136 const auto *FnExecDomainAA =
1137 I.getFunction() == &Scope
1138 ? ExecDomainAA
1139 : A.lookupAAFor<AAExecutionDomain>(
1140 IRPosition::function(*I.getFunction()), &QueryingAA,
1141 DepClassTy::NONE);
1142 if (!FnExecDomainAA)
1143 return false;
1144 if (InstIsExecutedInAlignedRegion ||
1145 (FindInterferingWrites &&
1146 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1147 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1148 return true;
1149 }
1150 if (InstIsExecutedByInitialThreadOnly &&
1151 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1153 return true;
1154 }
1155 return false;
1156 };
1157
1158 // Helper to determine if the access is executed by the same thread as the
1159 // given instruction, for now it is sufficient to avoid any potential
1160 // threading effects as we cannot deal with them anyway.
1161 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1162 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1163 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1164 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1165 };
1166
1167 // TODO: Use inter-procedural reachability and dominance.
1168 bool IsKnownNoRecurse;
1170 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1171 IsKnownNoRecurse);
1172
1173 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1174 // AAExecutionDomain) such that we allow scopes other than kernels as long
1175 // as the reaching kernels are disjoint.
1176 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1177 bool ObjHasKernelLifetime = false;
1178 const bool UseDominanceReasoning =
1179 FindInterferingWrites && IsKnownNoRecurse;
1180 const DominatorTree *DT =
1181 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1182
1183 // Helper to check if a value has "kernel lifetime", that is it will not
1184 // outlive a GPU kernel. This is true for shared, constant, and local
1185 // globals on AMD and NVIDIA GPUs.
1186 auto HasKernelLifetime = [&](Value *V, Module &M) {
1187 if (!AA::isGPU(M))
1188 return false;
1189 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1190 case AA::GPUAddressSpace::Shared:
1191 case AA::GPUAddressSpace::Constant:
1192 case AA::GPUAddressSpace::Local:
1193 return true;
1194 default:
1195 return false;
1196 };
1197 };
1198
1199 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1200 // to determine if we should look at reachability from the callee. For
1201 // certain pointers we know the lifetime and we do not have to step into the
1202 // callee to determine reachability as the pointer would be dead in the
1203 // callee. See the conditional initialization below.
1204 std::function<bool(const Function &)> IsLiveInCalleeCB;
1205
1206 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1207 // If the alloca containing function is not recursive the alloca
1208 // must be dead in the callee.
1209 const Function *AIFn = AI->getFunction();
1210 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1211 bool IsKnownNoRecurse;
1213 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1214 IsKnownNoRecurse)) {
1215 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1216 }
1217 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1218 // If the global has kernel lifetime we can stop if we reach a kernel
1219 // as it is "dead" in the (unknown) callees.
1220 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1221 if (ObjHasKernelLifetime)
1222 IsLiveInCalleeCB = [&A](const Function &Fn) {
1223 return !A.getInfoCache().isKernel(Fn);
1224 };
1225 }
1226
1227 // Set of accesses/instructions that will overwrite the result and are
1228 // therefore blockers in the reachability traversal.
1229 AA::InstExclusionSetTy ExclusionSet;
1230
1231 auto AccessCB = [&](const Access &Acc, bool Exact) {
1232 Function *AccScope = Acc.getRemoteInst()->getFunction();
1233 bool AccInSameScope = AccScope == &Scope;
1234
1235 // If the object has kernel lifetime we can ignore accesses only reachable
1236 // by other kernels. For now we only skip accesses *in* other kernels.
1237 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1238 A.getInfoCache().isKernel(*AccScope))
1239 return true;
1240
1241 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1242 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1243 ExclusionSet.insert(Acc.getRemoteInst());
1244 }
1245
1246 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1247 (!FindInterferingReads || !Acc.isRead()))
1248 return true;
1249
1250 bool Dominates = FindInterferingWrites && DT && Exact &&
1251 Acc.isMustAccess() && AccInSameScope &&
1252 DT->dominates(Acc.getRemoteInst(), &I);
1253 if (Dominates)
1254 DominatingWrites.insert(&Acc);
1255
1256 // Track if all interesting accesses are in the same `nosync` function as
1257 // the given instruction.
1258 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1259
1260 InterferingAccesses.push_back({&Acc, Exact});
1261 return true;
1262 };
1263 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1264 return false;
1265
1266 HasBeenWrittenTo = !DominatingWrites.empty();
1267
1268 // Dominating writes form a chain, find the least/lowest member.
1269 Instruction *LeastDominatingWriteInst = nullptr;
1270 for (const Access *Acc : DominatingWrites) {
1271 if (!LeastDominatingWriteInst) {
1272 LeastDominatingWriteInst = Acc->getRemoteInst();
1273 } else if (DT->dominates(LeastDominatingWriteInst,
1274 Acc->getRemoteInst())) {
1275 LeastDominatingWriteInst = Acc->getRemoteInst();
1276 }
1277 }
1278
1279 // Helper to determine if we can skip a specific write access.
1280 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1281 if (SkipCB && SkipCB(Acc))
1282 return true;
1283 if (!CanIgnoreThreading(Acc))
1284 return false;
1285
1286 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1287 // If we successfully excluded all effects we are interested in, the
1288 // access can be skipped.
1289 bool ReadChecked = !FindInterferingReads;
1290 bool WriteChecked = !FindInterferingWrites;
1291
1292 // If the instruction cannot reach the access, the former does not
1293 // interfere with what the access reads.
1294 if (!ReadChecked) {
1295 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1296 &ExclusionSet, IsLiveInCalleeCB))
1297 ReadChecked = true;
1298 }
1299 // If the instruction cannot be reach from the access, the latter does not
1300 // interfere with what the instruction reads.
1301 if (!WriteChecked) {
1302 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1303 &ExclusionSet, IsLiveInCalleeCB))
1304 WriteChecked = true;
1305 }
1306
1307 // If we still might be affected by the write of the access but there are
1308 // dominating writes in the function of the instruction
1309 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1310 // by them. This would have happend above if they are all in the same
1311 // function, so we only check the inter-procedural case. Effectively, we
1312 // want to show that there is no call after the dominting write that might
1313 // reach the access, and when it returns reach the instruction with the
1314 // updated value. To this end, we iterate all call sites, check if they
1315 // might reach the instruction without going through another access
1316 // (ExclusionSet) and at the same time might reach the access. However,
1317 // that is all part of AAInterFnReachability.
1318 if (!WriteChecked && HasBeenWrittenTo &&
1319 Acc.getRemoteInst()->getFunction() != &Scope) {
1320
1321 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1322 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1323 if (FnReachabilityAA) {
1324 // Without going backwards in the call tree, can we reach the access
1325 // from the least dominating write. Do not allow to pass the
1326 // instruction itself either.
1327 bool Inserted = ExclusionSet.insert(&I).second;
1328
1329 if (!FnReachabilityAA->instructionCanReach(
1330 A, *LeastDominatingWriteInst,
1331 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1332 WriteChecked = true;
1333
1334 if (Inserted)
1335 ExclusionSet.erase(&I);
1336 }
1337 }
1338
1339 if (ReadChecked && WriteChecked)
1340 return true;
1341
1342 if (!DT || !UseDominanceReasoning)
1343 return false;
1344 if (!DominatingWrites.count(&Acc))
1345 return false;
1346 return LeastDominatingWriteInst != Acc.getRemoteInst();
1347 };
1348
1349 // Run the user callback on all accesses we cannot skip and return if
1350 // that succeeded for all or not.
1351 for (auto &It : InterferingAccesses) {
1352 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1353 !CanSkipAccess(*It.first, It.second)) {
1354 if (!UserCB(*It.first, It.second))
1355 return false;
1356 }
1357 }
1358 return true;
1359 }
1360
1361 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1362 const AAPointerInfo &OtherAA,
1363 CallBase &CB) {
1364 using namespace AA::PointerInfo;
1365 if (!OtherAA.getState().isValidState() || !isValidState())
1366 return indicatePessimisticFixpoint();
1367
1368 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1369 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1370 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1371 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1372
1373 // Combine the accesses bin by bin.
1374 const auto &State = OtherAAImpl.getState();
1375 for (const auto &It : State) {
1376 for (auto Index : It.getSecond()) {
1377 const auto &RAcc = State.getAccess(Index);
1378 if (IsByval && !RAcc.isRead())
1379 continue;
1380 bool UsedAssumedInformation = false;
1381 AccessKind AK = RAcc.getKind();
1382 auto Content = A.translateArgumentToCallSiteContent(
1383 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1384 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1385 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1386
1387 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1388 RAcc.getType(), RAcc.getRemoteInst());
1389 }
1390 }
1391 return Changed;
1392 }
1393
1394 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1395 const OffsetInfo &Offsets, CallBase &CB,
1396 bool IsMustAcc) {
1397 using namespace AA::PointerInfo;
1398 if (!OtherAA.getState().isValidState() || !isValidState())
1399 return indicatePessimisticFixpoint();
1400
1401 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1402
1403 // Combine the accesses bin by bin.
1404 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1405 const auto &State = OtherAAImpl.getState();
1406 for (const auto &It : State) {
1407 for (auto Index : It.getSecond()) {
1408 const auto &RAcc = State.getAccess(Index);
1409 if (!IsMustAcc && RAcc.isAssumption())
1410 continue;
1411 for (auto Offset : Offsets) {
1412 auto NewRanges = Offset == AA::RangeTy::Unknown
1414 : RAcc.getRanges();
1415 if (!NewRanges.isUnknown()) {
1416 NewRanges.addToAllOffsets(Offset);
1417 }
1418 AccessKind AK = RAcc.getKind();
1419 if (!IsMustAcc)
1420 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1421 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1422 RAcc.getType(), RAcc.getRemoteInst());
1423 }
1424 }
1425 }
1426 return Changed;
1427 }
1428
1429 /// Statistic tracking for all AAPointerInfo implementations.
1430 /// See AbstractAttribute::trackStatistics().
1431 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1432
1433 /// Dump the state into \p O.
1434 void dumpState(raw_ostream &O) {
1435 for (auto &It : OffsetBins) {
1436 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1437 << "] : " << It.getSecond().size() << "\n";
1438 for (auto AccIndex : It.getSecond()) {
1439 auto &Acc = AccessList[AccIndex];
1440 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1441 if (Acc.getLocalInst() != Acc.getRemoteInst())
1442 O << " --> " << *Acc.getRemoteInst()
1443 << "\n";
1444 if (!Acc.isWrittenValueYetUndetermined()) {
1445 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1446 O << " - c: func " << Acc.getWrittenValue()->getName()
1447 << "\n";
1448 else if (Acc.getWrittenValue())
1449 O << " - c: " << *Acc.getWrittenValue() << "\n";
1450 else
1451 O << " - c: <unknown>\n";
1452 }
1453 }
1454 }
1455 }
1456};
1457
1458struct AAPointerInfoFloating : public AAPointerInfoImpl {
1460 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1461 : AAPointerInfoImpl(IRP, A) {}
1462
1463 /// Deal with an access and signal if it was handled successfully.
1464 bool handleAccess(Attributor &A, Instruction &I,
1465 std::optional<Value *> Content, AccessKind Kind,
1466 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1467 Type &Ty) {
1468 using namespace AA::PointerInfo;
1470 const DataLayout &DL = A.getDataLayout();
1471 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1472 if (!AccessSize.isScalable())
1473 Size = AccessSize.getFixedValue();
1474
1475 // Make a strictly ascending list of offsets as required by addAccess()
1476 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1477 llvm::sort(OffsetsSorted);
1478
1480 if (!VT || VT->getElementCount().isScalable() ||
1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1482 (*Content)->getType() != VT ||
1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1484 Changed =
1485 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1486 } else {
1487 // Handle vector stores with constant content element-wise.
1488 // TODO: We could look for the elements or create instructions
1489 // representing them.
1490 // TODO: We need to push the Content into the range abstraction
1491 // (AA::RangeTy) to allow different content values for different
1492 // ranges. ranges. Hence, support vectors storing different values.
1493 Type *ElementType = VT->getElementType();
1494 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1495 auto *ConstContent = cast<Constant>(*Content);
1496 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1497 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1498
1499 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1500 Value *ElementContent = ConstantExpr::getExtractElement(
1501 ConstContent, ConstantInt::get(Int32Ty, i));
1502
1503 // Add the element access.
1504 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1505 ElementContent, Kind, ElementType);
1506
1507 // Advance the offsets for the next element.
1508 for (auto &ElementOffset : ElementOffsets)
1509 ElementOffset += ElementSize;
1510 }
1511 }
1512 return true;
1513 };
1514
1515 /// See AbstractAttribute::updateImpl(...).
1516 ChangeStatus updateImpl(Attributor &A) override;
1517
1518 /// If the indices to \p GEP can be traced to constants, incorporate all
1519 /// of these into \p UsrOI.
1520 ///
1521 /// \return true iff \p UsrOI is updated.
1522 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1523 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1524 const GEPOperator *GEP);
1525
1526 /// See AbstractAttribute::trackStatistics()
1527 void trackStatistics() const override {
1528 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1529 }
1530};
1531
1532bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1533 const DataLayout &DL,
1534 OffsetInfo &UsrOI,
1535 const OffsetInfo &PtrOI,
1536 const GEPOperator *GEP) {
1537 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1538 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1539 APInt ConstantOffset(BitWidth, 0);
1540
1541 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1542 "Don't look for constant values if the offset has already been "
1543 "determined to be unknown.");
1544
1545 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1546 UsrOI.setUnknown();
1547 return true;
1548 }
1549
1550 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1551 << (VariableOffsets.empty() ? "" : "not") << " constant "
1552 << *GEP << "\n");
1553
1554 auto Union = PtrOI;
1555 Union.addToAll(ConstantOffset.getSExtValue());
1556
1557 // Each VI in VariableOffsets has a set of potential constant values. Every
1558 // combination of elements, picked one each from these sets, is separately
1559 // added to the original set of offsets, thus resulting in more offsets.
1560 for (const auto &VI : VariableOffsets) {
1561 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1562 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1563 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1564 UsrOI.setUnknown();
1565 return true;
1566 }
1567
1568 // UndefValue is treated as a zero, which leaves Union as is.
1569 if (PotentialConstantsAA->undefIsContained())
1570 continue;
1571
1572 // We need at least one constant in every set to compute an actual offset.
1573 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1574 // don't actually exist. In other words, the absence of constant values
1575 // implies that the operation can be assumed dead for now.
1576 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1577 if (AssumedSet.empty())
1578 return false;
1579
1580 OffsetInfo Product;
1581 for (const auto &ConstOffset : AssumedSet) {
1582 auto CopyPerOffset = Union;
1583 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1584 VI.second.getZExtValue());
1585 Product.merge(CopyPerOffset);
1586 }
1587 Union = Product;
1588 }
1589
1590 UsrOI = std::move(Union);
1591 return true;
1592}
1593
1594ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1595 using namespace AA::PointerInfo;
1597 const DataLayout &DL = A.getDataLayout();
1598 Value &AssociatedValue = getAssociatedValue();
1599
1600 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1601 OffsetInfoMap[&AssociatedValue].insert(0);
1602
1603 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1604 // One does not simply walk into a map and assign a reference to a possibly
1605 // new location. That can cause an invalidation before the assignment
1606 // happens, like so:
1607 //
1608 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1609 //
1610 // The RHS is a reference that may be invalidated by an insertion caused by
1611 // the LHS. So we ensure that the side-effect of the LHS happens first.
1612
1613 assert(OffsetInfoMap.contains(CurPtr) &&
1614 "CurPtr does not exist in the map!");
1615
1616 auto &UsrOI = OffsetInfoMap[Usr];
1617 auto &PtrOI = OffsetInfoMap[CurPtr];
1618 assert(!PtrOI.isUnassigned() &&
1619 "Cannot pass through if the input Ptr was not visited!");
1620 UsrOI.merge(PtrOI);
1621 Follow = true;
1622 return true;
1623 };
1624
1625 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1626 Value *CurPtr = U.get();
1627 User *Usr = U.getUser();
1628 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1629 << "\n");
1630 assert(OffsetInfoMap.count(CurPtr) &&
1631 "The current pointer offset should have been seeded!");
1632 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1633 "Current pointer should be assigned");
1634
1635 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1636 if (CE->isCast())
1637 return HandlePassthroughUser(Usr, CurPtr, Follow);
1638 if (!isa<GEPOperator>(CE)) {
1639 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1640 << "\n");
1641 return false;
1642 }
1643 }
1644 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1645 // Note the order here, the Usr access might change the map, CurPtr is
1646 // already in it though.
1647 auto &UsrOI = OffsetInfoMap[Usr];
1648 auto &PtrOI = OffsetInfoMap[CurPtr];
1649
1650 if (UsrOI.isUnknown())
1651 return true;
1652
1653 if (PtrOI.isUnknown()) {
1654 Follow = true;
1655 UsrOI.setUnknown();
1656 return true;
1657 }
1658
1659 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1660 return true;
1661 }
1662 if (isa<PtrToIntInst>(Usr))
1663 return false;
1664 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1665 return HandlePassthroughUser(Usr, CurPtr, Follow);
1666 // Returns are allowed if they are in the associated functions. Users can
1667 // then check the call site return. Returns from other functions can't be
1668 // tracked and are cause for invalidation.
1669 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1670 if (RI->getFunction() == getAssociatedFunction()) {
1671 auto &PtrOI = OffsetInfoMap[CurPtr];
1672 Changed |= setReachesReturn(PtrOI);
1673 return true;
1674 }
1675 return false;
1676 }
1677
1678 // For PHIs we need to take care of the recurrence explicitly as the value
1679 // might change while we iterate through a loop. For now, we give up if
1680 // the PHI is not invariant.
1681 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1682 // Note the order here, the Usr access might change the map, CurPtr is
1683 // already in it though.
1684 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1685 auto &UsrOI = PhiIt->second;
1686 auto &PtrOI = OffsetInfoMap[CurPtr];
1687
1688 // Check if the PHI operand has already an unknown offset as we can't
1689 // improve on that anymore.
1690 if (PtrOI.isUnknown()) {
1691 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1692 << *CurPtr << " in " << *PHI << "\n");
1693 Follow = !UsrOI.isUnknown();
1694 UsrOI.setUnknown();
1695 return true;
1696 }
1697
1698 // Check if the PHI is invariant (so far).
1699 if (UsrOI == PtrOI) {
1700 assert(!PtrOI.isUnassigned() &&
1701 "Cannot assign if the current Ptr was not visited!");
1702 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1703 return true;
1704 }
1705
1706 // Check if the PHI operand can be traced back to AssociatedValue.
1707 APInt Offset(
1708 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1709 0);
1710 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1711 DL, Offset, /* AllowNonInbounds */ true);
1712 auto It = OffsetInfoMap.find(CurPtrBase);
1713 if (It == OffsetInfoMap.end()) {
1714 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1715 << *CurPtr << " in " << *PHI
1716 << " (base: " << *CurPtrBase << ")\n");
1717 UsrOI.setUnknown();
1718 Follow = true;
1719 return true;
1720 }
1721
1722 // Check if the PHI operand is not dependent on the PHI itself. Every
1723 // recurrence is a cyclic net of PHIs in the data flow, and has an
1724 // equivalent Cycle in the control flow. One of those PHIs must be in the
1725 // header of that control flow Cycle. This is independent of the choice of
1726 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1727 // every Cycle header; if such a node is marked unknown, this will
1728 // eventually propagate through the whole net of PHIs in the recurrence.
1729 const auto *CI =
1730 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1731 *PHI->getFunction());
1732 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1733 auto BaseOI = It->getSecond();
1734 BaseOI.addToAll(Offset.getZExtValue());
1735 if (IsFirstPHIUser || BaseOI == UsrOI) {
1736 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1737 << " in " << *Usr << "\n");
1738 return HandlePassthroughUser(Usr, CurPtr, Follow);
1739 }
1740
1741 LLVM_DEBUG(
1742 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1743 << *CurPtr << " in " << *PHI << "\n");
1744 UsrOI.setUnknown();
1745 Follow = true;
1746 return true;
1747 }
1748
1749 UsrOI.merge(PtrOI);
1750 Follow = true;
1751 return true;
1752 }
1753
1754 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1755 // If the access is to a pointer that may or may not be the associated
1756 // value, e.g. due to a PHI, we cannot assume it will be read.
1757 AccessKind AK = AccessKind::AK_R;
1758 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1759 AK = AccessKind(AK | AccessKind::AK_MUST);
1760 else
1761 AK = AccessKind(AK | AccessKind::AK_MAY);
1762 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1763 OffsetInfoMap[CurPtr].Offsets, Changed,
1764 *LoadI->getType()))
1765 return false;
1766
1767 auto IsAssumption = [](Instruction &I) {
1768 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1769 return II->isAssumeLikeIntrinsic();
1770 return false;
1771 };
1772
1773 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1774 // Check if the assumption and the load are executed together without
1775 // memory modification.
1776 do {
1777 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1778 return true;
1779 FromI = FromI->getNextNode();
1780 } while (FromI && FromI != ToI);
1781 return false;
1782 };
1783
1784 BasicBlock *BB = LoadI->getParent();
1785 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1786 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1787 return false;
1788 BasicBlock *IntrBB = IntrI.getParent();
1789 if (IntrI.getParent() == BB) {
1790 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1791 return false;
1792 } else {
1793 auto PredIt = pred_begin(IntrBB);
1794 if (PredIt == pred_end(IntrBB))
1795 return false;
1796 if ((*PredIt) != BB)
1797 return false;
1798 if (++PredIt != pred_end(IntrBB))
1799 return false;
1800 for (auto *SuccBB : successors(BB)) {
1801 if (SuccBB == IntrBB)
1802 continue;
1803 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1804 continue;
1805 return false;
1806 }
1807 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1808 return false;
1809 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1810 return false;
1811 }
1812 return true;
1813 };
1814
1815 std::pair<Value *, IntrinsicInst *> Assumption;
1816 for (const Use &LoadU : LoadI->uses()) {
1817 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1818 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1819 continue;
1820 for (const Use &CmpU : CmpI->uses()) {
1821 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1822 if (!IsValidAssume(*IntrI))
1823 continue;
1824 int Idx = CmpI->getOperandUse(0) == LoadU;
1825 Assumption = {CmpI->getOperand(Idx), IntrI};
1826 break;
1827 }
1828 }
1829 }
1830 if (Assumption.first)
1831 break;
1832 }
1833
1834 // Check if we found an assumption associated with this load.
1835 if (!Assumption.first || !Assumption.second)
1836 return true;
1837
1838 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1839 << *Assumption.second << ": " << *LoadI
1840 << " == " << *Assumption.first << "\n");
1841 bool UsedAssumedInformation = false;
1842 std::optional<Value *> Content = nullptr;
1843 if (Assumption.first)
1844 Content =
1845 A.getAssumedSimplified(*Assumption.first, *this,
1846 UsedAssumedInformation, AA::Interprocedural);
1847 return handleAccess(
1848 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1849 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1850 }
1851
1852 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1853 ArrayRef<Value *> OtherOps, AccessKind AK) {
1854 for (auto *OtherOp : OtherOps) {
1855 if (OtherOp == CurPtr) {
1856 LLVM_DEBUG(
1857 dbgs()
1858 << "[AAPointerInfo] Escaping use in store like instruction " << I
1859 << "\n");
1860 return false;
1861 }
1862 }
1863
1864 // If the access is to a pointer that may or may not be the associated
1865 // value, e.g. due to a PHI, we cannot assume it will be written.
1866 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1867 AK = AccessKind(AK | AccessKind::AK_MUST);
1868 else
1869 AK = AccessKind(AK | AccessKind::AK_MAY);
1870 bool UsedAssumedInformation = false;
1871 std::optional<Value *> Content = nullptr;
1872 if (ValueOp)
1873 Content = A.getAssumedSimplified(
1874 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1875 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1876 Changed, ValueTy);
1877 };
1878
1879 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1880 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1881 *StoreI->getValueOperand()->getType(),
1882 {StoreI->getValueOperand()}, AccessKind::AK_W);
1883 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1884 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1885 {RMWI->getValOperand()}, AccessKind::AK_RW);
1886 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1887 return HandleStoreLike(
1888 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1889 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1890 AccessKind::AK_RW);
1891
1892 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1893 if (CB->isLifetimeStartOrEnd())
1894 return true;
1895 const auto *TLI =
1896 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1897 if (getFreedOperand(CB, TLI) == U)
1898 return true;
1899 if (CB->isArgOperand(&U)) {
1900 unsigned ArgNo = CB->getArgOperandNo(&U);
1901 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1902 *this, IRPosition::callsite_argument(*CB, ArgNo),
1904 if (!CSArgPI)
1905 return false;
1906 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1907 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1908 IsArgMustAcc) |
1909 Changed;
1910 if (!CSArgPI->reachesReturn())
1911 return isValidState();
1912
1914 if (!Callee || Callee->arg_size() <= ArgNo)
1915 return false;
1916 bool UsedAssumedInformation = false;
1917 auto ReturnedValue = A.getAssumedSimplified(
1918 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1920 auto *ReturnedArg =
1921 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1922 auto *Arg = Callee->getArg(ArgNo);
1923 if (ReturnedArg && Arg != ReturnedArg)
1924 return true;
1925 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1926 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1928 if (!CSRetPI)
1929 return false;
1930 OffsetInfo OI = OffsetInfoMap[CurPtr];
1931 CSArgPI->addReturnedOffsetsTo(OI);
1932 Changed =
1933 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1934 return isValidState();
1935 }
1936 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1937 << "\n");
1938 return false;
1939 }
1940
1941 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1942 return false;
1943 };
1944 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1945 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1946 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1947 if (OffsetInfoMap.count(NewU)) {
1948 LLVM_DEBUG({
1949 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1950 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1951 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1952 << "\n";
1953 }
1954 });
1955 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1956 }
1957 bool Unused;
1958 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1959 };
1960 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1961 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1962 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1963 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1964 return indicatePessimisticFixpoint();
1965 }
1966
1967 LLVM_DEBUG({
1968 dbgs() << "Accesses by bin after update:\n";
1969 dumpState(dbgs());
1970 });
1971
1972 return Changed;
1973}
1974
1975struct AAPointerInfoReturned final : AAPointerInfoImpl {
1976 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1977 : AAPointerInfoImpl(IRP, A) {}
1978
1979 /// See AbstractAttribute::updateImpl(...).
1980 ChangeStatus updateImpl(Attributor &A) override {
1981 return indicatePessimisticFixpoint();
1982 }
1983
1984 /// See AbstractAttribute::trackStatistics()
1985 void trackStatistics() const override {
1986 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1987 }
1988};
1989
1990struct AAPointerInfoArgument final : AAPointerInfoFloating {
1991 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1992 : AAPointerInfoFloating(IRP, A) {}
1993
1994 /// See AbstractAttribute::trackStatistics()
1995 void trackStatistics() const override {
1996 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1997 }
1998};
1999
2000struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
2001 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
2002 : AAPointerInfoFloating(IRP, A) {}
2003
2004 /// See AbstractAttribute::updateImpl(...).
2005 ChangeStatus updateImpl(Attributor &A) override {
2006 using namespace AA::PointerInfo;
2007 // We handle memory intrinsics explicitly, at least the first (=
2008 // destination) and second (=source) arguments as we know how they are
2009 // accessed.
2010 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2011 int64_t LengthVal = AA::RangeTy::Unknown;
2012 if (auto Length = MI->getLengthInBytes())
2013 LengthVal = Length->getSExtValue();
2014 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2015 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2016 if (ArgNo > 1) {
2017 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2018 << *MI << "\n");
2019 return indicatePessimisticFixpoint();
2020 } else {
2021 auto Kind =
2022 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2023 Changed =
2024 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2025 }
2026 LLVM_DEBUG({
2027 dbgs() << "Accesses by bin after update:\n";
2028 dumpState(dbgs());
2029 });
2030
2031 return Changed;
2032 }
2033
2034 // TODO: Once we have call site specific value information we can provide
2035 // call site specific liveness information and then it makes
2036 // sense to specialize attributes for call sites arguments instead of
2037 // redirecting requests to the callee argument.
2038 Argument *Arg = getAssociatedArgument();
2039 if (Arg) {
2040 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2041 auto *ArgAA =
2042 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2043 if (ArgAA && ArgAA->getState().isValidState())
2044 return translateAndAddStateFromCallee(A, *ArgAA,
2045 *cast<CallBase>(getCtxI()));
2046 if (!Arg->getParent()->isDeclaration())
2047 return indicatePessimisticFixpoint();
2048 }
2049
2050 bool IsKnownNoCapture;
2052 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2053 return indicatePessimisticFixpoint();
2054
2055 bool IsKnown = false;
2056 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2057 return ChangeStatus::UNCHANGED;
2058 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2059 auto Kind =
2060 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2061 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2062 nullptr);
2063 }
2064
2065 /// See AbstractAttribute::trackStatistics()
2066 void trackStatistics() const override {
2067 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2068 }
2069};
2070
2071struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2072 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2073 : AAPointerInfoFloating(IRP, A) {}
2074
2075 /// See AbstractAttribute::trackStatistics()
2076 void trackStatistics() const override {
2077 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2078 }
2079};
2080} // namespace
2081
2082/// -----------------------NoUnwind Function Attribute--------------------------
2083
2084namespace {
2085struct AANoUnwindImpl : AANoUnwind {
2086 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2087
2088 /// See AbstractAttribute::initialize(...).
2089 void initialize(Attributor &A) override {
2090 bool IsKnown;
2092 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2093 (void)IsKnown;
2094 }
2095
2096 const std::string getAsStr(Attributor *A) const override {
2097 return getAssumed() ? "nounwind" : "may-unwind";
2098 }
2099
2100 /// See AbstractAttribute::updateImpl(...).
2101 ChangeStatus updateImpl(Attributor &A) override {
2102 auto Opcodes = {
2103 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2104 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2105 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2106
2107 auto CheckForNoUnwind = [&](Instruction &I) {
2108 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2109 return true;
2110
2111 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2112 bool IsKnownNoUnwind;
2114 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2115 IsKnownNoUnwind);
2116 }
2117 return false;
2118 };
2119
2120 bool UsedAssumedInformation = false;
2121 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2122 UsedAssumedInformation))
2123 return indicatePessimisticFixpoint();
2124
2125 return ChangeStatus::UNCHANGED;
2126 }
2127};
2128
2129struct AANoUnwindFunction final : public AANoUnwindImpl {
2130 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2131 : AANoUnwindImpl(IRP, A) {}
2132
2133 /// See AbstractAttribute::trackStatistics()
2134 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2135};
2136
2137/// NoUnwind attribute deduction for a call sites.
2138struct AANoUnwindCallSite final
2139 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2140 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2141 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2142
2143 /// See AbstractAttribute::trackStatistics()
2144 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2145};
2146} // namespace
2147
2148/// ------------------------ NoSync Function Attribute -------------------------
2149
2150bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2151 switch (CB.getIntrinsicID()) {
2152 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2153 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2154 case Intrinsic::nvvm_barrier0_and:
2155 case Intrinsic::nvvm_barrier0_or:
2156 case Intrinsic::nvvm_barrier0_popc:
2157 return true;
2158 case Intrinsic::amdgcn_s_barrier:
2159 if (ExecutedAligned)
2160 return true;
2161 break;
2162 default:
2163 break;
2164 }
2165 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2166}
2167
2169 if (!I->isAtomic())
2170 return false;
2171
2172 if (auto *FI = dyn_cast<FenceInst>(I))
2173 // All legal orderings for fence are stronger than monotonic.
2174 return FI->getSyncScopeID() != SyncScope::SingleThread;
2175 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2176 // Unordered is not a legal ordering for cmpxchg.
2177 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2178 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2179 }
2180
2181 AtomicOrdering Ordering;
2182 switch (I->getOpcode()) {
2183 case Instruction::AtomicRMW:
2184 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2185 break;
2186 case Instruction::Store:
2187 Ordering = cast<StoreInst>(I)->getOrdering();
2188 break;
2189 case Instruction::Load:
2190 Ordering = cast<LoadInst>(I)->getOrdering();
2191 break;
2192 default:
2194 "New atomic operations need to be known in the attributor.");
2195 }
2196
2197 return (Ordering != AtomicOrdering::Unordered &&
2198 Ordering != AtomicOrdering::Monotonic);
2199}
2200
2201/// Return true if this intrinsic is nosync. This is only used for intrinsics
2202/// which would be nosync except that they have a volatile flag. All other
2203/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2205 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2206 return !MI->isVolatile();
2207 return false;
2208}
2209
2210namespace {
2211struct AANoSyncImpl : AANoSync {
2212 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2213
2214 /// See AbstractAttribute::initialize(...).
2215 void initialize(Attributor &A) override {
2216 bool IsKnown;
2217 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2218 DepClassTy::NONE, IsKnown));
2219 (void)IsKnown;
2220 }
2221
2222 const std::string getAsStr(Attributor *A) const override {
2223 return getAssumed() ? "nosync" : "may-sync";
2224 }
2225
2226 /// See AbstractAttribute::updateImpl(...).
2227 ChangeStatus updateImpl(Attributor &A) override;
2228};
2229
2230ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2231
2232 auto CheckRWInstForNoSync = [&](Instruction &I) {
2233 return AA::isNoSyncInst(A, I, *this);
2234 };
2235
2236 auto CheckForNoSync = [&](Instruction &I) {
2237 // At this point we handled all read/write effects and they are all
2238 // nosync, so they can be skipped.
2239 if (I.mayReadOrWriteMemory())
2240 return true;
2241
2242 bool IsKnown;
2243 CallBase &CB = cast<CallBase>(I);
2246 IsKnown))
2247 return true;
2248
2249 // non-convergent and readnone imply nosync.
2250 return !CB.isConvergent();
2251 };
2252
2253 bool UsedAssumedInformation = false;
2254 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2255 UsedAssumedInformation) ||
2256 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2257 UsedAssumedInformation))
2258 return indicatePessimisticFixpoint();
2259
2261}
2262
2263struct AANoSyncFunction final : public AANoSyncImpl {
2264 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2265 : AANoSyncImpl(IRP, A) {}
2266
2267 /// See AbstractAttribute::trackStatistics()
2268 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2269};
2270
2271/// NoSync attribute deduction for a call sites.
2272struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2273 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2274 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2275
2276 /// See AbstractAttribute::trackStatistics()
2277 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2278};
2279} // namespace
2280
2281/// ------------------------ No-Free Attributes ----------------------------
2282
2283namespace {
2284struct AANoFreeImpl : public AANoFree {
2285 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2286
2287 /// See AbstractAttribute::initialize(...).
2288 void initialize(Attributor &A) override {
2289 bool IsKnown;
2290 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2291 DepClassTy::NONE, IsKnown));
2292 (void)IsKnown;
2293 }
2294
2295 /// See AbstractAttribute::updateImpl(...).
2296 ChangeStatus updateImpl(Attributor &A) override {
2297 auto CheckForNoFree = [&](Instruction &I) {
2298 bool IsKnown;
2301 DepClassTy::REQUIRED, IsKnown);
2302 };
2303
2304 bool UsedAssumedInformation = false;
2305 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2306 UsedAssumedInformation))
2307 return indicatePessimisticFixpoint();
2308 return ChangeStatus::UNCHANGED;
2309 }
2310
2311 /// See AbstractAttribute::getAsStr().
2312 const std::string getAsStr(Attributor *A) const override {
2313 return getAssumed() ? "nofree" : "may-free";
2314 }
2315};
2316
2317struct AANoFreeFunction final : public AANoFreeImpl {
2318 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2319 : AANoFreeImpl(IRP, A) {}
2320
2321 /// See AbstractAttribute::trackStatistics()
2322 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2323};
2324
2325/// NoFree attribute deduction for a call sites.
2326struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2327 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2328 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2329
2330 /// See AbstractAttribute::trackStatistics()
2331 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2332};
2333
2334/// NoFree attribute for floating values.
2335struct AANoFreeFloating : AANoFreeImpl {
2336 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2337 : AANoFreeImpl(IRP, A) {}
2338
2339 /// See AbstractAttribute::trackStatistics()
2340 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2341
2342 /// See Abstract Attribute::updateImpl(...).
2343 ChangeStatus updateImpl(Attributor &A) override {
2344 const IRPosition &IRP = getIRPosition();
2345
2346 bool IsKnown;
2349 DepClassTy::OPTIONAL, IsKnown))
2350 return ChangeStatus::UNCHANGED;
2351
2352 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2353 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2354 Instruction *UserI = cast<Instruction>(U.getUser());
2355 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2356 if (CB->isBundleOperand(&U))
2357 return false;
2358 if (!CB->isArgOperand(&U))
2359 return true;
2360 unsigned ArgNo = CB->getArgOperandNo(&U);
2361
2362 bool IsKnown;
2364 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2365 DepClassTy::REQUIRED, IsKnown);
2366 }
2367
2368 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2369 isa<SelectInst>(UserI)) {
2370 Follow = true;
2371 return true;
2372 }
2373 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2374 return true;
2375
2376 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2377 return true;
2378
2379 // Unknown user.
2380 return false;
2381 };
2382 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2383 return indicatePessimisticFixpoint();
2384
2385 return ChangeStatus::UNCHANGED;
2386 }
2387};
2388
2389/// NoFree attribute for a call site argument.
2390struct AANoFreeArgument final : AANoFreeFloating {
2391 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2392 : AANoFreeFloating(IRP, A) {}
2393
2394 /// See AbstractAttribute::trackStatistics()
2395 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2396};
2397
2398/// NoFree attribute for call site arguments.
2399struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2400 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2401 : AANoFreeFloating(IRP, A) {}
2402
2403 /// See AbstractAttribute::updateImpl(...).
2404 ChangeStatus updateImpl(Attributor &A) override {
2405 // TODO: Once we have call site specific value information we can provide
2406 // call site specific liveness information and then it makes
2407 // sense to specialize attributes for call sites arguments instead of
2408 // redirecting requests to the callee argument.
2409 Argument *Arg = getAssociatedArgument();
2410 if (!Arg)
2411 return indicatePessimisticFixpoint();
2412 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2413 bool IsKnown;
2415 DepClassTy::REQUIRED, IsKnown))
2416 return ChangeStatus::UNCHANGED;
2417 return indicatePessimisticFixpoint();
2418 }
2419
2420 /// See AbstractAttribute::trackStatistics()
2421 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2422};
2423
2424/// NoFree attribute for function return value.
2425struct AANoFreeReturned final : AANoFreeFloating {
2426 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2427 : AANoFreeFloating(IRP, A) {
2428 llvm_unreachable("NoFree is not applicable to function returns!");
2429 }
2430
2431 /// See AbstractAttribute::initialize(...).
2432 void initialize(Attributor &A) override {
2433 llvm_unreachable("NoFree is not applicable to function returns!");
2434 }
2435
2436 /// See AbstractAttribute::updateImpl(...).
2437 ChangeStatus updateImpl(Attributor &A) override {
2438 llvm_unreachable("NoFree is not applicable to function returns!");
2439 }
2440
2441 /// See AbstractAttribute::trackStatistics()
2442 void trackStatistics() const override {}
2443};
2444
2445/// NoFree attribute deduction for a call site return value.
2446struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2447 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2448 : AANoFreeFloating(IRP, A) {}
2449
2450 ChangeStatus manifest(Attributor &A) override {
2451 return ChangeStatus::UNCHANGED;
2452 }
2453 /// See AbstractAttribute::trackStatistics()
2454 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2455};
2456} // namespace
2457
2458/// ------------------------ NonNull Argument Attribute ------------------------
2459
2461 Attribute::AttrKind ImpliedAttributeKind,
2462 bool IgnoreSubsumingPositions) {
2464 AttrKinds.push_back(Attribute::NonNull);
2467 AttrKinds.push_back(Attribute::Dereferenceable);
2468 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2469 return true;
2470
2471 DominatorTree *DT = nullptr;
2472 AssumptionCache *AC = nullptr;
2473 InformationCache &InfoCache = A.getInfoCache();
2474 if (const Function *Fn = IRP.getAnchorScope()) {
2475 if (!Fn->isDeclaration()) {
2478 }
2479 }
2480
2482 if (IRP.getPositionKind() != IRP_RETURNED) {
2483 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2484 } else {
2485 bool UsedAssumedInformation = false;
2486 if (!A.checkForAllInstructions(
2487 [&](Instruction &I) {
2488 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2489 return true;
2490 },
2491 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2492 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2493 return false;
2494 }
2495
2496 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2497 return !isKnownNonZero(
2498 VAC.getValue(),
2499 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2500 }))
2501 return false;
2502
2503 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2504 Attribute::NonNull)});
2505 return true;
2506}
2507
2508namespace {
2509static int64_t getKnownNonNullAndDerefBytesForUse(
2510 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2511 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2512 TrackUse = false;
2513
2514 const Value *UseV = U->get();
2515 if (!UseV->getType()->isPointerTy())
2516 return 0;
2517
2518 // We need to follow common pointer manipulation uses to the accesses they
2519 // feed into. We can try to be smart to avoid looking through things we do not
2520 // like for now, e.g., non-inbounds GEPs.
2521 if (isa<CastInst>(I)) {
2522 TrackUse = true;
2523 return 0;
2524 }
2525
2527 TrackUse = true;
2528 return 0;
2529 }
2530
2531 Type *PtrTy = UseV->getType();
2532 const Function *F = I->getFunction();
2535 const DataLayout &DL = A.getInfoCache().getDL();
2536 if (const auto *CB = dyn_cast<CallBase>(I)) {
2537 if (CB->isBundleOperand(U)) {
2538 if (RetainedKnowledge RK = getKnowledgeFromUse(
2539 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2540 IsNonNull |=
2541 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2542 return RK.ArgValue;
2543 }
2544 return 0;
2545 }
2546
2547 if (CB->isCallee(U)) {
2548 IsNonNull |= !NullPointerIsDefined;
2549 return 0;
2550 }
2551
2552 unsigned ArgNo = CB->getArgOperandNo(U);
2553 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2554 // As long as we only use known information there is no need to track
2555 // dependences here.
2556 bool IsKnownNonNull;
2558 DepClassTy::NONE, IsKnownNonNull);
2559 IsNonNull |= IsKnownNonNull;
2560 auto *DerefAA =
2561 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2562 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2563 }
2564
2565 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2566 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2567 Loc->Size.isScalable() || I->isVolatile())
2568 return 0;
2569
2570 int64_t Offset;
2571 const Value *Base =
2572 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2573 if (Base && Base == &AssociatedValue) {
2574 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2575 IsNonNull |= !NullPointerIsDefined;
2576 return std::max(int64_t(0), DerefBytes);
2577 }
2578
2579 /// Corner case when an offset is 0.
2581 /*AllowNonInbounds*/ true);
2582 if (Base && Base == &AssociatedValue && Offset == 0) {
2583 int64_t DerefBytes = Loc->Size.getValue();
2584 IsNonNull |= !NullPointerIsDefined;
2585 return std::max(int64_t(0), DerefBytes);
2586 }
2587
2588 return 0;
2589}
2590
2591struct AANonNullImpl : AANonNull {
2592 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2593
2594 /// See AbstractAttribute::initialize(...).
2595 void initialize(Attributor &A) override {
2596 Value &V = *getAssociatedValue().stripPointerCasts();
2597 if (isa<ConstantPointerNull>(V)) {
2598 indicatePessimisticFixpoint();
2599 return;
2600 }
2601
2602 if (Instruction *CtxI = getCtxI())
2603 followUsesInMBEC(*this, A, getState(), *CtxI);
2604 }
2605
2606 /// See followUsesInMBEC
2607 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2608 AANonNull::StateType &State) {
2609 bool IsNonNull = false;
2610 bool TrackUse = false;
2611 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2612 IsNonNull, TrackUse);
2613 State.setKnown(IsNonNull);
2614 return TrackUse;
2615 }
2616
2617 /// See AbstractAttribute::getAsStr().
2618 const std::string getAsStr(Attributor *A) const override {
2619 return getAssumed() ? "nonnull" : "may-null";
2620 }
2621};
2622
2623/// NonNull attribute for a floating value.
2624struct AANonNullFloating : public AANonNullImpl {
2625 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2626 : AANonNullImpl(IRP, A) {}
2627
2628 /// See AbstractAttribute::updateImpl(...).
2629 ChangeStatus updateImpl(Attributor &A) override {
2630 auto CheckIRP = [&](const IRPosition &IRP) {
2631 bool IsKnownNonNull;
2633 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2634 };
2635
2636 bool Stripped;
2637 bool UsedAssumedInformation = false;
2638 Value *AssociatedValue = &getAssociatedValue();
2640 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2641 AA::AnyScope, UsedAssumedInformation))
2642 Stripped = false;
2643 else
2644 Stripped =
2645 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2646
2647 if (!Stripped) {
2648 bool IsKnown;
2649 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2650 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2651 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2652 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2653 IsKnown);
2654 }))
2655 return ChangeStatus::UNCHANGED;
2656 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2658 A, this, IRPosition::value(*Select->getFalseValue()),
2659 DepClassTy::OPTIONAL, IsKnown) &&
2661 A, this, IRPosition::value(*Select->getTrueValue()),
2662 DepClassTy::OPTIONAL, IsKnown))
2663 return ChangeStatus::UNCHANGED;
2664
2665 // If we haven't stripped anything we might still be able to use a
2666 // different AA, but only if the IRP changes. Effectively when we
2667 // interpret this not as a call site value but as a floating/argument
2668 // value.
2669 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2670 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2671 return indicatePessimisticFixpoint();
2672 return ChangeStatus::UNCHANGED;
2673 }
2674
2675 for (const auto &VAC : Values)
2676 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2677 return indicatePessimisticFixpoint();
2678
2679 return ChangeStatus::UNCHANGED;
2680 }
2681
2682 /// See AbstractAttribute::trackStatistics()
2683 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2684};
2685
2686/// NonNull attribute for function return value.
2687struct AANonNullReturned final
2688 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2689 false, AANonNull::IRAttributeKind, false> {
2690 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2691 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2692 false, Attribute::NonNull, false>(IRP, A) {
2693 }
2694
2695 /// See AbstractAttribute::getAsStr().
2696 const std::string getAsStr(Attributor *A) const override {
2697 return getAssumed() ? "nonnull" : "may-null";
2698 }
2699
2700 /// See AbstractAttribute::trackStatistics()
2701 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2702};
2703
2704/// NonNull attribute for function argument.
2705struct AANonNullArgument final
2706 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2707 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2708 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2709
2710 /// See AbstractAttribute::trackStatistics()
2711 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2712};
2713
2714struct AANonNullCallSiteArgument final : AANonNullFloating {
2715 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2716 : AANonNullFloating(IRP, A) {}
2717
2718 /// See AbstractAttribute::trackStatistics()
2719 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2720};
2721
2722/// NonNull attribute for a call site return position.
2723struct AANonNullCallSiteReturned final
2724 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2725 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2726 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2727
2728 /// See AbstractAttribute::trackStatistics()
2729 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2730};
2731} // namespace
2732
2733/// ------------------------ Must-Progress Attributes --------------------------
2734namespace {
2735struct AAMustProgressImpl : public AAMustProgress {
2736 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2737 : AAMustProgress(IRP, A) {}
2738
2739 /// See AbstractAttribute::initialize(...).
2740 void initialize(Attributor &A) override {
2741 bool IsKnown;
2743 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2744 (void)IsKnown;
2745 }
2746
2747 /// See AbstractAttribute::getAsStr()
2748 const std::string getAsStr(Attributor *A) const override {
2749 return getAssumed() ? "mustprogress" : "may-not-progress";
2750 }
2751};
2752
2753struct AAMustProgressFunction final : AAMustProgressImpl {
2754 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2755 : AAMustProgressImpl(IRP, A) {}
2756
2757 /// See AbstractAttribute::updateImpl(...).
2758 ChangeStatus updateImpl(Attributor &A) override {
2759 bool IsKnown;
2761 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2762 if (IsKnown)
2763 return indicateOptimisticFixpoint();
2764 return ChangeStatus::UNCHANGED;
2765 }
2766
2767 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2768 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2769 bool IsKnownMustProgress;
2771 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2772 /* IgnoreSubsumingPositions */ true);
2773 };
2774
2775 bool AllCallSitesKnown = true;
2776 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2777 /* RequireAllCallSites */ true,
2778 AllCallSitesKnown))
2779 return indicatePessimisticFixpoint();
2780
2781 return ChangeStatus::UNCHANGED;
2782 }
2783
2784 /// See AbstractAttribute::trackStatistics()
2785 void trackStatistics() const override {
2786 STATS_DECLTRACK_FN_ATTR(mustprogress)
2787 }
2788};
2789
2790/// MustProgress attribute deduction for a call sites.
2791struct AAMustProgressCallSite final : AAMustProgressImpl {
2792 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2793 : AAMustProgressImpl(IRP, A) {}
2794
2795 /// See AbstractAttribute::updateImpl(...).
2796 ChangeStatus updateImpl(Attributor &A) override {
2797 // TODO: Once we have call site specific value information we can provide
2798 // call site specific liveness information and then it makes
2799 // sense to specialize attributes for call sites arguments instead of
2800 // redirecting requests to the callee argument.
2801 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2802 bool IsKnownMustProgress;
2804 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2805 return indicatePessimisticFixpoint();
2806 return ChangeStatus::UNCHANGED;
2807 }
2808
2809 /// See AbstractAttribute::trackStatistics()
2810 void trackStatistics() const override {
2811 STATS_DECLTRACK_CS_ATTR(mustprogress);
2812 }
2813};
2814} // namespace
2815
2816/// ------------------------ No-Recurse Attributes ----------------------------
2817
2818namespace {
2819struct AANoRecurseImpl : public AANoRecurse {
2820 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2821
2822 /// See AbstractAttribute::initialize(...).
2823 void initialize(Attributor &A) override {
2824 bool IsKnown;
2826 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2827 (void)IsKnown;
2828 }
2829
2830 /// See AbstractAttribute::getAsStr()
2831 const std::string getAsStr(Attributor *A) const override {
2832 return getAssumed() ? "norecurse" : "may-recurse";
2833 }
2834};
2835
2836struct AANoRecurseFunction final : AANoRecurseImpl {
2837 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2838 : AANoRecurseImpl(IRP, A) {}
2839
2840 /// See AbstractAttribute::updateImpl(...).
2841 ChangeStatus updateImpl(Attributor &A) override {
2842
2843 // If all live call sites are known to be no-recurse, we are as well.
2844 auto CallSitePred = [&](AbstractCallSite ACS) {
2845 bool IsKnownNoRecurse;
2847 A, this,
2848 IRPosition::function(*ACS.getInstruction()->getFunction()),
2849 DepClassTy::NONE, IsKnownNoRecurse))
2850 return false;
2851 return IsKnownNoRecurse;
2852 };
2853 bool UsedAssumedInformation = false;
2854 if (A.checkForAllCallSites(CallSitePred, *this, true,
2855 UsedAssumedInformation)) {
2856 // If we know all call sites and all are known no-recurse, we are done.
2857 // If all known call sites, which might not be all that exist, are known
2858 // to be no-recurse, we are not done but we can continue to assume
2859 // no-recurse. If one of the call sites we have not visited will become
2860 // live, another update is triggered.
2861 if (!UsedAssumedInformation)
2862 indicateOptimisticFixpoint();
2863 return ChangeStatus::UNCHANGED;
2864 }
2865
2866 const AAInterFnReachability *EdgeReachability =
2867 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2868 DepClassTy::REQUIRED);
2869 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2870 return indicatePessimisticFixpoint();
2871 return ChangeStatus::UNCHANGED;
2872 }
2873
2874 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2875};
2876
2877/// NoRecurse attribute deduction for a call sites.
2878struct AANoRecurseCallSite final
2879 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2880 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2881 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2882
2883 /// See AbstractAttribute::trackStatistics()
2884 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2885};
2886} // namespace
2887
2888/// ------------------------ No-Convergent Attribute --------------------------
2889
2890namespace {
2891struct AANonConvergentImpl : public AANonConvergent {
2892 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2893 : AANonConvergent(IRP, A) {}
2894
2895 /// See AbstractAttribute::getAsStr()
2896 const std::string getAsStr(Attributor *A) const override {
2897 return getAssumed() ? "non-convergent" : "may-be-convergent";
2898 }
2899};
2900
2901struct AANonConvergentFunction final : AANonConvergentImpl {
2902 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2903 : AANonConvergentImpl(IRP, A) {}
2904
2905 /// See AbstractAttribute::updateImpl(...).
2906 ChangeStatus updateImpl(Attributor &A) override {
2907 // If all function calls are known to not be convergent, we are not
2908 // convergent.
2909 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2910 CallBase &CB = cast<CallBase>(Inst);
2912 if (!Callee || Callee->isIntrinsic()) {
2913 return false;
2914 }
2915 if (Callee->isDeclaration()) {
2916 return !Callee->hasFnAttribute(Attribute::Convergent);
2917 }
2918 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2919 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2920 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2921 };
2922
2923 bool UsedAssumedInformation = false;
2924 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2925 UsedAssumedInformation)) {
2926 return indicatePessimisticFixpoint();
2927 }
2928 return ChangeStatus::UNCHANGED;
2929 }
2930
2931 ChangeStatus manifest(Attributor &A) override {
2932 if (isKnownNotConvergent() &&
2933 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2934 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2935 return ChangeStatus::CHANGED;
2936 }
2937 return ChangeStatus::UNCHANGED;
2938 }
2939
2940 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2941};
2942} // namespace
2943
2944/// -------------------- Undefined-Behavior Attributes ------------------------
2945
2946namespace {
2947struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2948 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2949 : AAUndefinedBehavior(IRP, A) {}
2950
2951 /// See AbstractAttribute::updateImpl(...).
2952 // through a pointer (i.e. also branches etc.)
2953 ChangeStatus updateImpl(Attributor &A) override {
2954 const size_t UBPrevSize = KnownUBInsts.size();
2955 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2956
2957 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2958 // Lang ref now states volatile store is not UB, let's skip them.
2959 if (I.isVolatile() && I.mayWriteToMemory())
2960 return true;
2961
2962 // Skip instructions that are already saved.
2963 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2964 return true;
2965
2966 // If we reach here, we know we have an instruction
2967 // that accesses memory through a pointer operand,
2968 // for which getPointerOperand() should give it to us.
2969 Value *PtrOp =
2970 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2971 assert(PtrOp &&
2972 "Expected pointer operand of memory accessing instruction");
2973
2974 // Either we stopped and the appropriate action was taken,
2975 // or we got back a simplified value to continue.
2976 std::optional<Value *> SimplifiedPtrOp =
2977 stopOnUndefOrAssumed(A, PtrOp, &I);
2978 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2979 return true;
2980 const Value *PtrOpVal = *SimplifiedPtrOp;
2981
2982 // A memory access through a pointer is considered UB
2983 // only if the pointer has constant null value.
2984 // TODO: Expand it to not only check constant values.
2985 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2986 AssumedNoUBInsts.insert(&I);
2987 return true;
2988 }
2989 const Type *PtrTy = PtrOpVal->getType();
2990
2991 // Because we only consider instructions inside functions,
2992 // assume that a parent function exists.
2993 const Function *F = I.getFunction();
2994
2995 // A memory access using constant null pointer is only considered UB
2996 // if null pointer is _not_ defined for the target platform.
2998 AssumedNoUBInsts.insert(&I);
2999 else
3000 KnownUBInsts.insert(&I);
3001 return true;
3002 };
3003
3004 auto InspectBrInstForUB = [&](Instruction &I) {
3005 // A conditional branch instruction is considered UB if it has `undef`
3006 // condition.
3007
3008 // Skip instructions that are already saved.
3009 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3010 return true;
3011
3012 // We know we have a branch instruction.
3013 auto *BrInst = cast<BranchInst>(&I);
3014
3015 // Unconditional branches are never considered UB.
3016 if (BrInst->isUnconditional())
3017 return true;
3018
3019 // Either we stopped and the appropriate action was taken,
3020 // or we got back a simplified value to continue.
3021 std::optional<Value *> SimplifiedCond =
3022 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3023 if (!SimplifiedCond || !*SimplifiedCond)
3024 return true;
3025 AssumedNoUBInsts.insert(&I);
3026 return true;
3027 };
3028
3029 auto InspectCallSiteForUB = [&](Instruction &I) {
3030 // Check whether a callsite always cause UB or not
3031
3032 // Skip instructions that are already saved.
3033 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3034 return true;
3035
3036 // Check nonnull and noundef argument attribute violation for each
3037 // callsite.
3038 CallBase &CB = cast<CallBase>(I);
3040 if (!Callee)
3041 return true;
3042 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3043 // If current argument is known to be simplified to null pointer and the
3044 // corresponding argument position is known to have nonnull attribute,
3045 // the argument is poison. Furthermore, if the argument is poison and
3046 // the position is known to have noundef attriubte, this callsite is
3047 // considered UB.
3048 if (idx >= Callee->arg_size())
3049 break;
3050 Value *ArgVal = CB.getArgOperand(idx);
3051 if (!ArgVal)
3052 continue;
3053 // Here, we handle three cases.
3054 // (1) Not having a value means it is dead. (we can replace the value
3055 // with undef)
3056 // (2) Simplified to undef. The argument violate noundef attriubte.
3057 // (3) Simplified to null pointer where known to be nonnull.
3058 // The argument is a poison value and violate noundef attribute.
3059 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3060 bool IsKnownNoUndef;
3062 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3063 if (!IsKnownNoUndef)
3064 continue;
3065 bool UsedAssumedInformation = false;
3066 std::optional<Value *> SimplifiedVal =
3067 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3068 UsedAssumedInformation, AA::Interprocedural);
3069 if (UsedAssumedInformation)
3070 continue;
3071 if (SimplifiedVal && !*SimplifiedVal)
3072 return true;
3073 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3074 KnownUBInsts.insert(&I);
3075 continue;
3076 }
3077 if (!ArgVal->getType()->isPointerTy() ||
3078 !isa<ConstantPointerNull>(**SimplifiedVal))
3079 continue;
3080 bool IsKnownNonNull;
3082 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3083 if (IsKnownNonNull)
3084 KnownUBInsts.insert(&I);
3085 }
3086 return true;
3087 };
3088
3089 auto InspectReturnInstForUB = [&](Instruction &I) {
3090 auto &RI = cast<ReturnInst>(I);
3091 // Either we stopped and the appropriate action was taken,
3092 // or we got back a simplified return value to continue.
3093 std::optional<Value *> SimplifiedRetValue =
3094 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3095 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3096 return true;
3097
3098 // Check if a return instruction always cause UB or not
3099 // Note: It is guaranteed that the returned position of the anchor
3100 // scope has noundef attribute when this is called.
3101 // We also ensure the return position is not "assumed dead"
3102 // because the returned value was then potentially simplified to
3103 // `undef` in AAReturnedValues without removing the `noundef`
3104 // attribute yet.
3105
3106 // When the returned position has noundef attriubte, UB occurs in the
3107 // following cases.
3108 // (1) Returned value is known to be undef.
3109 // (2) The value is known to be a null pointer and the returned
3110 // position has nonnull attribute (because the returned value is
3111 // poison).
3112 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3113 bool IsKnownNonNull;
3115 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3116 IsKnownNonNull);
3117 if (IsKnownNonNull)
3118 KnownUBInsts.insert(&I);
3119 }
3120
3121 return true;
3122 };
3123
3124 bool UsedAssumedInformation = false;
3125 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3126 {Instruction::Load, Instruction::Store,
3127 Instruction::AtomicCmpXchg,
3128 Instruction::AtomicRMW},
3129 UsedAssumedInformation,
3130 /* CheckBBLivenessOnly */ true);
3131 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3132 UsedAssumedInformation,
3133 /* CheckBBLivenessOnly */ true);
3134 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3135 UsedAssumedInformation);
3136
3137 // If the returned position of the anchor scope has noundef attriubte, check
3138 // all returned instructions.
3139 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3140 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3141 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3142 bool IsKnownNoUndef;
3144 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3145 if (IsKnownNoUndef)
3146 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3147 {Instruction::Ret}, UsedAssumedInformation,
3148 /* CheckBBLivenessOnly */ true);
3149 }
3150 }
3151
3152 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3153 UBPrevSize != KnownUBInsts.size())
3154 return ChangeStatus::CHANGED;
3155 return ChangeStatus::UNCHANGED;
3156 }
3157
3158 bool isKnownToCauseUB(Instruction *I) const override {
3159 return KnownUBInsts.count(I);
3160 }
3161
3162 bool isAssumedToCauseUB(Instruction *I) const override {
3163 // In simple words, if an instruction is not in the assumed to _not_
3164 // cause UB, then it is assumed UB (that includes those
3165 // in the KnownUBInsts set). The rest is boilerplate
3166 // is to ensure that it is one of the instructions we test
3167 // for UB.
3168
3169 switch (I->getOpcode()) {
3170 case Instruction::Load:
3171 case Instruction::Store:
3172 case Instruction::AtomicCmpXchg:
3173 case Instruction::AtomicRMW:
3174 return !AssumedNoUBInsts.count(I);
3175 case Instruction::Br: {
3176 auto *BrInst = cast<BranchInst>(I);
3177 if (BrInst->isUnconditional())
3178 return false;
3179 return !AssumedNoUBInsts.count(I);
3180 } break;
3181 default:
3182 return false;
3183 }
3184 return false;
3185 }
3186
3187 ChangeStatus manifest(Attributor &A) override {
3188 if (KnownUBInsts.empty())
3189 return ChangeStatus::UNCHANGED;
3190 for (Instruction *I : KnownUBInsts)
3191 A.changeToUnreachableAfterManifest(I);
3192 return ChangeStatus::CHANGED;
3193 }
3194
3195 /// See AbstractAttribute::getAsStr()
3196 const std::string getAsStr(Attributor *A) const override {
3197 return getAssumed() ? "undefined-behavior" : "no-ub";
3198 }
3199
3200 /// Note: The correctness of this analysis depends on the fact that the
3201 /// following 2 sets will stop changing after some point.
3202 /// "Change" here means that their size changes.
3203 /// The size of each set is monotonically increasing
3204 /// (we only add items to them) and it is upper bounded by the number of
3205 /// instructions in the processed function (we can never save more
3206 /// elements in either set than this number). Hence, at some point,
3207 /// they will stop increasing.
3208 /// Consequently, at some point, both sets will have stopped
3209 /// changing, effectively making the analysis reach a fixpoint.
3210
3211 /// Note: These 2 sets are disjoint and an instruction can be considered
3212 /// one of 3 things:
3213 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3214 /// the KnownUBInsts set.
3215 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3216 /// has a reason to assume it).
3217 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3218 /// could not find a reason to assume or prove that it can cause UB,
3219 /// hence it assumes it doesn't. We have a set for these instructions
3220 /// so that we don't reprocess them in every update.
3221 /// Note however that instructions in this set may cause UB.
3222
3223protected:
3224 /// A set of all live instructions _known_ to cause UB.
3225 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3226
3227private:
3228 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3229 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3230
3231 // Should be called on updates in which if we're processing an instruction
3232 // \p I that depends on a value \p V, one of the following has to happen:
3233 // - If the value is assumed, then stop.
3234 // - If the value is known but undef, then consider it UB.
3235 // - Otherwise, do specific processing with the simplified value.
3236 // We return std::nullopt in the first 2 cases to signify that an appropriate
3237 // action was taken and the caller should stop.
3238 // Otherwise, we return the simplified value that the caller should
3239 // use for specific processing.
3240 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3241 Instruction *I) {
3242 bool UsedAssumedInformation = false;
3243 std::optional<Value *> SimplifiedV =
3244 A.getAssumedSimplified(IRPosition::value(*V), *this,
3245 UsedAssumedInformation, AA::Interprocedural);
3246 if (!UsedAssumedInformation) {
3247 // Don't depend on assumed values.
3248 if (!SimplifiedV) {
3249 // If it is known (which we tested above) but it doesn't have a value,
3250 // then we can assume `undef` and hence the instruction is UB.
3251 KnownUBInsts.insert(I);
3252 return std::nullopt;
3253 }
3254 if (!*SimplifiedV)
3255 return nullptr;
3256 V = *SimplifiedV;
3257 }
3258 if (isa<UndefValue>(V)) {
3259 KnownUBInsts.insert(I);
3260 return std::nullopt;
3261 }
3262 return V;
3263 }
3264};
3265
3266struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3267 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3268 : AAUndefinedBehaviorImpl(IRP, A) {}
3269
3270 /// See AbstractAttribute::trackStatistics()
3271 void trackStatistics() const override {
3272 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3273 "Number of instructions known to have UB");
3274 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3275 KnownUBInsts.size();
3276 }
3277};
3278} // namespace
3279
3280/// ------------------------ Will-Return Attributes ----------------------------
3281
3282namespace {
3283// Helper function that checks whether a function has any cycle which we don't
3284// know if it is bounded or not.
3285// Loops with maximum trip count are considered bounded, any other cycle not.
3286static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3287 ScalarEvolution *SE =
3288 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3289 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3290 // If either SCEV or LoopInfo is not available for the function then we assume
3291 // any cycle to be unbounded cycle.
3292 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3293 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3294 if (!SE || !LI) {
3295 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3296 if (SCCI.hasCycle())
3297 return true;
3298 return false;
3299 }
3300
3301 // If there's irreducible control, the function may contain non-loop cycles.
3303 return true;
3304
3305 // Any loop that does not have a max trip count is considered unbounded cycle.
3306 for (auto *L : LI->getLoopsInPreorder()) {
3307 if (!SE->getSmallConstantMaxTripCount(L))
3308 return true;
3309 }
3310 return false;
3311}
3312
3313struct AAWillReturnImpl : public AAWillReturn {
3314 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3315 : AAWillReturn(IRP, A) {}
3316
3317 /// See AbstractAttribute::initialize(...).
3318 void initialize(Attributor &A) override {
3319 bool IsKnown;
3321 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3322 (void)IsKnown;
3323 }
3324
3325 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3326 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3327 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3328 return false;
3329
3330 bool IsKnown;
3331 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3332 return IsKnown || !KnownOnly;
3333 return false;
3334 }
3335
3336 /// See AbstractAttribute::updateImpl(...).
3337 ChangeStatus updateImpl(Attributor &A) override {
3338 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3339 return ChangeStatus::UNCHANGED;
3340
3341 auto CheckForWillReturn = [&](Instruction &I) {
3343 bool IsKnown;
3345 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3346 if (IsKnown)
3347 return true;
3348 } else {
3349 return false;
3350 }
3351 bool IsKnownNoRecurse;
3353 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3354 };
3355
3356 bool UsedAssumedInformation = false;
3357 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3358 UsedAssumedInformation))
3359 return indicatePessimisticFixpoint();
3360
3361 return ChangeStatus::UNCHANGED;
3362 }
3363
3364 /// See AbstractAttribute::getAsStr()
3365 const std::string getAsStr(Attributor *A) const override {
3366 return getAssumed() ? "willreturn" : "may-noreturn";
3367 }
3368};
3369
3370struct AAWillReturnFunction final : AAWillReturnImpl {
3371 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3372 : AAWillReturnImpl(IRP, A) {}
3373
3374 /// See AbstractAttribute::initialize(...).
3375 void initialize(Attributor &A) override {
3376 AAWillReturnImpl::initialize(A);
3377
3378 Function *F = getAnchorScope();
3379 assert(F && "Did expect an anchor function");
3380 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3381 indicatePessimisticFixpoint();
3382 }
3383
3384 /// See AbstractAttribute::trackStatistics()
3385 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3386};
3387
3388/// WillReturn attribute deduction for a call sites.
3389struct AAWillReturnCallSite final
3390 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3391 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3392 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3393
3394 /// See AbstractAttribute::updateImpl(...).
3395 ChangeStatus updateImpl(Attributor &A) override {
3396 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3397 return ChangeStatus::UNCHANGED;
3398
3399 return AACalleeToCallSite::updateImpl(A);
3400 }
3401
3402 /// See AbstractAttribute::trackStatistics()
3403 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3404};
3405} // namespace
3406
3407/// -------------------AAIntraFnReachability Attribute--------------------------
3408
3409/// All information associated with a reachability query. This boilerplate code
3410/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3411/// different \p ToTy values.
3412template <typename ToTy> struct ReachabilityQueryInfo {
3413 enum class Reachable {
3416 };
3417
3418 /// Start here,
3419 const Instruction *From = nullptr;
3420 /// reach this place,
3421 const ToTy *To = nullptr;
3422 /// without going through any of these instructions,
3424 /// and remember if it worked:
3426
3427 /// Precomputed hash for this RQI.
3428 unsigned Hash = 0;
3429
3430 unsigned computeHashValue() const {
3431 assert(Hash == 0 && "Computed hash twice!");
3434 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3435 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3436 InstSetDMI::getHashValue(ExclusionSet));
3437 }
3438
3440 : From(From), To(To) {}
3441
3442 /// Constructor replacement to ensure unique and stable sets are used for the
3443 /// cache.
3445 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3446 : From(&From), To(&To), ExclusionSet(ES) {
3447
3448 if (!ES || ES->empty()) {
3449 ExclusionSet = nullptr;
3450 } else if (MakeUnique) {
3451 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3452 }
3453 }
3454
3457};
3458
3459namespace llvm {
3460template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3463
3466
3469 return &TombstoneKey;
3470 }
3471 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3472 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3473 }
3474 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3475 const ReachabilityQueryInfo<ToTy> *RHS) {
3476 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3477 return false;
3478 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3479 }
3480};
3481
3482#define DefineKeys(ToTy) \
3483 template <> \
3484 ReachabilityQueryInfo<ToTy> \
3485 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3486 ReachabilityQueryInfo<ToTy>( \
3487 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3488 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3489 template <> \
3490 ReachabilityQueryInfo<ToTy> \
3491 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3492 ReachabilityQueryInfo<ToTy>( \
3493 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3494 DenseMapInfo<const ToTy *>::getTombstoneKey());
3495
3497#undef DefineKeys
3498
3499} // namespace llvm
3500
3501namespace {
3502
3503template <typename BaseTy, typename ToTy>
3504struct CachedReachabilityAA : public BaseTy {
3505 using RQITy = ReachabilityQueryInfo<ToTy>;
3506
3507 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3508
3509 /// See AbstractAttribute::isQueryAA.
3510 bool isQueryAA() const override { return true; }
3511
3512 /// See AbstractAttribute::updateImpl(...).
3513 ChangeStatus updateImpl(Attributor &A) override {
3514 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3515 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3516 RQITy *RQI = QueryVector[u];
3517 if (RQI->Result == RQITy::Reachable::No &&
3518 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3519 Changed = ChangeStatus::CHANGED;
3520 }
3521 return Changed;
3522 }
3523
3524 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3525 bool IsTemporaryRQI) = 0;
3526
3527 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3528 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3529 RQI.Result = Result;
3530
3531 // Remove the temporary RQI from the cache.
3532 if (IsTemporaryRQI)
3533 QueryCache.erase(&RQI);
3534
3535 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3536 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3537 // this query. 2) We did not use the exclusion set, potentially because
3538 // there is none.
3539 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3540 RQITy PlainRQI(RQI.From, RQI.To);
3541 if (!QueryCache.count(&PlainRQI)) {
3542 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3543 RQIPtr->Result = Result;
3544 QueryVector.push_back(RQIPtr);
3545 QueryCache.insert(RQIPtr);
3546 }
3547 }
3548
3549 // Check if we need to insert a new permanent RQI with the exclusion set.
3550 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3551 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3552 "Did not expect empty set!");
3553 RQITy *RQIPtr = new (A.Allocator)
3554 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3555 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3556 RQIPtr->Result = Result;
3557 assert(!QueryCache.count(RQIPtr));
3558 QueryVector.push_back(RQIPtr);
3559 QueryCache.insert(RQIPtr);
3560 }
3561
3562 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3563 A.registerForUpdate(*this);
3564 return Result == RQITy::Reachable::Yes;
3565 }
3566
3567 const std::string getAsStr(Attributor *A) const override {
3568 // TODO: Return the number of reachable queries.
3569 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3570 }
3571
3572 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3573 typename RQITy::Reachable &Result) {
3574 if (!this->getState().isValidState()) {
3575 Result = RQITy::Reachable::Yes;
3576 return true;
3577 }
3578
3579 // If we have an exclusion set we might be able to find our answer by
3580 // ignoring it first.
3581 if (StackRQI.ExclusionSet) {
3582 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3583 auto It = QueryCache.find(&PlainRQI);
3584 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3585 Result = RQITy::Reachable::No;
3586 return true;
3587 }
3588 }
3589
3590 auto It = QueryCache.find(&StackRQI);
3591 if (It != QueryCache.end()) {
3592 Result = (*It)->Result;
3593 return true;
3594 }
3595
3596 // Insert a temporary for recursive queries. We will replace it with a
3597 // permanent entry later.
3598 QueryCache.insert(&StackRQI);
3599 return false;
3600 }
3601
3602private:
3603 SmallVector<RQITy *> QueryVector;
3604 DenseSet<RQITy *> QueryCache;
3605};
3606
3607struct AAIntraFnReachabilityFunction final
3608 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3609 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3610 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3611 : Base(IRP, A) {
3612 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3613 *IRP.getAssociatedFunction());
3614 }
3615
3616 bool isAssumedReachable(
3617 Attributor &A, const Instruction &From, const Instruction &To,
3618 const AA::InstExclusionSetTy *ExclusionSet) const override {
3619 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3620 if (&From == &To)
3621 return true;
3622
3623 RQITy StackRQI(A, From, To, ExclusionSet, false);
3624 typename RQITy::Reachable Result;
3625 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3626 return NonConstThis->isReachableImpl(A, StackRQI,
3627 /*IsTemporaryRQI=*/true);
3628 return Result == RQITy::Reachable::Yes;
3629 }
3630
3631 ChangeStatus updateImpl(Attributor &A) override {
3632 // We only depend on liveness. DeadEdges is all we care about, check if any
3633 // of them changed.
3634 auto *LivenessAA =
3635 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3636 if (LivenessAA &&
3637 llvm::all_of(DeadEdges,
3638 [&](const auto &DeadEdge) {
3639 return LivenessAA->isEdgeDead(DeadEdge.first,
3640 DeadEdge.second);
3641 }) &&
3642 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3643 return LivenessAA->isAssumedDead(BB);
3644 })) {
3645 return ChangeStatus::UNCHANGED;
3646 }
3647 DeadEdges.clear();
3648 DeadBlocks.clear();
3649 return Base::updateImpl(A);
3650 }
3651
3652 bool isReachableImpl(Attributor &A, RQITy &RQI,
3653 bool IsTemporaryRQI) override {
3654 const Instruction *Origin = RQI.From;
3655 bool UsedExclusionSet = false;
3656
3657 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3658 const AA::InstExclusionSetTy *ExclusionSet) {
3659 const Instruction *IP = &From;
3660 while (IP && IP != &To) {
3661 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3662 UsedExclusionSet = true;
3663 break;
3664 }
3665 IP = IP->getNextNode();
3666 }
3667 return IP == &To;
3668 };
3669
3670 const BasicBlock *FromBB = RQI.From->getParent();
3671 const BasicBlock *ToBB = RQI.To->getParent();
3672 assert(FromBB->getParent() == ToBB->getParent() &&
3673 "Not an intra-procedural query!");
3674
3675 // Check intra-block reachability, however, other reaching paths are still
3676 // possible.
3677 if (FromBB == ToBB &&
3678 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3679 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3680 IsTemporaryRQI);
3681
3682 // Check if reaching the ToBB block is sufficient or if even that would not
3683 // ensure reaching the target. In the latter case we are done.
3684 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3685 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3686 IsTemporaryRQI);
3687
3688 const Function *Fn = FromBB->getParent();
3689 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3690 if (RQI.ExclusionSet)
3691 for (auto *I : *RQI.ExclusionSet)
3692 if (I->getFunction() == Fn)
3693 ExclusionBlocks.insert(I->getParent());
3694
3695 // Check if we make it out of the FromBB block at all.
3696 if (ExclusionBlocks.count(FromBB) &&
3697 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3698 RQI.ExclusionSet))
3699 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3700
3701 auto *LivenessAA =
3702 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3703 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3704 DeadBlocks.insert(ToBB);
3705 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3706 IsTemporaryRQI);
3707 }
3708
3709 SmallPtrSet<const BasicBlock *, 16> Visited;
3711 Worklist.push_back(FromBB);
3712
3713 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3714 while (!Worklist.empty()) {
3715 const BasicBlock *BB = Worklist.pop_back_val();
3716 if (!Visited.insert(BB).second)
3717 continue;
3718 for (const BasicBlock *SuccBB : successors(BB)) {
3719 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3720 LocalDeadEdges.insert({BB, SuccBB});
3721 continue;
3722 }
3723 // We checked before if we just need to reach the ToBB block.
3724 if (SuccBB == ToBB)
3725 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3726 IsTemporaryRQI);
3727 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3728 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3729 IsTemporaryRQI);
3730
3731 if (ExclusionBlocks.count(SuccBB)) {
3732 UsedExclusionSet = true;
3733 continue;
3734 }
3735 Worklist.push_back(SuccBB);
3736 }
3737 }
3738
3739 DeadEdges.insert_range(LocalDeadEdges);
3740 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3741 IsTemporaryRQI);
3742 }
3743
3744 /// See AbstractAttribute::trackStatistics()
3745 void trackStatistics() const override {}
3746
3747private:
3748 // Set of assumed dead blocks we used in the last query. If any changes we
3749 // update the state.
3750 DenseSet<const BasicBlock *> DeadBlocks;
3751
3752 // Set of assumed dead edges we used in the last query. If any changes we
3753 // update the state.
3754 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3755
3756 /// The dominator tree of the function to short-circuit reasoning.
3757 const DominatorTree *DT = nullptr;
3758};
3759} // namespace
3760
3761/// ------------------------ NoAlias Argument Attribute ------------------------
3762
3764 Attribute::AttrKind ImpliedAttributeKind,
3765 bool IgnoreSubsumingPositions) {
3766 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3767 "Unexpected attribute kind");
3768 Value *Val = &IRP.getAssociatedValue();
3770 if (isa<AllocaInst>(Val))
3771 return true;
3772 } else {
3773 IgnoreSubsumingPositions = true;
3774 }
3775
3776 if (isa<UndefValue>(Val))
3777 return true;
3778
3779 if (isa<ConstantPointerNull>(Val) &&
3782 return true;
3783
3784 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3785 IgnoreSubsumingPositions, Attribute::NoAlias))
3786 return true;
3787
3788 return false;
3789}
3790
3791namespace {
3792struct AANoAliasImpl : AANoAlias {
3793 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3794 assert(getAssociatedType()->isPointerTy() &&
3795 "Noalias is a pointer attribute");
3796 }
3797
3798 const std::string getAsStr(Attributor *A) const override {
3799 return getAssumed() ? "noalias" : "may-alias";
3800 }
3801};
3802
3803/// NoAlias attribute for a floating value.
3804struct AANoAliasFloating final : AANoAliasImpl {
3805 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3806 : AANoAliasImpl(IRP, A) {}
3807
3808 /// See AbstractAttribute::updateImpl(...).
3809 ChangeStatus updateImpl(Attributor &A) override {
3810 // TODO: Implement this.
3811 return indicatePessimisticFixpoint();
3812 }
3813
3814 /// See AbstractAttribute::trackStatistics()
3815 void trackStatistics() const override {
3817 }
3818};
3819
3820/// NoAlias attribute for an argument.
3821struct AANoAliasArgument final
3822 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3823 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3824 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3825
3826 /// See AbstractAttribute::update(...).
3827 ChangeStatus updateImpl(Attributor &A) override {
3828 // We have to make sure no-alias on the argument does not break
3829 // synchronization when this is a callback argument, see also [1] below.
3830 // If synchronization cannot be affected, we delegate to the base updateImpl
3831 // function, otherwise we give up for now.
3832
3833 // If the function is no-sync, no-alias cannot break synchronization.
3834 bool IsKnownNoSycn;
3836 A, this, IRPosition::function_scope(getIRPosition()),
3837 DepClassTy::OPTIONAL, IsKnownNoSycn))
3838 return Base::updateImpl(A);
3839
3840 // If the argument is read-only, no-alias cannot break synchronization.
3841 bool IsKnown;
3842 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3843 return Base::updateImpl(A);
3844
3845 // If the argument is never passed through callbacks, no-alias cannot break
3846 // synchronization.
3847 bool UsedAssumedInformation = false;
3848 if (A.checkForAllCallSites(
3849 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3850 true, UsedAssumedInformation))
3851 return Base::updateImpl(A);
3852
3853 // TODO: add no-alias but make sure it doesn't break synchronization by
3854 // introducing fake uses. See:
3855 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3856 // International Workshop on OpenMP 2018,
3857 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3858
3859 return indicatePessimisticFixpoint();
3860 }
3861
3862 /// See AbstractAttribute::trackStatistics()
3863 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3864};
3865
3866struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3867 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3868 : AANoAliasImpl(IRP, A) {}
3869
3870 /// Determine if the underlying value may alias with the call site argument
3871 /// \p OtherArgNo of \p ICS (= the underlying call site).
3872 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3873 const AAMemoryBehavior &MemBehaviorAA,
3874 const CallBase &CB, unsigned OtherArgNo) {
3875 // We do not need to worry about aliasing with the underlying IRP.
3876 if (this->getCalleeArgNo() == (int)OtherArgNo)
3877 return false;
3878
3879 // If it is not a pointer or pointer vector we do not alias.
3880 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3881 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3882 return false;
3883
3884 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3885 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3886
3887 // If the argument is readnone, there is no read-write aliasing.
3888 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3889 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3890 return false;
3891 }
3892
3893 // If the argument is readonly and the underlying value is readonly, there
3894 // is no read-write aliasing.
3895 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3896 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3897 IsReadOnly) {
3898 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3899 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3900 return false;
3901 }
3902
3903 // We have to utilize actual alias analysis queries so we need the object.
3904 if (!AAR)
3905 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3906 *getAnchorScope());
3907
3908 // Try to rule it out at the call site.
3909 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3910 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3911 "callsite arguments: "
3912 << getAssociatedValue() << " " << *ArgOp << " => "
3913 << (IsAliasing ? "" : "no-") << "alias \n");
3914
3915 return IsAliasing;
3916 }
3917
3918 bool isKnownNoAliasDueToNoAliasPreservation(
3919 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3920 // We can deduce "noalias" if the following conditions hold.
3921 // (i) Associated value is assumed to be noalias in the definition.
3922 // (ii) Associated value is assumed to be no-capture in all the uses
3923 // possibly executed before this callsite.
3924 // (iii) There is no other pointer argument which could alias with the
3925 // value.
3926
3927 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3928 const Function *ScopeFn = VIRP.getAnchorScope();
3929 // Check whether the value is captured in the scope using AANoCapture.
3930 // Look at CFG and check only uses possibly executed before this
3931 // callsite.
3932 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3933 Instruction *UserI = cast<Instruction>(U.getUser());
3934
3935 // If UserI is the curr instruction and there is a single potential use of
3936 // the value in UserI we allow the use.
3937 // TODO: We should inspect the operands and allow those that cannot alias
3938 // with the value.
3939 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3940 return true;
3941
3942 if (ScopeFn) {
3943 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3944 if (CB->isArgOperand(&U)) {
3945
3946 unsigned ArgNo = CB->getArgOperandNo(&U);
3947
3948 bool IsKnownNoCapture;
3950 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3951 DepClassTy::OPTIONAL, IsKnownNoCapture))
3952 return true;
3953 }
3954 }
3955
3957 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3958 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3959 return true;
3960 }
3961
3962 // TODO: We should track the capturing uses in AANoCapture but the problem
3963 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3964 // a value in the module slice.
3965 // TODO(captures): Make this more precise.
3966 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3967 if (capturesNothing(CI))
3968 return true;
3969 if (CI.isPassthrough()) {
3970 Follow = true;
3971 return true;
3972 }
3973 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3974 return false;
3975 };
3976
3977 bool IsKnownNoCapture;
3978 const AANoCapture *NoCaptureAA = nullptr;
3979 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3980 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3981 if (!IsAssumedNoCapture &&
3982 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3983 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3984 LLVM_DEBUG(
3985 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3986 << " cannot be noalias as it is potentially captured\n");
3987 return false;
3988 }
3989 }
3990 if (NoCaptureAA)
3991 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3992
3993 // Check there is no other pointer argument which could alias with the
3994 // value passed at this call site.
3995 // TODO: AbstractCallSite
3996 const auto &CB = cast<CallBase>(getAnchorValue());
3997 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3998 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3999 return false;
4000
4001 return true;
4002 }
4003
4004 /// See AbstractAttribute::updateImpl(...).
4005 ChangeStatus updateImpl(Attributor &A) override {
4006 // If the argument is readnone we are done as there are no accesses via the
4007 // argument.
4008 auto *MemBehaviorAA =
4009 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4010 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4011 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4012 return ChangeStatus::UNCHANGED;
4013 }
4014
4015 bool IsKnownNoAlias;
4016 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4018 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4019 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4020 << " is not no-alias at the definition\n");
4021 return indicatePessimisticFixpoint();
4022 }
4023
4024 AAResults *AAR = nullptr;
4025 if (MemBehaviorAA &&
4026 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4027 LLVM_DEBUG(
4028 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4029 return ChangeStatus::UNCHANGED;
4030 }
4031
4032 return indicatePessimisticFixpoint();
4033 }
4034
4035 /// See AbstractAttribute::trackStatistics()
4036 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4037};
4038
4039/// NoAlias attribute for function return value.
4040struct AANoAliasReturned final : AANoAliasImpl {
4041 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4042 : AANoAliasImpl(IRP, A) {}
4043
4044 /// See AbstractAttribute::updateImpl(...).
4045 ChangeStatus updateImpl(Attributor &A) override {
4046
4047 auto CheckReturnValue = [&](Value &RV) -> bool {
4048 if (Constant *C = dyn_cast<Constant>(&RV))
4049 if (C->isNullValue() || isa<UndefValue>(C))
4050 return true;
4051
4052 /// For now, we can only deduce noalias if we have call sites.
4053 /// FIXME: add more support.
4054 if (!isa<CallBase>(&RV))
4055 return false;
4056
4057 const IRPosition &RVPos = IRPosition::value(RV);
4058 bool IsKnownNoAlias;
4060 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4061 return false;
4062
4063 bool IsKnownNoCapture;
4064 const AANoCapture *NoCaptureAA = nullptr;
4065 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4066 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4067 &NoCaptureAA);
4068 return IsAssumedNoCapture ||
4069 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4070 };
4071
4072 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4073 return indicatePessimisticFixpoint();
4074
4075 return ChangeStatus::UNCHANGED;
4076 }
4077
4078 /// See AbstractAttribute::trackStatistics()
4079 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4080};
4081
4082/// NoAlias attribute deduction for a call site return value.
4083struct AANoAliasCallSiteReturned final
4084 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4085 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4086 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4087
4088 /// See AbstractAttribute::trackStatistics()
4089 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4090};
4091} // namespace
4092
4093/// -------------------AAIsDead Function Attribute-----------------------
4094
4095namespace {
4096struct AAIsDeadValueImpl : public AAIsDead {
4097 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4098
4099 /// See AAIsDead::isAssumedDead().
4100 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4101
4102 /// See AAIsDead::isKnownDead().
4103 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4104
4105 /// See AAIsDead::isAssumedDead(BasicBlock *).
4106 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4107
4108 /// See AAIsDead::isKnownDead(BasicBlock *).
4109 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4110
4111 /// See AAIsDead::isAssumedDead(Instruction *I).
4112 bool isAssumedDead(const Instruction *I) const override {
4113 return I == getCtxI() && isAssumedDead();
4114 }
4115
4116 /// See AAIsDead::isKnownDead(Instruction *I).
4117 bool isKnownDead(const Instruction *I) const override {
4118 return isAssumedDead(I) && isKnownDead();
4119 }
4120
4121 /// See AbstractAttribute::getAsStr().
4122 const std::string getAsStr(Attributor *A) const override {
4123 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4124 }
4125
4126 /// Check if all uses are assumed dead.
4127 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4128 // Callers might not check the type, void has no uses.
4129 if (V.getType()->isVoidTy() || V.use_empty())
4130 return true;
4131
4132 // If we replace a value with a constant there are no uses left afterwards.
4133 if (!isa<Constant>(V)) {
4134 if (auto *I = dyn_cast<Instruction>(&V))
4135 if (!A.isRunOn(*I->getFunction()))
4136 return false;
4137 bool UsedAssumedInformation = false;
4138 std::optional<Constant *> C =
4139 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4140 if (!C || *C)
4141 return true;
4142 }
4143
4144 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4145 // Explicitly set the dependence class to required because we want a long
4146 // chain of N dependent instructions to be considered live as soon as one is
4147 // without going through N update cycles. This is not required for
4148 // correctness.
4149 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4150 DepClassTy::REQUIRED,
4151 /* IgnoreDroppableUses */ false);
4152 }
4153
4154 /// Determine if \p I is assumed to be side-effect free.
4155 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4157 return true;
4158
4159 auto *CB = dyn_cast<CallBase>(I);
4160 if (!CB || isa<IntrinsicInst>(CB))
4161 return false;
4162
4163 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4164
4165 bool IsKnownNoUnwind;
4167 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4168 return false;
4169
4170 bool IsKnown;
4171 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4172 }
4173};
4174
4175struct AAIsDeadFloating : public AAIsDeadValueImpl {
4176 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4177 : AAIsDeadValueImpl(IRP, A) {}
4178
4179 /// See AbstractAttribute::initialize(...).
4180 void initialize(Attributor &A) override {
4181 AAIsDeadValueImpl::initialize(A);
4182
4183 if (isa<UndefValue>(getAssociatedValue())) {
4184 indicatePessimisticFixpoint();
4185 return;
4186 }
4187
4188 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4189 if (!isAssumedSideEffectFree(A, I)) {
4191 indicatePessimisticFixpoint();
4192 else
4193 removeAssumedBits(HAS_NO_EFFECT);
4194 }
4195 }
4196
4197 bool isDeadFence(Attributor &A, FenceInst &FI) {
4198 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4199 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4200 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4201 return false;
4202 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4203 return true;
4204 }
4205
4206 bool isDeadStore(Attributor &A, StoreInst &SI,
4207 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4208 // Lang ref now states volatile store is not UB/dead, let's skip them.
4209 if (SI.isVolatile())
4210 return false;
4211
4212 // If we are collecting assumes to be deleted we are in the manifest stage.
4213 // It's problematic to collect the potential copies again now so we use the
4214 // cached ones.
4215 bool UsedAssumedInformation = false;
4216 if (!AssumeOnlyInst) {
4217 PotentialCopies.clear();
4218 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4219 UsedAssumedInformation)) {
4220 LLVM_DEBUG(
4221 dbgs()
4222 << "[AAIsDead] Could not determine potential copies of store!\n");
4223 return false;
4224 }
4225 }
4226 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4227 << " potential copies.\n");
4228
4229 InformationCache &InfoCache = A.getInfoCache();
4230 return llvm::all_of(PotentialCopies, [&](Value *V) {
4231 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4232 UsedAssumedInformation))
4233 return true;
4234 if (auto *LI = dyn_cast<LoadInst>(V)) {
4235 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4236 auto &UserI = cast<Instruction>(*U.getUser());
4237 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4238 if (AssumeOnlyInst)
4239 AssumeOnlyInst->insert(&UserI);
4240 return true;
4241 }
4242 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4243 })) {
4244 return true;
4245 }
4246 }
4247 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4248 << " is assumed live!\n");
4249 return false;
4250 });
4251 }
4252
4253 /// See AbstractAttribute::getAsStr().
4254 const std::string getAsStr(Attributor *A) const override {
4255 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4257 if (isValidState())
4258 return "assumed-dead-store";
4260 if (isValidState())
4261 return "assumed-dead-fence";
4262 return AAIsDeadValueImpl::getAsStr(A);
4263 }
4264
4265 /// See AbstractAttribute::updateImpl(...).
4266 ChangeStatus updateImpl(Attributor &A) override {
4267 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4268 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4269 if (!isDeadStore(A, *SI))
4270 return indicatePessimisticFixpoint();
4271 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4272 if (!isDeadFence(A, *FI))
4273 return indicatePessimisticFixpoint();
4274 } else {
4275 if (!isAssumedSideEffectFree(A, I))
4276 return indicatePessimisticFixpoint();
4277 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4278 return indicatePessimisticFixpoint();
4279 }
4281 }
4282
4283 bool isRemovableStore() const override {
4284 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4285 }
4286
4287 /// See AbstractAttribute::manifest(...).
4288 ChangeStatus manifest(Attributor &A) override {
4289 Value &V = getAssociatedValue();
4290 if (auto *I = dyn_cast<Instruction>(&V)) {
4291 // If we get here we basically know the users are all dead. We check if
4292 // isAssumedSideEffectFree returns true here again because it might not be
4293 // the case and only the users are dead but the instruction (=call) is
4294 // still needed.
4295 if (auto *SI = dyn_cast<StoreInst>(I)) {
4296 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4297 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4298 (void)IsDead;
4299 assert(IsDead && "Store was assumed to be dead!");
4300 A.deleteAfterManifest(*I);
4301 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4302 Instruction *AOI = AssumeOnlyInst[i];
4303 for (auto *Usr : AOI->users())
4304 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4305 A.deleteAfterManifest(*AOI);
4306 }
4307 return ChangeStatus::CHANGED;
4308 }
4309 if (auto *FI = dyn_cast<FenceInst>(I)) {
4310 assert(isDeadFence(A, *FI));
4311 A.deleteAfterManifest(*FI);
4312 return ChangeStatus::CHANGED;
4313 }
4314 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4315 A.deleteAfterManifest(*I);
4316 return ChangeStatus::CHANGED;
4317 }
4318 }
4320 }
4321
4322 /// See AbstractAttribute::trackStatistics()
4323 void trackStatistics() const override {
4325 }
4326
4327private:
4328 // The potential copies of a dead store, used for deletion during manifest.
4329 SmallSetVector<Value *, 4> PotentialCopies;
4330};
4331
4332struct AAIsDeadArgument : public AAIsDeadFloating {
4333 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4334 : AAIsDeadFloating(IRP, A) {}
4335
4336 /// See AbstractAttribute::manifest(...).
4337 ChangeStatus manifest(Attributor &A) override {
4338 Argument &Arg = *getAssociatedArgument();
4339 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4340 if (A.registerFunctionSignatureRewrite(
4341 Arg, /* ReplacementTypes */ {},
4344 return ChangeStatus::CHANGED;
4345 }
4346 return ChangeStatus::UNCHANGED;
4347 }
4348
4349 /// See AbstractAttribute::trackStatistics()
4350 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4351};
4352
4353struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4354 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4355 : AAIsDeadValueImpl(IRP, A) {}
4356
4357 /// See AbstractAttribute::initialize(...).
4358 void initialize(Attributor &A) override {
4359 AAIsDeadValueImpl::initialize(A);
4360 if (isa<UndefValue>(getAssociatedValue()))
4361 indicatePessimisticFixpoint();
4362 }
4363
4364 /// See AbstractAttribute::updateImpl(...).
4365 ChangeStatus updateImpl(Attributor &A) override {
4366 // TODO: Once we have call site specific value information we can provide
4367 // call site specific liveness information and then it makes
4368 // sense to specialize attributes for call sites arguments instead of
4369 // redirecting requests to the callee argument.
4370 Argument *Arg = getAssociatedArgument();
4371 if (!Arg)
4372 return indicatePessimisticFixpoint();
4373 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4374 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4375 if (!ArgAA)
4376 return indicatePessimisticFixpoint();
4377 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4378 }
4379
4380 /// See AbstractAttribute::manifest(...).
4381 ChangeStatus manifest(Attributor &A) override {
4382 CallBase &CB = cast<CallBase>(getAnchorValue());
4383 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4384 assert(!isa<UndefValue>(U.get()) &&
4385 "Expected undef values to be filtered out!");
4386 UndefValue &UV = *UndefValue::get(U->getType());
4387 if (A.changeUseAfterManifest(U, UV))
4388 return ChangeStatus::CHANGED;
4389 return ChangeStatus::UNCHANGED;
4390 }
4391
4392 /// See AbstractAttribute::trackStatistics()
4393 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4394};
4395
4396struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4397 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4398 : AAIsDeadFloating(IRP, A) {}
4399
4400 /// See AAIsDead::isAssumedDead().
4401 bool isAssumedDead() const override {
4402 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4403 }
4404
4405 /// See AbstractAttribute::initialize(...).
4406 void initialize(Attributor &A) override {
4407 AAIsDeadFloating::initialize(A);
4408 if (isa<UndefValue>(getAssociatedValue())) {
4409 indicatePessimisticFixpoint();
4410 return;
4411 }
4412
4413 // We track this separately as a secondary state.
4414 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4415 }
4416
4417 /// See AbstractAttribute::updateImpl(...).
4418 ChangeStatus updateImpl(Attributor &A) override {
4419 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4420 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4421 IsAssumedSideEffectFree = false;
4422 Changed = ChangeStatus::CHANGED;
4423 }
4424 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4425 return indicatePessimisticFixpoint();
4426 return Changed;
4427 }
4428
4429 /// See AbstractAttribute::trackStatistics()
4430 void trackStatistics() const override {
4431 if (IsAssumedSideEffectFree)
4433 else
4434 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4435 }
4436
4437 /// See AbstractAttribute::getAsStr().
4438 const std::string getAsStr(Attributor *A) const override {
4439 return isAssumedDead()
4440 ? "assumed-dead"
4441 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4442 }
4443
4444private:
4445 bool IsAssumedSideEffectFree = true;
4446};
4447
4448struct AAIsDeadReturned : public AAIsDeadValueImpl {
4449 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4450 : AAIsDeadValueImpl(IRP, A) {}
4451
4452 /// See AbstractAttribute::updateImpl(...).
4453 ChangeStatus updateImpl(Attributor &A) override {
4454
4455 bool UsedAssumedInformation = false;
4456 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4457 {Instruction::Ret}, UsedAssumedInformation);
4458
4459 auto PredForCallSite = [&](AbstractCallSite ACS) {
4460 if (ACS.isCallbackCall() || !ACS.getInstruction())
4461 return false;
4462 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4463 };
4464
4465 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4466 UsedAssumedInformation))
4467 return indicatePessimisticFixpoint();
4468
4469 return ChangeStatus::UNCHANGED;
4470 }
4471
4472 /// See AbstractAttribute::manifest(...).
4473 ChangeStatus manifest(Attributor &A) override {
4474 // TODO: Rewrite the signature to return void?
4475 bool AnyChange = false;
4476 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4477 auto RetInstPred = [&](Instruction &I) {
4478 ReturnInst &RI = cast<ReturnInst>(I);
4480 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4481 return true;
4482 };
4483 bool UsedAssumedInformation = false;
4484 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4485 UsedAssumedInformation);
4486 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4487 }
4488
4489 /// See AbstractAttribute::trackStatistics()
4490 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4491};
4492
4493struct AAIsDeadFunction : public AAIsDead {
4494 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4495
4496 /// See AbstractAttribute::initialize(...).
4497 void initialize(Attributor &A) override {
4498 Function *F = getAnchorScope();
4499 assert(F && "Did expect an anchor function");
4500 if (!isAssumedDeadInternalFunction(A)) {
4501 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4502 assumeLive(A, F->getEntryBlock());
4503 }
4504 }
4505
4506 bool isAssumedDeadInternalFunction(Attributor &A) {
4507 if (!getAnchorScope()->hasLocalLinkage())
4508 return false;
4509 bool UsedAssumedInformation = false;
4510 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4511 true, UsedAssumedInformation);
4512 }
4513
4514 /// See AbstractAttribute::getAsStr().
4515 const std::string getAsStr(Attributor *A) const override {
4516 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4517 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4518 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4519 std::to_string(KnownDeadEnds.size()) + "]";
4520 }
4521
4522 /// See AbstractAttribute::manifest(...).
4523 ChangeStatus manifest(Attributor &A) override {
4524 assert(getState().isValidState() &&
4525 "Attempted to manifest an invalid state!");
4526
4527 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4528 Function &F = *getAnchorScope();
4529
4530 if (AssumedLiveBlocks.empty()) {
4531 A.deleteAfterManifest(F);
4532 return ChangeStatus::CHANGED;
4533 }
4534
4535 // Flag to determine if we can change an invoke to a call assuming the
4536 // callee is nounwind. This is not possible if the personality of the
4537 // function allows to catch asynchronous exceptions.
4538 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4539
4540 KnownDeadEnds.set_union(ToBeExploredFrom);
4541 for (const Instruction *DeadEndI : KnownDeadEnds) {
4542 auto *CB = dyn_cast<CallBase>(DeadEndI);
4543 if (!CB)
4544 continue;
4545 bool IsKnownNoReturn;
4547 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4548 IsKnownNoReturn);
4549 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4550 continue;
4551
4552 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4553 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4554 else
4555 A.changeToUnreachableAfterManifest(
4556 const_cast<Instruction *>(DeadEndI->getNextNode()));
4557 HasChanged = ChangeStatus::CHANGED;
4558 }
4559
4560 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4561 for (BasicBlock &BB : F)
4562 if (!AssumedLiveBlocks.count(&BB)) {
4563 A.deleteAfterManifest(BB);
4564 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4565 HasChanged = ChangeStatus::CHANGED;
4566 }
4567
4568 return HasChanged;
4569 }
4570
4571 /// See AbstractAttribute::updateImpl(...).
4572 ChangeStatus updateImpl(Attributor &A) override;
4573
4574 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4575 assert(From->getParent() == getAnchorScope() &&
4576 To->getParent() == getAnchorScope() &&
4577 "Used AAIsDead of the wrong function");
4578 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4579 }
4580
4581 /// See AbstractAttribute::trackStatistics()
4582 void trackStatistics() const override {}
4583
4584 /// Returns true if the function is assumed dead.
4585 bool isAssumedDead() const override { return false; }
4586
4587 /// See AAIsDead::isKnownDead().
4588 bool isKnownDead() const override { return false; }
4589
4590 /// See AAIsDead::isAssumedDead(BasicBlock *).
4591 bool isAssumedDead(const BasicBlock *BB) const override {
4592 assert(BB->getParent() == getAnchorScope() &&
4593 "BB must be in the same anchor scope function.");
4594
4595 if (!getAssumed())
4596 return false;
4597 return !AssumedLiveBlocks.count(BB);
4598 }
4599
4600 /// See AAIsDead::isKnownDead(BasicBlock *).
4601 bool isKnownDead(const BasicBlock *BB) const override {
4602 return getKnown() && isAssumedDead(BB);
4603 }
4604
4605 /// See AAIsDead::isAssumed(Instruction *I).
4606 bool isAssumedDead(const Instruction *I) const override {
4607 assert(I->getParent()->getParent() == getAnchorScope() &&
4608 "Instruction must be in the same anchor scope function.");
4609
4610 if (!getAssumed())
4611 return false;
4612
4613 // If it is not in AssumedLiveBlocks then it for sure dead.
4614 // Otherwise, it can still be after noreturn call in a live block.
4615 if (!AssumedLiveBlocks.count(I->getParent()))
4616 return true;
4617
4618 // If it is not after a liveness barrier it is live.
4619 const Instruction *PrevI = I->getPrevNode();
4620 while (PrevI) {
4621 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4622 return true;
4623 PrevI = PrevI->getPrevNode();
4624 }
4625 return false;
4626 }
4627
4628 /// See AAIsDead::isKnownDead(Instruction *I).
4629 bool isKnownDead(const Instruction *I) const override {
4630 return getKnown() && isAssumedDead(I);
4631 }
4632
4633 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4634 /// that internal function called from \p BB should now be looked at.
4635 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4636 if (!AssumedLiveBlocks.insert(&BB).second)
4637 return false;
4638
4639 // We assume that all of BB is (probably) live now and if there are calls to
4640 // internal functions we will assume that those are now live as well. This
4641 // is a performance optimization for blocks with calls to a lot of internal
4642 // functions. It can however cause dead functions to be treated as live.
4643 for (const Instruction &I : BB)
4644 if (const auto *CB = dyn_cast<CallBase>(&I))
4646 if (F->hasLocalLinkage())
4647 A.markLiveInternalFunction(*F);
4648 return true;
4649 }
4650
4651 /// Collection of instructions that need to be explored again, e.g., we
4652 /// did assume they do not transfer control to (one of their) successors.
4653 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4654
4655 /// Collection of instructions that are known to not transfer control.
4656 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4657
4658 /// Collection of all assumed live edges
4659 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4660
4661 /// Collection of all assumed live BasicBlocks.
4662 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4663};
4664
4665static bool
4666identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4667 AbstractAttribute &AA,
4668 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4669 const IRPosition &IPos = IRPosition::callsite_function(CB);
4670
4671 bool IsKnownNoReturn;
4673 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4674 return !IsKnownNoReturn;
4675 if (CB.isTerminator())
4676 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4677 else
4678 AliveSuccessors.push_back(CB.getNextNode());
4679 return false;
4680}
4681
4682static bool
4683identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4684 AbstractAttribute &AA,
4685 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4686 bool UsedAssumedInformation =
4687 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4688
4689 // First, determine if we can change an invoke to a call assuming the
4690 // callee is nounwind. This is not possible if the personality of the
4691 // function allows to catch asynchronous exceptions.
4692 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4693 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4694 } else {
4695 const IRPosition &IPos = IRPosition::callsite_function(II);
4696
4697 bool IsKnownNoUnwind;
4699 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4700 UsedAssumedInformation |= !IsKnownNoUnwind;
4701 } else {
4702 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4703 }
4704 }
4705 return UsedAssumedInformation;
4706}
4707
4708static bool
4709identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4710 AbstractAttribute &AA,
4711 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4712 bool UsedAssumedInformation = false;
4713 if (BI.getNumSuccessors() == 1) {
4714 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4715 } else {
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 }
4730 return UsedAssumedInformation;
4731}
4732
4733static bool
4734identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4735 AbstractAttribute &AA,
4736 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4737 bool UsedAssumedInformation = false;
4739 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4740 Values, AA::AnyScope,
4741 UsedAssumedInformation)) {
4742 // Something went wrong, assume all successors are live.
4743 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4744 AliveSuccessors.push_back(&SuccBB->front());
4745 return false;
4746 }
4747
4748 if (Values.empty() ||
4749 (Values.size() == 1 &&
4750 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4751 // No valid value yet, assume all edges are dead.
4752 return UsedAssumedInformation;
4753 }
4754
4755 Type &Ty = *SI.getCondition()->getType();
4756 SmallPtrSet<ConstantInt *, 8> Constants;
4757 auto CheckForConstantInt = [&](Value *V) {
4758 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4759 Constants.insert(CI);
4760 return true;
4761 }
4762 return false;
4763 };
4764
4765 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4766 return CheckForConstantInt(VAC.getValue());
4767 })) {
4768 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4769 AliveSuccessors.push_back(&SuccBB->front());
4770 return UsedAssumedInformation;
4771 }
4772
4773 unsigned MatchedCases = 0;
4774 for (const auto &CaseIt : SI.cases()) {
4775 if (Constants.count(CaseIt.getCaseValue())) {
4776 ++MatchedCases;
4777 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4778 }
4779 }
4780
4781 // If all potential values have been matched, we will not visit the default
4782 // case.
4783 if (MatchedCases < Constants.size())
4784 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4785 return UsedAssumedInformation;
4786}
4787
4788ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4790
4791 if (AssumedLiveBlocks.empty()) {
4792 if (isAssumedDeadInternalFunction(A))
4794
4795 Function *F = getAnchorScope();
4796 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4797 assumeLive(A, F->getEntryBlock());
4798 Change = ChangeStatus::CHANGED;
4799 }
4800
4801 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4802 << getAnchorScope()->size() << "] BBs and "
4803 << ToBeExploredFrom.size() << " exploration points and "
4804 << KnownDeadEnds.size() << " known dead ends\n");
4805
4806 // Copy and clear the list of instructions we need to explore from. It is
4807 // refilled with instructions the next update has to look at.
4808 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4809 ToBeExploredFrom.end());
4810 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4811
4813 while (!Worklist.empty()) {
4814 const Instruction *I = Worklist.pop_back_val();
4815 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4816
4817 // Fast forward for uninteresting instructions. We could look for UB here
4818 // though.
4819 while (!I->isTerminator() && !isa<CallBase>(I))
4820 I = I->getNextNode();
4821
4822 AliveSuccessors.clear();
4823
4824 bool UsedAssumedInformation = false;
4825 switch (I->getOpcode()) {
4826 // TODO: look for (assumed) UB to backwards propagate "deadness".
4827 default:
4828 assert(I->isTerminator() &&
4829 "Expected non-terminators to be handled already!");
4830 for (const BasicBlock *SuccBB : successors(I->getParent()))
4831 AliveSuccessors.push_back(&SuccBB->front());
4832 break;
4833 case Instruction::Call:
4834 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4835 *this, AliveSuccessors);
4836 break;
4837 case Instruction::Invoke:
4838 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4839 *this, AliveSuccessors);
4840 break;
4841 case Instruction::Br:
4842 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4843 *this, AliveSuccessors);
4844 break;
4845 case Instruction::Switch:
4846 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4847 *this, AliveSuccessors);
4848 break;
4849 }
4850
4851 if (UsedAssumedInformation) {
4852 NewToBeExploredFrom.insert(I);
4853 } else if (AliveSuccessors.empty() ||
4854 (I->isTerminator() &&
4855 AliveSuccessors.size() < I->getNumSuccessors())) {
4856 if (KnownDeadEnds.insert(I))
4857 Change = ChangeStatus::CHANGED;
4858 }
4859
4860 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4861 << AliveSuccessors.size() << " UsedAssumedInformation: "
4862 << UsedAssumedInformation << "\n");
4863
4864 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4865 if (!I->isTerminator()) {
4866 assert(AliveSuccessors.size() == 1 &&
4867 "Non-terminator expected to have a single successor!");
4868 Worklist.push_back(AliveSuccessor);
4869 } else {
4870 // record the assumed live edge
4871 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4872 if (AssumedLiveEdges.insert(Edge).second)
4873 Change = ChangeStatus::CHANGED;
4874 if (assumeLive(A, *AliveSuccessor->getParent()))
4875 Worklist.push_back(AliveSuccessor);
4876 }
4877 }
4878 }
4879
4880 // Check if the content of ToBeExploredFrom changed, ignore the order.
4881 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4882 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4883 return !ToBeExploredFrom.count(I);
4884 })) {
4885 Change = ChangeStatus::CHANGED;
4886 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4887 }
4888
4889 // If we know everything is live there is no need to query for liveness.
4890 // Instead, indicating a pessimistic fixpoint will cause the state to be
4891 // "invalid" and all queries to be answered conservatively without lookups.
4892 // To be in this state we have to (1) finished the exploration and (3) not
4893 // discovered any non-trivial dead end and (2) not ruled unreachable code
4894 // dead.
4895 if (ToBeExploredFrom.empty() &&
4896 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4897 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4898 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4899 }))
4900 return indicatePessimisticFixpoint();
4901 return Change;
4902}
4903
4904/// Liveness information for a call sites.
4905struct AAIsDeadCallSite final : AAIsDeadFunction {
4906 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4907 : AAIsDeadFunction(IRP, A) {}
4908
4909 /// See AbstractAttribute::initialize(...).
4910 void initialize(Attributor &A) override {
4911 // TODO: Once we have call site specific value information we can provide
4912 // call site specific liveness information and then it makes
4913 // sense to specialize attributes for call sites instead of
4914 // redirecting requests to the callee.
4915 llvm_unreachable("Abstract attributes for liveness are not "
4916 "supported for call sites yet!");
4917 }
4918
4919 /// See AbstractAttribute::updateImpl(...).
4920 ChangeStatus updateImpl(Attributor &A) override {
4921 return indicatePessimisticFixpoint();
4922 }
4923
4924 /// See AbstractAttribute::trackStatistics()
4925 void trackStatistics() const override {}
4926};
4927} // namespace
4928
4929/// -------------------- Dereferenceable Argument Attribute --------------------
4930
4931namespace {
4932struct AADereferenceableImpl : AADereferenceable {
4933 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4934 : AADereferenceable(IRP, A) {}
4935 using StateType = DerefState;
4936
4937 /// See AbstractAttribute::initialize(...).
4938 void initialize(Attributor &A) override {
4939 Value &V = *getAssociatedValue().stripPointerCasts();
4941 A.getAttrs(getIRPosition(),
4942 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4943 Attrs, /* IgnoreSubsumingPositions */ false);
4944 for (const Attribute &Attr : Attrs)
4945 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4946
4947 // Ensure we initialize the non-null AA (if necessary).
4948 bool IsKnownNonNull;
4950 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4951
4952 bool CanBeNull, CanBeFreed;
4953 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4954 A.getDataLayout(), CanBeNull, CanBeFreed));
4955
4956 if (Instruction *CtxI = getCtxI())
4957 followUsesInMBEC(*this, A, getState(), *CtxI);
4958 }
4959
4960 /// See AbstractAttribute::getState()
4961 /// {
4962 StateType &getState() override { return *this; }
4963 const StateType &getState() const override { return *this; }
4964 /// }
4965
4966 /// Helper function for collecting accessed bytes in must-be-executed-context
4967 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4968 DerefState &State) {
4969 const Value *UseV = U->get();
4970 if (!UseV->getType()->isPointerTy())
4971 return;
4972
4973 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4974 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4975 return;
4976
4977 int64_t Offset;
4979 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4980 if (Base && Base == &getAssociatedValue())
4981 State.addAccessedBytes(Offset, Loc->Size.getValue());
4982 }
4983
4984 /// See followUsesInMBEC
4985 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4986 AADereferenceable::StateType &State) {
4987 bool IsNonNull = false;
4988 bool TrackUse = false;
4989 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4990 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4991 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4992 << " for instruction " << *I << "\n");
4993
4994 addAccessedBytesForUse(A, U, I, State);
4995 State.takeKnownDerefBytesMaximum(DerefBytes);
4996 return TrackUse;
4997 }
4998
4999 /// See AbstractAttribute::manifest(...).
5000 ChangeStatus manifest(Attributor &A) override {
5001 ChangeStatus Change = AADereferenceable::manifest(A);
5002 bool IsKnownNonNull;
5003 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5004 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5005 if (IsAssumedNonNull &&
5006 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5007 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5008 return ChangeStatus::CHANGED;
5009 }
5010 return Change;
5011 }
5012
5013 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5014 SmallVectorImpl<Attribute> &Attrs) const override {
5015 // TODO: Add *_globally support
5016 bool IsKnownNonNull;
5017 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5018 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5019 if (IsAssumedNonNull)
5020 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5021 Ctx, getAssumedDereferenceableBytes()));
5022 else
5023 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5024 Ctx, getAssumedDereferenceableBytes()));
5025 }
5026
5027 /// See AbstractAttribute::getAsStr().
5028 const std::string getAsStr(Attributor *A) const override {
5029 if (!getAssumedDereferenceableBytes())
5030 return "unknown-dereferenceable";
5031 bool IsKnownNonNull;
5032 bool IsAssumedNonNull = false;
5033 if (A)
5035 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5036 return std::string("dereferenceable") +
5037 (IsAssumedNonNull ? "" : "_or_null") +
5038 (isAssumedGlobal() ? "_globally" : "") + "<" +
5039 std::to_string(getKnownDereferenceableBytes()) + "-" +
5040 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5041 (!A ? " [non-null is unknown]" : "");
5042 }
5043};
5044
5045/// Dereferenceable attribute for a floating value.
5046struct AADereferenceableFloating : AADereferenceableImpl {
5047 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5048 : AADereferenceableImpl(IRP, A) {}
5049
5050 /// See AbstractAttribute::updateImpl(...).
5051 ChangeStatus updateImpl(Attributor &A) override {
5052 bool Stripped;
5053 bool UsedAssumedInformation = false;
5055 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5056 AA::AnyScope, UsedAssumedInformation)) {
5057 Values.push_back({getAssociatedValue(), getCtxI()});
5058 Stripped = false;
5059 } else {
5060 Stripped = Values.size() != 1 ||
5061 Values.front().getValue() != &getAssociatedValue();
5062 }
5063
5064 const DataLayout &DL = A.getDataLayout();
5065 DerefState T;
5066
5067 auto VisitValueCB = [&](const Value &V) -> bool {
5068 unsigned IdxWidth =
5069 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5070 APInt Offset(IdxWidth, 0);
5072 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5073 /* AllowNonInbounds */ true);
5074
5075 const auto *AA = A.getAAFor<AADereferenceable>(
5076 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5077 int64_t DerefBytes = 0;
5078 if (!AA || (!Stripped && this == AA)) {
5079 // Use IR information if we did not strip anything.
5080 // TODO: track globally.
5081 bool CanBeNull, CanBeFreed;
5082 DerefBytes =
5083 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5084 T.GlobalState.indicatePessimisticFixpoint();
5085 } else {
5086 const DerefState &DS = AA->getState();
5087 DerefBytes = DS.DerefBytesState.getAssumed();
5088 T.GlobalState &= DS.GlobalState;
5089 }
5090
5091 // For now we do not try to "increase" dereferenceability due to negative
5092 // indices as we first have to come up with code to deal with loops and
5093 // for overflows of the dereferenceable bytes.
5094 int64_t OffsetSExt = Offset.getSExtValue();
5095 if (OffsetSExt < 0)
5096 OffsetSExt = 0;
5097
5098 T.takeAssumedDerefBytesMinimum(
5099 std::max(int64_t(0), DerefBytes - OffsetSExt));
5100
5101 if (this == AA) {
5102 if (!Stripped) {
5103 // If nothing was stripped IR information is all we got.
5104 T.takeKnownDerefBytesMaximum(
5105 std::max(int64_t(0), DerefBytes - OffsetSExt));
5106 T.indicatePessimisticFixpoint();
5107 } else if (OffsetSExt > 0) {
5108 // If something was stripped but there is circular reasoning we look
5109 // for the offset. If it is positive we basically decrease the
5110 // dereferenceable bytes in a circular loop now, which will simply
5111 // drive them down to the known value in a very slow way which we
5112 // can accelerate.
5113 T.indicatePessimisticFixpoint();
5114 }
5115 }
5116
5117 return T.isValidState();
5118 };
5119
5120 for (const auto &VAC : Values)
5121 if (!VisitValueCB(*VAC.getValue()))
5122 return indicatePessimisticFixpoint();
5123
5124 return clampStateAndIndicateChange(getState(), T);
5125 }
5126
5127 /// See AbstractAttribute::trackStatistics()
5128 void trackStatistics() const override {
5129 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5130 }
5131};
5132
5133/// Dereferenceable attribute for a return value.
5134struct AADereferenceableReturned final
5135 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5136 using Base =
5137 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5138 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5139 : Base(IRP, A) {}
5140
5141 /// See AbstractAttribute::trackStatistics()
5142 void trackStatistics() const override {
5143 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5144 }
5145};
5146
5147/// Dereferenceable attribute for an argument
5148struct AADereferenceableArgument final
5149 : AAArgumentFromCallSiteArguments<AADereferenceable,
5150 AADereferenceableImpl> {
5151 using Base =
5152 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5153 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5154 : Base(IRP, A) {}
5155
5156 /// See AbstractAttribute::trackStatistics()
5157 void trackStatistics() const override {
5158 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5159 }
5160};
5161
5162/// Dereferenceable attribute for a call site argument.
5163struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5164 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5165 : AADereferenceableFloating(IRP, A) {}
5166
5167 /// See AbstractAttribute::trackStatistics()
5168 void trackStatistics() const override {
5169 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5170 }
5171};
5172
5173/// Dereferenceable attribute deduction for a call site return value.
5174struct AADereferenceableCallSiteReturned final
5175 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5176 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5177 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5178 : Base(IRP, A) {}
5179
5180 /// See AbstractAttribute::trackStatistics()
5181 void trackStatistics() const override {
5182 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5183 }
5184};
5185} // namespace
5186
5187// ------------------------ Align Argument Attribute ------------------------
5188
5189namespace {
5190static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5191 Value &AssociatedValue, const Use *U,
5192 const Instruction *I, bool &TrackUse) {
5193 // We need to follow common pointer manipulation uses to the accesses they
5194 // feed into.
5195 if (isa<CastInst>(I)) {
5196 // Follow all but ptr2int casts.
5197 TrackUse = !isa<PtrToIntInst>(I);
5198 return 0;
5199 }
5200 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5201 if (GEP->hasAllConstantIndices())
5202 TrackUse = true;
5203 return 0;
5204 }
5205
5206 MaybeAlign MA;
5207 if (const auto *CB = dyn_cast<CallBase>(I)) {
5208 if (CB->isBundleOperand(U) || CB->isCallee(U))
5209 return 0;
5210
5211 unsigned ArgNo = CB->getArgOperandNo(U);
5212 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5213 // As long as we only use known information there is no need to track
5214 // dependences here.
5215 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5216 if (AlignAA)
5217 MA = MaybeAlign(AlignAA->getKnownAlign());
5218 }
5219
5220 const DataLayout &DL = A.getDataLayout();
5221 const Value *UseV = U->get();
5222 if (auto *SI = dyn_cast<StoreInst>(I)) {
5223 if (SI->getPointerOperand() == UseV)
5224 MA = SI->getAlign();
5225 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5226 if (LI->getPointerOperand() == UseV)
5227 MA = LI->getAlign();
5228 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5229 if (AI->getPointerOperand() == UseV)
5230 MA = AI->getAlign();
5231 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5232 if (AI->getPointerOperand() == UseV)
5233 MA = AI->getAlign();
5234 }
5235
5236 if (!MA || *MA <= QueryingAA.getKnownAlign())
5237 return 0;
5238
5239 unsigned Alignment = MA->value();
5240 int64_t Offset;
5241
5242 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5243 if (Base == &AssociatedValue) {
5244 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5245 // So we can say that the maximum power of two which is a divisor of
5246 // gcd(Offset, Alignment) is an alignment.
5247
5248 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5249 Alignment = llvm::bit_floor(gcd);
5250 }
5251 }
5252
5253 return Alignment;
5254}
5255
5256struct AAAlignImpl : AAAlign {
5257 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5258
5259 /// See AbstractAttribute::initialize(...).
5260 void initialize(Attributor &A) override {
5262 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5263 for (const Attribute &Attr : Attrs)
5264 takeKnownMaximum(Attr.getValueAsInt());
5265
5266 Value &V = *getAssociatedValue().stripPointerCasts();
5267 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5268
5269 if (Instruction *CtxI = getCtxI())
5270 followUsesInMBEC(*this, A, getState(), *CtxI);
5271 }
5272
5273 /// See AbstractAttribute::manifest(...).
5274 ChangeStatus manifest(Attributor &A) override {
5275 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5276
5277 // Check for users that allow alignment annotations.
5278 Value &AssociatedValue = getAssociatedValue();
5279 if (isa<ConstantData>(AssociatedValue))
5280 return ChangeStatus::UNCHANGED;
5281
5282 for (const Use &U : AssociatedValue.uses()) {
5283 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5284 if (SI->getPointerOperand() == &AssociatedValue)
5285 if (SI->getAlign() < getAssumedAlign()) {
5286 STATS_DECLTRACK(AAAlign, Store,
5287 "Number of times alignment added to a store");
5288 SI->setAlignment(getAssumedAlign());
5289 InstrChanged = ChangeStatus::CHANGED;
5290 }
5291 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5292 if (LI->getPointerOperand() == &AssociatedValue)
5293 if (LI->getAlign() < getAssumedAlign()) {
5294 LI->setAlignment(getAssumedAlign());
5295 STATS_DECLTRACK(AAAlign, Load,
5296 "Number of times alignment added to a load");
5297 InstrChanged = ChangeStatus::CHANGED;
5298 }
5299 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5300 if (RMW->getPointerOperand() == &AssociatedValue) {
5301 if (RMW->getAlign() < getAssumedAlign()) {
5302 STATS_DECLTRACK(AAAlign, AtomicRMW,
5303 "Number of times alignment added to atomicrmw");
5304
5305 RMW->setAlignment(getAssumedAlign());
5306 InstrChanged = ChangeStatus::CHANGED;
5307 }
5308 }
5309 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5310 if (CAS->getPointerOperand() == &AssociatedValue) {
5311 if (CAS->getAlign() < getAssumedAlign()) {
5312 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5313 "Number of times alignment added to cmpxchg");
5314 CAS->setAlignment(getAssumedAlign());
5315 InstrChanged = ChangeStatus::CHANGED;
5316 }
5317 }
5318 }
5319 }
5320
5321 ChangeStatus Changed = AAAlign::manifest(A);
5322
5323 Align InheritAlign =
5324 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5325 if (InheritAlign >= getAssumedAlign())
5326 return InstrChanged;
5327 return Changed | InstrChanged;
5328 }
5329
5330 // TODO: Provide a helper to determine the implied ABI alignment and check in
5331 // the existing manifest method and a new one for AAAlignImpl that value
5332 // to avoid making the alignment explicit if it did not improve.
5333
5334 /// See AbstractAttribute::getDeducedAttributes
5335 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5336 SmallVectorImpl<Attribute> &Attrs) const override {
5337 if (getAssumedAlign() > 1)
5338 Attrs.emplace_back(
5339 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5340 }
5341
5342 /// See followUsesInMBEC
5343 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5344 AAAlign::StateType &State) {
5345 bool TrackUse = false;
5346
5347 unsigned int KnownAlign =
5348 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5349 State.takeKnownMaximum(KnownAlign);
5350
5351 return TrackUse;
5352 }
5353
5354 /// See AbstractAttribute::getAsStr().
5355 const std::string getAsStr(Attributor *A) const override {
5356 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5357 std::to_string(getAssumedAlign().value()) + ">";
5358 }
5359};
5360
5361/// Align attribute for a floating value.
5362struct AAAlignFloating : AAAlignImpl {
5363 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5364
5365 /// See AbstractAttribute::updateImpl(...).
5366 ChangeStatus updateImpl(Attributor &A) override {
5367 const DataLayout &DL = A.getDataLayout();
5368
5369 bool Stripped;
5370 bool UsedAssumedInformation = false;
5372 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5373 AA::AnyScope, UsedAssumedInformation)) {
5374 Values.push_back({getAssociatedValue(), getCtxI()});
5375 Stripped = false;
5376 } else {
5377 Stripped = Values.size() != 1 ||
5378 Values.front().getValue() != &getAssociatedValue();
5379 }
5380
5381 StateType T;
5382 auto VisitValueCB = [&](Value &V) -> bool {
5384 return true;
5385 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5386 DepClassTy::REQUIRED);
5387 if (!AA || (!Stripped && this == AA)) {
5388 int64_t Offset;
5389 unsigned Alignment = 1;
5390 if (const Value *Base =
5392 // TODO: Use AAAlign for the base too.
5393 Align PA = Base->getPointerAlignment(DL);
5394 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5395 // So we can say that the maximum power of two which is a divisor of
5396 // gcd(Offset, Alignment) is an alignment.
5397
5398 uint32_t gcd =
5399 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5400 Alignment = llvm::bit_floor(gcd);
5401 } else {
5402 Alignment = V.getPointerAlignment(DL).value();
5403 }
5404 // Use only IR information if we did not strip anything.
5405 T.takeKnownMaximum(Alignment);
5406 T.indicatePessimisticFixpoint();
5407 } else {
5408 // Use abstract attribute information.
5409 const AAAlign::StateType &DS = AA->getState();
5410 T ^= DS;
5411 }
5412 return T.isValidState();
5413 };
5414
5415 for (const auto &VAC : Values) {
5416 if (!VisitValueCB(*VAC.getValue()))
5417 return indicatePessimisticFixpoint();
5418 }
5419
5420 // TODO: If we know we visited all incoming values, thus no are assumed
5421 // dead, we can take the known information from the state T.
5422 return clampStateAndIndicateChange(getState(), T);
5423 }
5424
5425 /// See AbstractAttribute::trackStatistics()
5426 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5427};
5428
5429/// Align attribute for function return value.
5430struct AAAlignReturned final
5431 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5432 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5433 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5434
5435 /// See AbstractAttribute::trackStatistics()
5436 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5437};
5438
5439/// Align attribute for function argument.
5440struct AAAlignArgument final
5441 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5442 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5443 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5444
5445 /// See AbstractAttribute::manifest(...).
5446 ChangeStatus manifest(Attributor &A) override {
5447 // If the associated argument is involved in a must-tail call we give up
5448 // because we would need to keep the argument alignments of caller and
5449 // callee in-sync. Just does not seem worth the trouble right now.
5450 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5451 return ChangeStatus::UNCHANGED;
5452 return Base::manifest(A);
5453 }
5454
5455 /// See AbstractAttribute::trackStatistics()
5456 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5457};
5458
5459struct AAAlignCallSiteArgument final : AAAlignFloating {
5460 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5461 : AAAlignFloating(IRP, A) {}
5462
5463 /// See AbstractAttribute::manifest(...).
5464 ChangeStatus manifest(Attributor &A) override {
5465 // If the associated argument is involved in a must-tail call we give up
5466 // because we would need to keep the argument alignments of caller and
5467 // callee in-sync. Just does not seem worth the trouble right now.
5468 if (Argument *Arg = getAssociatedArgument())
5469 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5470 return ChangeStatus::UNCHANGED;
5471 ChangeStatus Changed = AAAlignImpl::manifest(A);
5472 Align InheritAlign =
5473 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5474 if (InheritAlign >= getAssumedAlign())
5475 Changed = ChangeStatus::UNCHANGED;
5476 return Changed;
5477 }
5478
5479 /// See AbstractAttribute::updateImpl(Attributor &A).
5480 ChangeStatus updateImpl(Attributor &A) override {
5481 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5482 if (Argument *Arg = getAssociatedArgument()) {
5483 // We only take known information from the argument
5484 // so we do not need to track a dependence.
5485 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5486 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5487 if (ArgAlignAA)
5488 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5489 }
5490 return Changed;
5491 }
5492
5493 /// See AbstractAttribute::trackStatistics()
5494 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5495};
5496
5497/// Align attribute deduction for a call site return value.
5498struct AAAlignCallSiteReturned final
5499 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5500 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5501 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5502 : Base(IRP, A) {}
5503
5504 /// See AbstractAttribute::trackStatistics()
5505 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5506};
5507} // namespace
5508
5509/// ------------------ Function No-Return Attribute ----------------------------
5510namespace {
5511struct AANoReturnImpl : public AANoReturn {
5512 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5513
5514 /// See AbstractAttribute::initialize(...).
5515 void initialize(Attributor &A) override {
5516 bool IsKnown;
5518 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5519 (void)IsKnown;
5520 }
5521
5522 /// See AbstractAttribute::getAsStr().
5523 const std::string getAsStr(Attributor *A) const override {
5524 return getAssumed() ? "noreturn" : "may-return";
5525 }
5526
5527 /// See AbstractAttribute::updateImpl(Attributor &A).
5528 ChangeStatus updateImpl(Attributor &A) override {
5529 auto CheckForNoReturn = [](Instruction &) { return false; };
5530 bool UsedAssumedInformation = false;
5531 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5532 {(unsigned)Instruction::Ret},
5533 UsedAssumedInformation))
5534 return indicatePessimisticFixpoint();
5535 return ChangeStatus::UNCHANGED;
5536 }
5537};
5538
5539struct AANoReturnFunction final : AANoReturnImpl {
5540 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5541 : AANoReturnImpl(IRP, A) {}
5542
5543 /// See AbstractAttribute::trackStatistics()
5544 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5545};
5546
5547/// NoReturn attribute deduction for a call sites.
5548struct AANoReturnCallSite final
5549 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5550 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5551 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5552
5553 /// See AbstractAttribute::trackStatistics()
5554 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5555};
5556} // namespace
5557
5558/// ----------------------- Instance Info ---------------------------------
5559
5560namespace {
5561/// A class to hold the state of for no-capture attributes.
5562struct AAInstanceInfoImpl : public AAInstanceInfo {
5563 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5564 : AAInstanceInfo(IRP, A) {}
5565
5566 /// See AbstractAttribute::initialize(...).
5567 void initialize(Attributor &A) override {
5568 Value &V = getAssociatedValue();
5569 if (auto *C = dyn_cast<Constant>(&V)) {
5570 if (C->isThreadDependent())
5571 indicatePessimisticFixpoint();
5572 else
5573 indicateOptimisticFixpoint();
5574 return;
5575 }
5576 if (auto *CB = dyn_cast<CallBase>(&V))
5577 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5578 !CB->mayReadFromMemory()) {
5579 indicateOptimisticFixpoint();
5580 return;
5581 }
5582 if (auto *I = dyn_cast<Instruction>(&V)) {
5583 const auto *CI =
5584 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5585 *I->getFunction());
5586 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5587 indicatePessimisticFixpoint();
5588 return;
5589 }
5590 }
5591 }
5592
5593 /// See AbstractAttribute::updateImpl(...).
5594 ChangeStatus updateImpl(Attributor &A) override {
5595 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5596
5597 Value &V = getAssociatedValue();
5598 const Function *Scope = nullptr;
5599 if (auto *I = dyn_cast<Instruction>(&V))
5600 Scope = I->getFunction();
5601 if (auto *A = dyn_cast<Argument>(&V)) {
5602 Scope = A->getParent();
5603 if (!Scope->hasLocalLinkage())
5604 return Changed;
5605 }
5606 if (!Scope)
5607 return indicateOptimisticFixpoint();
5608
5609 bool IsKnownNoRecurse;
5611 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5612 IsKnownNoRecurse))
5613 return Changed;
5614
5615 auto UsePred = [&](const Use &U, bool &Follow) {
5616 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5617 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5618 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5619 Follow = true;
5620 return true;
5621 }
5622 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5623 (isa<StoreInst>(UserI) &&
5624 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5625 return true;
5626 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5627 // This check is not guaranteeing uniqueness but for now that we cannot
5628 // end up with two versions of \p U thinking it was one.
5630 if (!Callee || !Callee->hasLocalLinkage())
5631 return true;
5632 if (!CB->isArgOperand(&U))
5633 return false;
5634 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5636 DepClassTy::OPTIONAL);
5637 if (!ArgInstanceInfoAA ||
5638 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5639 return false;
5640 // If this call base might reach the scope again we might forward the
5641 // argument back here. This is very conservative.
5643 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5644 [Scope](const Function &Fn) { return &Fn != Scope; }))
5645 return false;
5646 return true;
5647 }
5648 return false;
5649 };
5650
5651 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5652 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5653 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5654 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5655 AA::isDynamicallyUnique(A, *this, *Ptr))
5656 return true;
5657 }
5658 return false;
5659 };
5660
5661 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5662 DepClassTy::OPTIONAL,
5663 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5664 return indicatePessimisticFixpoint();
5665
5666 return Changed;
5667 }
5668
5669 /// See AbstractState::getAsStr().
5670 const std::string getAsStr(Attributor *A) const override {
5671 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5672 }
5673
5674 /// See AbstractAttribute::trackStatistics()
5675 void trackStatistics() const override {}
5676};
5677
5678/// InstanceInfo attribute for floating values.
5679struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5680 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5681 : AAInstanceInfoImpl(IRP, A) {}
5682};
5683
5684/// NoCapture attribute for function arguments.
5685struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5686 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5687 : AAInstanceInfoFloating(IRP, A) {}
5688};
5689
5690/// InstanceInfo attribute for call site arguments.
5691struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5692 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5693 : AAInstanceInfoImpl(IRP, A) {}
5694
5695 /// See AbstractAttribute::updateImpl(...).
5696 ChangeStatus updateImpl(Attributor &A) override {
5697 // TODO: Once we have call site specific value information we can provide
5698 // call site specific liveness information and then it makes
5699 // sense to specialize attributes for call sites arguments instead of
5700 // redirecting requests to the callee argument.
5701 Argument *Arg = getAssociatedArgument();
5702 if (!Arg)
5703 return indicatePessimisticFixpoint();
5704 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5705 auto *ArgAA =
5706 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5707 if (!ArgAA)
5708 return indicatePessimisticFixpoint();
5709 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5710 }
5711};
5712
5713/// InstanceInfo attribute for function return value.
5714struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5715 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5716 : AAInstanceInfoImpl(IRP, A) {
5717 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5718 }
5719
5720 /// See AbstractAttribute::initialize(...).
5721 void initialize(Attributor &A) override {
5722 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5723 }
5724
5725 /// See AbstractAttribute::updateImpl(...).
5726 ChangeStatus updateImpl(Attributor &A) override {
5727 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5728 }
5729};
5730
5731/// InstanceInfo attribute deduction for a call site return value.
5732struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5733 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5734 : AAInstanceInfoFloating(IRP, A) {}
5735};
5736} // namespace
5737
5738/// ----------------------- Variable Capturing ---------------------------------
5740 Attribute::AttrKind ImpliedAttributeKind,
5741 bool IgnoreSubsumingPositions) {
5742 assert(ImpliedAttributeKind == Attribute::Captures &&
5743 "Unexpected attribute kind");
5744 Value &V = IRP.getAssociatedValue();
5745 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5746 return V.use_empty();
5747
5748 // You cannot "capture" null in the default address space.
5749 //
5750 // FIXME: This should use NullPointerIsDefined to account for the function
5751 // attribute.
5753 V.getType()->getPointerAddressSpace() == 0)) {
5754 return true;
5755 }
5756
5758 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5759 /* IgnoreSubsumingPositions */ true);
5760 for (const Attribute &Attr : Attrs)
5761 if (capturesNothing(Attr.getCaptureInfo()))
5762 return true;
5763
5765 if (Argument *Arg = IRP.getAssociatedArgument()) {
5767 A.getAttrs(IRPosition::argument(*Arg),
5768 {Attribute::Captures, Attribute::ByVal}, Attrs,
5769 /* IgnoreSubsumingPositions */ true);
5770 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5771 return Attr.getKindAsEnum() == Attribute::ByVal ||
5773 });
5774 if (ArgNoCapture) {
5775 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5776 V.getContext(), CaptureInfo::none()));
5777 return true;
5778 }
5779 }
5780
5781 if (const Function *F = IRP.getAssociatedFunction()) {
5782 // Check what state the associated function can actually capture.
5785 if (State.isKnown(NO_CAPTURE)) {
5786 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5788 return true;
5789 }
5790 }
5791
5792 return false;
5793}
5794
5795/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5796/// depending on the ability of the function associated with \p IRP to capture
5797/// state in memory and through "returning/throwing", respectively.
5799 const Function &F,
5800 BitIntegerState &State) {
5801 // TODO: Once we have memory behavior attributes we should use them here.
5802
5803 // If we know we cannot communicate or write to memory, we do not care about
5804 // ptr2int anymore.
5805 bool ReadOnly = F.onlyReadsMemory();
5806 bool NoThrow = F.doesNotThrow();
5807 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5808 if (ReadOnly && NoThrow && IsVoidReturn) {
5809 State.addKnownBits(NO_CAPTURE);
5810 return;
5811 }
5812
5813 // A function cannot capture state in memory if it only reads memory, it can
5814 // however return/throw state and the state might be influenced by the
5815 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5816 if (ReadOnly)
5817 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5818
5819 // A function cannot communicate state back if it does not through
5820 // exceptions and doesn not return values.
5821 if (NoThrow && IsVoidReturn)
5822 State.addKnownBits(NOT_CAPTURED_IN_RET);
5823
5824 // Check existing "returned" attributes.
5825 int ArgNo = IRP.getCalleeArgNo();
5826 if (!NoThrow || ArgNo < 0 ||
5827 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5828 return;
5829
5830 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5831 if (F.hasParamAttribute(U, Attribute::Returned)) {
5832 if (U == unsigned(ArgNo))
5833 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5834 else if (ReadOnly)
5835 State.addKnownBits(NO_CAPTURE);
5836 else
5837 State.addKnownBits(NOT_CAPTURED_IN_RET);
5838 break;
5839 }
5840}
5841
5842namespace {
5843/// A class to hold the state of for no-capture attributes.
5844struct AANoCaptureImpl : public AANoCapture {
5845 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5846
5847 /// See AbstractAttribute::initialize(...).
5848 void initialize(Attributor &A) override {
5849 bool IsKnown;
5851 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5852 (void)IsKnown;
5853 }
5854
5855 /// See AbstractAttribute::updateImpl(...).
5856 ChangeStatus updateImpl(Attributor &A) override;
5857
5858 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5859 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5860 SmallVectorImpl<Attribute> &Attrs) const override {
5861 if (!isAssumedNoCaptureMaybeReturned())
5862 return;
5863
5864 if (isArgumentPosition()) {
5865 if (isAssumedNoCapture())
5866 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5867 else if (ManifestInternal)
5868 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5869 }
5870 }
5871
5872 /// See AbstractState::getAsStr().
5873 const std::string getAsStr(Attributor *A) const override {
5874 if (isKnownNoCapture())
5875 return "known not-captured";
5876 if (isAssumedNoCapture())
5877 return "assumed not-captured";
5878 if (isKnownNoCaptureMaybeReturned())
5879 return "known not-captured-maybe-returned";
5880 if (isAssumedNoCaptureMaybeReturned())
5881 return "assumed not-captured-maybe-returned";
5882 return "assumed-captured";
5883 }
5884
5885 /// Check the use \p U and update \p State accordingly. Return true if we
5886 /// should continue to update the state.
5887 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5888 bool &Follow) {
5889 Instruction *UInst = cast<Instruction>(U.getUser());
5890 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5891 << *UInst << "\n");
5892
5893 // Deal with ptr2int by following uses.
5894 if (isa<PtrToIntInst>(UInst)) {
5895 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5896 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5897 /* Return */ true);
5898 }
5899
5900 // For stores we already checked if we can follow them, if they make it
5901 // here we give up.
5902 if (isa<StoreInst>(UInst))
5903 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5904 /* Return */ true);
5905
5906 // Explicitly catch return instructions.
5907 if (isa<ReturnInst>(UInst)) {
5908 if (UInst->getFunction() == getAnchorScope())
5909 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5910 /* Return */ true);
5911 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5912 /* Return */ true);
5913 }
5914
5915 // For now we only use special logic for call sites. However, the tracker
5916 // itself knows about a lot of other non-capturing cases already.
5917 auto *CB = dyn_cast<CallBase>(UInst);
5918 if (!CB || !CB->isArgOperand(&U))
5919 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5920 /* Return */ true);
5921
5922 unsigned ArgNo = CB->getArgOperandNo(&U);
5923 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5924 // If we have a abstract no-capture attribute for the argument we can use
5925 // it to justify a non-capture attribute here. This allows recursion!
5926 bool IsKnownNoCapture;
5927 const AANoCapture *ArgNoCaptureAA = nullptr;
5928 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
5929 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5930 &ArgNoCaptureAA);
5931 if (IsAssumedNoCapture)
5932 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5933 /* Return */ false);
5934 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5935 Follow = true;
5936 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5937 /* Return */ false);
5938 }
5939
5940 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5941 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5942 /* Return */ true);
5943 }
5944
5945 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5946 /// \p CapturedInRet, then return true if we should continue updating the
5947 /// state.
5948 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
5949 bool CapturedInInt, bool CapturedInRet) {
5950 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
5951 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
5952 if (CapturedInMem)
5953 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
5954 if (CapturedInInt)
5955 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
5956 if (CapturedInRet)
5957 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
5958 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
5959 }
5960};
5961
5962ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
5963 const IRPosition &IRP = getIRPosition();
5964 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
5965 : &IRP.getAssociatedValue();
5966 if (!V)
5967 return indicatePessimisticFixpoint();
5968
5969 const Function *F =
5970 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
5971
5972 // TODO: Is the checkForAllUses below useful for constants?
5973 if (!F)
5974 return indicatePessimisticFixpoint();
5975
5977 const IRPosition &FnPos = IRPosition::function(*F);
5978
5979 // Readonly means we cannot capture through memory.
5980 bool IsKnown;
5981 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
5982 T.addKnownBits(NOT_CAPTURED_IN_MEM);
5983 if (IsKnown)
5984 addKnownBits(NOT_CAPTURED_IN_MEM);
5985 }
5986
5987 // Make sure all returned values are different than the underlying value.
5988 // TODO: we could do this in a more sophisticated way inside
5989 // AAReturnedValues, e.g., track all values that escape through returns
5990 // directly somehow.
5991 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
5993 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
5995 UsedAssumedInformation))
5996 return false;
5997 bool SeenConstant = false;
5998 for (const AA::ValueAndContext &VAC : Values) {
5999 if (isa<Constant>(VAC.getValue())) {
6000 if (SeenConstant)
6001 return false;
6002 SeenConstant = true;
6003 } else if (!isa<Argument>(VAC.getValue()) ||
6004 VAC.getValue() == getAssociatedArgument())
6005 return false;
6006 }
6007 return true;
6008 };
6009
6010 bool IsKnownNoUnwind;
6012 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6013 bool IsVoidTy = F->getReturnType()->isVoidTy();
6014 bool UsedAssumedInformation = false;
6015 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6016 T.addKnownBits(NOT_CAPTURED_IN_RET);
6017 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6019 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6020 addKnownBits(NOT_CAPTURED_IN_RET);
6021 if (isKnown(NOT_CAPTURED_IN_MEM))
6022 return indicateOptimisticFixpoint();
6023 }
6024 }
6025 }
6026
6027 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6028 // TODO(captures): Make this more precise.
6029 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6030 if (capturesNothing(CI))
6031 return true;
6032 if (CI.isPassthrough()) {
6033 Follow = true;
6034 return true;
6035 }
6036 return checkUse(A, T, U, Follow);
6037 };
6038
6039 if (!A.checkForAllUses(UseCheck, *this, *V))
6040 return indicatePessimisticFixpoint();
6041
6042 AANoCapture::StateType &S = getState();
6043 auto Assumed = S.getAssumed();
6044 S.intersectAssumedBits(T.getAssumed());
6045 if (!isAssumedNoCaptureMaybeReturned())
6046 return indicatePessimisticFixpoint();
6047 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6049}
6050
6051/// NoCapture attribute for function arguments.
6052struct AANoCaptureArgument final : AANoCaptureImpl {
6053 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6054 : AANoCaptureImpl(IRP, A) {}
6055
6056 /// See AbstractAttribute::trackStatistics()
6057 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6058};
6059
6060/// NoCapture attribute for call site arguments.
6061struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6062 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6063 : AANoCaptureImpl(IRP, A) {}
6064
6065 /// See AbstractAttribute::updateImpl(...).
6066 ChangeStatus updateImpl(Attributor &A) override {
6067 // TODO: Once we have call site specific value information we can provide
6068 // call site specific liveness information and then it makes
6069 // sense to specialize attributes for call sites arguments instead of
6070 // redirecting requests to the callee argument.
6071 Argument *Arg = getAssociatedArgument();
6072 if (!Arg)
6073 return indicatePessimisticFixpoint();
6074 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6075 bool IsKnownNoCapture;
6076 const AANoCapture *ArgAA = nullptr;
6078 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6079 &ArgAA))
6080 return ChangeStatus::UNCHANGED;
6081 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6082 return indicatePessimisticFixpoint();
6083 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6084 }
6085
6086 /// See AbstractAttribute::trackStatistics()
6087 void trackStatistics() const override {
6089 };
6090};
6091
6092/// NoCapture attribute for floating values.
6093struct AANoCaptureFloating final : AANoCaptureImpl {
6094 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6095 : AANoCaptureImpl(IRP, A) {}
6096
6097 /// See AbstractAttribute::trackStatistics()
6098 void trackStatistics() const override {
6100 }
6101};
6102
6103/// NoCapture attribute for function return value.
6104struct AANoCaptureReturned final : AANoCaptureImpl {
6105 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6106 : AANoCaptureImpl(IRP, A) {
6107 llvm_unreachable("NoCapture is not applicable to function returns!");
6108 }
6109
6110 /// See AbstractAttribute::initialize(...).
6111 void initialize(Attributor &A) override {
6112 llvm_unreachable("NoCapture is not applicable to function returns!");
6113 }
6114
6115 /// See AbstractAttribute::updateImpl(...).
6116 ChangeStatus updateImpl(Attributor &A) override {
6117 llvm_unreachable("NoCapture is not applicable to function returns!");
6118 }
6119
6120 /// See AbstractAttribute::trackStatistics()
6121 void trackStatistics() const override {}
6122};
6123
6124/// NoCapture attribute deduction for a call site return value.
6125struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6126 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6127 : AANoCaptureImpl(IRP, A) {}
6128
6129 /// See AbstractAttribute::initialize(...).
6130 void initialize(Attributor &A) override {
6131 const Function *F = getAnchorScope();
6132 // Check what state the associated function can actually capture.
6133 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6134 }
6135
6136 /// See AbstractAttribute::trackStatistics()
6137 void trackStatistics() const override {
6139 }
6140};
6141} // namespace
6142
6143/// ------------------ Value Simplify Attribute ----------------------------
6144
6145bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6146 // FIXME: Add a typecast support.
6149 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6150 return false;
6151
6152 LLVM_DEBUG({
6154 dbgs() << "[ValueSimplify] is assumed to be "
6155 << **SimplifiedAssociatedValue << "\n";
6156 else
6157 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6158 });
6159 return true;
6160}
6161
6162namespace {
6163struct AAValueSimplifyImpl : AAValueSimplify {
6164 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6165 : AAValueSimplify(IRP, A) {}
6166
6167 /// See AbstractAttribute::initialize(...).
6168 void initialize(Attributor &A) override {
6169 if (getAssociatedValue().getType()->isVoidTy())
6170 indicatePessimisticFixpoint();
6171 if (A.hasSimplificationCallback(getIRPosition()))
6172 indicatePessimisticFixpoint();
6173 }
6174
6175 /// See AbstractAttribute::getAsStr().
6176 const std::string getAsStr(Attributor *A) const override {
6177 LLVM_DEBUG({
6178 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6179 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6180 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6181 });
6182 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6183 : "not-simple";
6184 }
6185
6186 /// See AbstractAttribute::trackStatistics()
6187 void trackStatistics() const override {}
6188
6189 /// See AAValueSimplify::getAssumedSimplifiedValue()
6190 std::optional<Value *>
6191 getAssumedSimplifiedValue(Attributor &A) const override {
6192 return SimplifiedAssociatedValue;
6193 }
6194
6195 /// Ensure the return value is \p V with type \p Ty, if not possible return
6196 /// nullptr. If \p Check is true we will only verify such an operation would
6197 /// suceed and return a non-nullptr value if that is the case. No IR is
6198 /// generated or modified.
6199 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6200 bool Check) {
6201 if (auto *TypedV = AA::getWithType(V, Ty))
6202 return TypedV;
6203 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6204 return Check ? &V
6205 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6206 &V, &Ty, "", CtxI->getIterator());
6207 return nullptr;
6208 }
6209
6210 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6211 /// If \p Check is true we will only verify such an operation would suceed and
6212 /// return a non-nullptr value if that is the case. No IR is generated or
6213 /// modified.
6214 static Value *reproduceInst(Attributor &A,
6215 const AbstractAttribute &QueryingAA,
6216 Instruction &I, Type &Ty, Instruction *CtxI,
6217 bool Check, ValueToValueMapTy &VMap) {
6218 assert(CtxI && "Cannot reproduce an instruction without context!");
6219 if (Check && (I.mayReadFromMemory() ||
6220 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6221 /* TLI */ nullptr)))
6222 return nullptr;
6223 for (Value *Op : I.operands()) {
6224 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6225 if (!NewOp) {
6226 assert(Check && "Manifest of new value unexpectedly failed!");
6227 return nullptr;
6228 }
6229 if (!Check)
6230 VMap[Op] = NewOp;
6231 }
6232 if (Check)
6233 return &I;
6234
6235 Instruction *CloneI = I.clone();
6236 // TODO: Try to salvage debug information here.
6237 CloneI->setDebugLoc(DebugLoc());
6238 VMap[&I] = CloneI;
6239 CloneI->insertBefore(CtxI->getIterator());
6240 RemapInstruction(CloneI, VMap);
6241 return CloneI;
6242 }
6243
6244 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6245 /// If \p Check is true we will only verify such an operation would suceed and
6246 /// return a non-nullptr value if that is the case. No IR is generated or
6247 /// modified.
6248 static Value *reproduceValue(Attributor &A,
6249 const AbstractAttribute &QueryingAA, Value &V,
6250 Type &Ty, Instruction *CtxI, bool Check,
6251 ValueToValueMapTy &VMap) {
6252 if (const auto &NewV = VMap.lookup(&V))
6253 return NewV;
6254 bool UsedAssumedInformation = false;
6255 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6256 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6257 if (!SimpleV.has_value())
6258 return PoisonValue::get(&Ty);
6259 Value *EffectiveV = &V;
6260 if (*SimpleV)
6261 EffectiveV = *SimpleV;
6262 if (auto *C = dyn_cast<Constant>(EffectiveV))
6263 return C;
6264 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6265 A.getInfoCache()))
6266 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6267 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6268 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6269 return ensureType(A, *NewV, Ty, CtxI, Check);
6270 return nullptr;
6271 }
6272
6273 /// Return a value we can use as replacement for the associated one, or
6274 /// nullptr if we don't have one that makes sense.
6275 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6276 Value *NewV = SimplifiedAssociatedValue
6277 ? *SimplifiedAssociatedValue
6278 : UndefValue::get(getAssociatedType());
6279 if (NewV && NewV != &getAssociatedValue()) {
6280 ValueToValueMapTy VMap;
6281 // First verify we can reprduce the value with the required type at the
6282 // context location before we actually start modifying the IR.
6283 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6284 /* CheckOnly */ true, VMap))
6285 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6286 /* CheckOnly */ false, VMap);
6287 }
6288 return nullptr;
6289 }
6290
6291 /// Helper function for querying AAValueSimplify and updating candidate.
6292 /// \param IRP The value position we are trying to unify with SimplifiedValue
6293 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6294 const IRPosition &IRP, bool Simplify = true) {
6295 bool UsedAssumedInformation = false;
6296 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6297 if (Simplify)
6298 QueryingValueSimplified = A.getAssumedSimplified(
6299 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6300 return unionAssumed(QueryingValueSimplified);
6301 }
6302
6303 /// Returns a candidate is found or not
6304 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6305 if (!getAssociatedValue().getType()->isIntegerTy())
6306 return false;
6307
6308 // This will also pass the call base context.
6309 const auto *AA =
6310 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6311 if (!AA)
6312 return false;
6313
6314 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6315
6316 if (!COpt) {
6317 SimplifiedAssociatedValue = std::nullopt;
6318 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6319 return true;
6320 }
6321 if (auto *C = *COpt) {
6322 SimplifiedAssociatedValue = C;
6323 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6324 return true;
6325 }
6326 return false;
6327 }
6328
6329 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6330 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6331 return true;
6332 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6333 return true;
6334 return false;
6335 }
6336
6337 /// See AbstractAttribute::manifest(...).
6338 ChangeStatus manifest(Attributor &A) override {
6339 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6340 for (auto &U : getAssociatedValue().uses()) {
6341 // Check if we need to adjust the insertion point to make sure the IR is
6342 // valid.
6343 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6344 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6345 IP = PHI->getIncomingBlock(U)->getTerminator();
6346 if (auto *NewV = manifestReplacementValue(A, IP)) {
6347 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6348 << " -> " << *NewV << " :: " << *this << "\n");
6349 if (A.changeUseAfterManifest(U, *NewV))
6350 Changed = ChangeStatus::CHANGED;
6351 }
6352 }
6353
6354 return Changed | AAValueSimplify::manifest(A);
6355 }
6356
6357 /// See AbstractState::indicatePessimisticFixpoint(...).
6358 ChangeStatus indicatePessimisticFixpoint() override {
6359 SimplifiedAssociatedValue = &getAssociatedValue();
6360 return AAValueSimplify::indicatePessimisticFixpoint();
6361 }
6362};
6363
6364struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6365 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6366 : AAValueSimplifyImpl(IRP, A) {}
6367
6368 void initialize(Attributor &A) override {
6369 AAValueSimplifyImpl::initialize(A);
6370 if (A.hasAttr(getIRPosition(),
6371 {Attribute::InAlloca, Attribute::Preallocated,
6372 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6373 /* IgnoreSubsumingPositions */ true))
6374 indicatePessimisticFixpoint();
6375 }
6376
6377 /// See AbstractAttribute::updateImpl(...).
6378 ChangeStatus updateImpl(Attributor &A) override {
6379 // Byval is only replacable if it is readonly otherwise we would write into
6380 // the replaced value and not the copy that byval creates implicitly.
6381 Argument *Arg = getAssociatedArgument();
6382 if (Arg->hasByValAttr()) {
6383 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6384 // there is no race by not copying a constant byval.
6385 bool IsKnown;
6386 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6387 return indicatePessimisticFixpoint();
6388 }
6389
6390 auto Before = SimplifiedAssociatedValue;
6391
6392 auto PredForCallSite = [&](AbstractCallSite ACS) {
6393 const IRPosition &ACSArgPos =
6394 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6395 // Check if a coresponding argument was found or if it is on not
6396 // associated (which can happen for callback calls).
6397 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6398 return false;
6399
6400 // Simplify the argument operand explicitly and check if the result is
6401 // valid in the current scope. This avoids refering to simplified values
6402 // in other functions, e.g., we don't want to say a an argument in a
6403 // static function is actually an argument in a different function.
6404 bool UsedAssumedInformation = false;
6405 std::optional<Constant *> SimpleArgOp =
6406 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6407 if (!SimpleArgOp)
6408 return true;
6409 if (!*SimpleArgOp)
6410 return false;
6411 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6412 return false;
6413 return unionAssumed(*SimpleArgOp);
6414 };
6415
6416 // Generate a answer specific to a call site context.
6417 bool Success;
6418 bool UsedAssumedInformation = false;
6419 if (hasCallBaseContext() &&
6420 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6421 Success = PredForCallSite(
6422 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6423 else
6424 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6425 UsedAssumedInformation);
6426
6427 if (!Success)
6428 if (!askSimplifiedValueForOtherAAs(A))
6429 return indicatePessimisticFixpoint();
6430
6431 // If a candidate was found in this update, return CHANGED.
6432 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6433 : ChangeStatus ::CHANGED;
6434 }
6435
6436 /// See AbstractAttribute::trackStatistics()
6437 void trackStatistics() const override {
6438 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6439 }
6440};
6441
6442struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6443 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6444 : AAValueSimplifyImpl(IRP, A) {}
6445
6446 /// See AAValueSimplify::getAssumedSimplifiedValue()
6447 std::optional<Value *>
6448 getAssumedSimplifiedValue(Attributor &A) const override {
6449 if (!isValidState())
6450 return nullptr;
6451 return SimplifiedAssociatedValue;
6452 }
6453
6454 /// See AbstractAttribute::updateImpl(...).
6455 ChangeStatus updateImpl(Attributor &A) override {
6456 auto Before = SimplifiedAssociatedValue;
6457
6458 auto ReturnInstCB = [&](Instruction &I) {
6459 auto &RI = cast<ReturnInst>(I);
6460 return checkAndUpdate(
6461 A, *this,
6462 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6463 };
6464
6465 bool UsedAssumedInformation = false;
6466 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6467 UsedAssumedInformation))
6468 if (!askSimplifiedValueForOtherAAs(A))
6469 return indicatePessimisticFixpoint();
6470
6471 // If a candidate was found in this update, return CHANGED.
6472 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6473 : ChangeStatus ::CHANGED;
6474 }
6475
6476 ChangeStatus manifest(Attributor &A) override {
6477 // We queried AAValueSimplify for the returned values so they will be
6478 // replaced if a simplified form was found. Nothing to do here.
6479 return ChangeStatus::UNCHANGED;
6480 }
6481
6482 /// See AbstractAttribute::trackStatistics()
6483 void trackStatistics() const override {
6484 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6485 }
6486};
6487
6488struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6489 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6490 : AAValueSimplifyImpl(IRP, A) {}
6491
6492 /// See AbstractAttribute::initialize(...).
6493 void initialize(Attributor &A) override {
6494 AAValueSimplifyImpl::initialize(A);
6495 Value &V = getAnchorValue();
6496
6497 // TODO: add other stuffs
6498 if (isa<Constant>(V))
6499 indicatePessimisticFixpoint();
6500 }
6501
6502 /// See AbstractAttribute::updateImpl(...).
6503 ChangeStatus updateImpl(Attributor &A) override {
6504 auto Before = SimplifiedAssociatedValue;
6505 if (!askSimplifiedValueForOtherAAs(A))
6506 return indicatePessimisticFixpoint();
6507
6508 // If a candidate was found in this update, return CHANGED.
6509 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6510 : ChangeStatus ::CHANGED;
6511 }
6512
6513 /// See AbstractAttribute::trackStatistics()
6514 void trackStatistics() const override {
6515 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6516 }
6517};
6518
6519struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6520 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6521 : AAValueSimplifyImpl(IRP, A) {}
6522
6523 /// See AbstractAttribute::initialize(...).
6524 void initialize(Attributor &A) override {
6525 SimplifiedAssociatedValue = nullptr;
6526 indicateOptimisticFixpoint();
6527 }
6528 /// See AbstractAttribute::initialize(...).
6529 ChangeStatus updateImpl(Attributor &A) override {
6531 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6532 }
6533 /// See AbstractAttribute::trackStatistics()
6534 void trackStatistics() const override {
6535 STATS_DECLTRACK_FN_ATTR(value_simplify)
6536 }
6537};
6538
6539struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6540 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6541 : AAValueSimplifyFunction(IRP, A) {}
6542 /// See AbstractAttribute::trackStatistics()
6543 void trackStatistics() const override {
6544 STATS_DECLTRACK_CS_ATTR(value_simplify)
6545 }
6546};
6547
6548struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6549 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6550 : AAValueSimplifyImpl(IRP, A) {}
6551
6552 void initialize(Attributor &A) override {
6553 AAValueSimplifyImpl::initialize(A);
6554 Function *Fn = getAssociatedFunction();
6555 assert(Fn && "Did expect an associted function");
6556 for (Argument &Arg : Fn->args()) {
6557 if (Arg.hasReturnedAttr()) {
6558 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6559 Arg.getArgNo());
6561 checkAndUpdate(A, *this, IRP))
6562 indicateOptimisticFixpoint();
6563 else
6564 indicatePessimisticFixpoint();
6565 return;
6566 }
6567 }
6568 }
6569
6570 /// See AbstractAttribute::updateImpl(...).
6571 ChangeStatus updateImpl(Attributor &A) override {
6572 return indicatePessimisticFixpoint();
6573 }
6574
6575 void trackStatistics() const override {
6576 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6577 }
6578};
6579
6580struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6581 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6582 : AAValueSimplifyFloating(IRP, A) {}
6583
6584 /// See AbstractAttribute::manifest(...).
6585 ChangeStatus manifest(Attributor &A) override {
6586 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6587 // TODO: We should avoid simplification duplication to begin with.
6588 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6589 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6590 if (FloatAA && FloatAA->getState().isValidState())
6591 return Changed;
6592
6593 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6594 Use &U = cast<CallBase>(&getAnchorValue())
6595 ->getArgOperandUse(getCallSiteArgNo());
6596 if (A.changeUseAfterManifest(U, *NewV))
6597 Changed = ChangeStatus::CHANGED;
6598 }
6599
6600 return Changed | AAValueSimplify::manifest(A);
6601 }
6602
6603 void trackStatistics() const override {
6604 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6605 }
6606};
6607} // namespace
6608
6609/// ----------------------- Heap-To-Stack Conversion ---------------------------
6610namespace {
6611struct AAHeapToStackFunction final : public AAHeapToStack {
6612
6613 struct AllocationInfo {
6614 /// The call that allocates the memory.
6615 CallBase *const CB;
6616
6617 /// The library function id for the allocation.
6618 LibFunc LibraryFunctionId = NotLibFunc;
6619
6620 /// The status wrt. a rewrite.
6621 enum {
6622 STACK_DUE_TO_USE,
6623 STACK_DUE_TO_FREE,
6624 INVALID,
6625 } Status = STACK_DUE_TO_USE;
6626
6627 /// Flag to indicate if we encountered a use that might free this allocation
6628 /// but which is not in the deallocation infos.
6629 bool HasPotentiallyFreeingUnknownUses = false;
6630
6631 /// Flag to indicate that we should place the new alloca in the function
6632 /// entry block rather than where the call site (CB) is.
6633 bool MoveAllocaIntoEntry = true;
6634
6635 /// The set of free calls that use this allocation.
6636 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6637 };
6638
6639 struct DeallocationInfo {
6640 /// The call that deallocates the memory.
6641 CallBase *const CB;
6642 /// The value freed by the call.
6643 Value *FreedOp;
6644
6645 /// Flag to indicate if we don't know all objects this deallocation might
6646 /// free.
6647 bool MightFreeUnknownObjects = false;
6648
6649 /// The set of allocation calls that are potentially freed.
6650 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6651 };
6652
6653 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6654 : AAHeapToStack(IRP, A) {}
6655
6656 ~AAHeapToStackFunction() {
6657 // Ensure we call the destructor so we release any memory allocated in the
6658 // sets.
6659 for (auto &It : AllocationInfos)
6660 It.second->~AllocationInfo();
6661 for (auto &It : DeallocationInfos)
6662 It.second->~DeallocationInfo();
6663 }
6664
6665 void initialize(Attributor &A) override {
6666 AAHeapToStack::initialize(A);
6667
6668 const Function *F = getAnchorScope();
6669 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6670
6671 auto AllocationIdentifierCB = [&](Instruction &I) {
6672 CallBase *CB = dyn_cast<CallBase>(&I);
6673 if (!CB)
6674 return true;
6675 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6676 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6677 return true;
6678 }
6679 // To do heap to stack, we need to know that the allocation itself is
6680 // removable once uses are rewritten, and that we can initialize the
6681 // alloca to the same pattern as the original allocation result.
6682 if (isRemovableAlloc(CB, TLI)) {
6683 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6684 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6685 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6686 AllocationInfos[CB] = AI;
6687 if (TLI)
6688 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6689 }
6690 }
6691 return true;
6692 };
6693
6694 bool UsedAssumedInformation = false;
6695 bool Success = A.checkForAllCallLikeInstructions(
6696 AllocationIdentifierCB, *this, UsedAssumedInformation,
6697 /* CheckBBLivenessOnly */ false,
6698 /* CheckPotentiallyDead */ true);
6699 (void)Success;
6700 assert(Success && "Did not expect the call base visit callback to fail!");
6701
6703 [](const IRPosition &, const AbstractAttribute *,
6704 bool &) -> std::optional<Value *> { return nullptr; };
6705 for (const auto &It : AllocationInfos)
6706 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6707 SCB);
6708 for (const auto &It : DeallocationInfos)
6709 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6710 SCB);
6711 }
6712
6713 const std::string getAsStr(Attributor *A) const override {
6714 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6715 for (const auto &It : AllocationInfos) {
6716 if (It.second->Status == AllocationInfo::INVALID)
6717 ++NumInvalidMallocs;
6718 else
6719 ++NumH2SMallocs;
6720 }
6721 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6722 std::to_string(NumInvalidMallocs);
6723 }
6724
6725 /// See AbstractAttribute::trackStatistics().
6726 void trackStatistics() const override {
6727 STATS_DECL(
6728 MallocCalls, Function,
6729 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6730 for (const auto &It : AllocationInfos)
6731 if (It.second->Status != AllocationInfo::INVALID)
6732 ++BUILD_STAT_NAME(MallocCalls, Function);
6733 }
6734
6735 bool isAssumedHeapToStack(const CallBase &CB) const override {
6736 if (isValidState())
6737 if (AllocationInfo *AI =
6738 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6739 return AI->Status != AllocationInfo::INVALID;
6740 return false;
6741 }
6742
6743 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6744 if (!isValidState())
6745 return false;
6746
6747 for (const auto &It : AllocationInfos) {
6748 AllocationInfo &AI = *It.second;
6749 if (AI.Status == AllocationInfo::INVALID)
6750 continue;
6751
6752 if (AI.PotentialFreeCalls.count(&CB))
6753 return true;
6754 }
6755
6756 return false;
6757 }
6758
6759 ChangeStatus manifest(Attributor &A) override {
6760 assert(getState().isValidState() &&
6761 "Attempted to manifest an invalid state!");
6762
6763 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6764 Function *F = getAnchorScope();
6765 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6766
6767 for (auto &It : AllocationInfos) {
6768 AllocationInfo &AI = *It.second;
6769 if (AI.Status == AllocationInfo::INVALID)
6770 continue;
6771
6772 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6773 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6774 A.deleteAfterManifest(*FreeCall);
6775 HasChanged = ChangeStatus::CHANGED;
6776 }
6777
6778 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6779 << "\n");
6780
6781 auto Remark = [&](OptimizationRemark OR) {
6782 LibFunc IsAllocShared;
6783 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6784 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6785 return OR << "Moving globalized variable to the stack.";
6786 return OR << "Moving memory allocation from the heap to the stack.";
6787 };
6788 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6789 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6790 else
6791 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6792
6793 const DataLayout &DL = A.getInfoCache().getDL();
6794 Value *Size;
6795 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6796 if (SizeAPI) {
6797 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6798 } else {
6799 LLVMContext &Ctx = AI.CB->getContext();
6800 ObjectSizeOpts Opts;
6801 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6802 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6803 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6804 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6805 Size = SizeOffsetPair.Size;
6806 }
6807
6808 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6809 ? F->getEntryBlock().begin()
6810 : AI.CB->getIterator();
6811
6812 Align Alignment(1);
6813 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6814 Alignment = std::max(Alignment, *RetAlign);
6815 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6816 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6817 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6818 "Expected an alignment during manifest!");
6819 Alignment =
6820 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6821 }
6822
6823 // TODO: Hoist the alloca towards the function entry.
6824 unsigned AS = DL.getAllocaAddrSpace();
6825 Instruction *Alloca =
6826 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6827 AI.CB->getName() + ".h2s", IP);
6828
6829 if (Alloca->getType() != AI.CB->getType())
6830 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6831 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6832
6833 auto *I8Ty = Type::getInt8Ty(F->getContext());
6834 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6835 assert(InitVal &&
6836 "Must be able to materialize initial memory state of allocation");
6837
6838 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6839
6840 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6841 auto *NBB = II->getNormalDest();
6842 BranchInst::Create(NBB, AI.CB->getParent());
6843 A.deleteAfterManifest(*AI.CB);
6844 } else {
6845 A.deleteAfterManifest(*AI.CB);
6846 }
6847
6848 // Initialize the alloca with the same value as used by the allocation
6849 // function. We can skip undef as the initial value of an alloc is
6850 // undef, and the memset would simply end up being DSEd.
6851 if (!isa<UndefValue>(InitVal)) {
6852 IRBuilder<> Builder(Alloca->getNextNode());
6853 // TODO: Use alignment above if align!=1
6854 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6855 }
6856 HasChanged = ChangeStatus::CHANGED;
6857 }
6858
6859 return HasChanged;
6860 }
6861
6862 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6863 Value &V) {
6864 bool UsedAssumedInformation = false;
6865 std::optional<Constant *> SimpleV =
6866 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6867 if (!SimpleV)
6868 return APInt(64, 0);
6869 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6870 return CI->getValue();
6871 return std::nullopt;
6872 }
6873
6874 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6875 AllocationInfo &AI) {
6876 auto Mapper = [&](const Value *V) -> const Value * {
6877 bool UsedAssumedInformation = false;
6878 if (std::optional<Constant *> SimpleV =
6879 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6880 if (*SimpleV)
6881 return *SimpleV;
6882 return V;
6883 };
6884
6885 const Function *F = getAnchorScope();
6886 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6887 return getAllocSize(AI.CB, TLI, Mapper);
6888 }
6889
6890 /// Collection of all malloc-like calls in a function with associated
6891 /// information.
6892 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6893
6894 /// Collection of all free-like calls in a function with associated
6895 /// information.
6896 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6897
6898 ChangeStatus updateImpl(Attributor &A) override;
6899};
6900
6901ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6903 const Function *F = getAnchorScope();
6904 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6905
6906 const auto *LivenessAA =
6907 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6908
6909 MustBeExecutedContextExplorer *Explorer =
6910 A.getInfoCache().getMustBeExecutedContextExplorer();
6911
6912 bool StackIsAccessibleByOtherThreads =
6913 A.getInfoCache().stackIsAccessibleByOtherThreads();
6914
6915 LoopInfo *LI =
6916 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6917 std::optional<bool> MayContainIrreducibleControl;
6918 auto IsInLoop = [&](BasicBlock &BB) {
6919 if (&F->getEntryBlock() == &BB)
6920 return false;
6921 if (!MayContainIrreducibleControl.has_value())
6922 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6923 if (*MayContainIrreducibleControl)
6924 return true;
6925 if (!LI)
6926 return true;
6927 return LI->getLoopFor(&BB) != nullptr;
6928 };
6929
6930 // Flag to ensure we update our deallocation information at most once per
6931 // updateImpl call and only if we use the free check reasoning.
6932 bool HasUpdatedFrees = false;
6933
6934 auto UpdateFrees = [&]() {
6935 HasUpdatedFrees = true;
6936
6937 for (auto &It : DeallocationInfos) {
6938 DeallocationInfo &DI = *It.second;
6939 // For now we cannot use deallocations that have unknown inputs, skip
6940 // them.
6941 if (DI.MightFreeUnknownObjects)
6942 continue;
6943
6944 // No need to analyze dead calls, ignore them instead.
6945 bool UsedAssumedInformation = false;
6946 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
6947 /* CheckBBLivenessOnly */ true))
6948 continue;
6949
6950 // Use the non-optimistic version to get the freed object.
6951 Value *Obj = getUnderlyingObject(DI.FreedOp);
6952 if (!Obj) {
6953 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6954 DI.MightFreeUnknownObjects = true;
6955 continue;
6956 }
6957
6958 // Free of null and undef can be ignored as no-ops (or UB in the latter
6959 // case).
6961 continue;
6962
6963 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
6964 if (!ObjCB) {
6965 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6966 << "\n");
6967 DI.MightFreeUnknownObjects = true;
6968 continue;
6969 }
6970
6971 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
6972 if (!AI) {
6973 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6974 << "\n");
6975 DI.MightFreeUnknownObjects = true;
6976 continue;
6977 }
6978
6979 DI.PotentialAllocationCalls.insert(ObjCB);
6980 }
6981 };
6982
6983 auto FreeCheck = [&](AllocationInfo &AI) {
6984 // If the stack is not accessible by other threads, the "must-free" logic
6985 // doesn't apply as the pointer could be shared and needs to be places in
6986 // "shareable" memory.
6987 if (!StackIsAccessibleByOtherThreads) {
6988 bool IsKnownNoSycn;
6990 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
6991 LLVM_DEBUG(
6992 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6993 "other threads and function is not nosync:\n");
6994 return false;
6995 }
6996 }
6997 if (!HasUpdatedFrees)
6998 UpdateFrees();
6999
7000 // TODO: Allow multi exit functions that have different free calls.
7001 if (AI.PotentialFreeCalls.size() != 1) {
7002 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7003 << AI.PotentialFreeCalls.size() << "\n");
7004 return false;
7005 }
7006 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7007 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7008 if (!DI) {
7009 LLVM_DEBUG(
7010 dbgs() << "[H2S] unique free call was not known as deallocation call "
7011 << *UniqueFree << "\n");
7012 return false;
7013 }
7014 if (DI->MightFreeUnknownObjects) {
7015 LLVM_DEBUG(
7016 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7017 return false;
7018 }
7019 if (DI->PotentialAllocationCalls.empty())
7020 return true;
7021 if (DI->PotentialAllocationCalls.size() > 1) {
7022 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7023 << DI->PotentialAllocationCalls.size()
7024 << " different allocations\n");
7025 return false;
7026 }
7027 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7028 LLVM_DEBUG(
7029 dbgs()
7030 << "[H2S] unique free call not known to free this allocation but "
7031 << **DI->PotentialAllocationCalls.begin() << "\n");
7032 return false;
7033 }
7034
7035 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
7036 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
7037 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7038 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7039 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7040 "with the allocation "
7041 << *UniqueFree << "\n");
7042 return false;
7043 }
7044 }
7045 return true;
7046 };
7047
7048 auto UsesCheck = [&](AllocationInfo &AI) {
7049 bool ValidUsesOnly = true;
7050
7051 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7052 Instruction *UserI = cast<Instruction>(U.getUser());
7053 if (isa<LoadInst>(UserI))
7054 return true;
7055 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7056 if (SI->getValueOperand() == U.get()) {
7058 << "[H2S] escaping store to memory: " << *UserI << "\n");
7059 ValidUsesOnly = false;
7060 } else {
7061 // A store into the malloc'ed memory is fine.
7062 }
7063 return true;
7064 }
7065 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7066 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7067 return true;
7068 if (DeallocationInfos.count(CB)) {
7069 AI.PotentialFreeCalls.insert(CB);
7070 return true;
7071 }
7072
7073 unsigned ArgNo = CB->getArgOperandNo(&U);
7074 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7075
7076 bool IsKnownNoCapture;
7077 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7078 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7079
7080 // If a call site argument use is nofree, we are fine.
7081 bool IsKnownNoFree;
7082 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7083 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7084
7085 if (!IsAssumedNoCapture ||
7086 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7087 !IsAssumedNoFree)) {
7088 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7089
7090 // Emit a missed remark if this is missed OpenMP globalization.
7091 auto Remark = [&](OptimizationRemarkMissed ORM) {
7092 return ORM
7093 << "Could not move globalized variable to the stack. "
7094 "Variable is potentially captured in call. Mark "
7095 "parameter as `__attribute__((noescape))` to override.";
7096 };
7097
7098 if (ValidUsesOnly &&
7099 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7100 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7101
7102 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7103 ValidUsesOnly = false;
7104 }
7105 return true;
7106 }
7107
7108 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7109 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7110 Follow = true;
7111 return true;
7112 }
7113 // Unknown user for which we can not track uses further (in a way that
7114 // makes sense).
7115 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7116 ValidUsesOnly = false;
7117 return true;
7118 };
7119 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7120 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7121 [&](const Use &OldU, const Use &NewU) {
7122 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7123 return !SI || StackIsAccessibleByOtherThreads ||
7124 AA::isAssumedThreadLocalObject(
7125 A, *SI->getPointerOperand(), *this);
7126 }))
7127 return false;
7128 return ValidUsesOnly;
7129 };
7130
7131 // The actual update starts here. We look at all allocations and depending on
7132 // their status perform the appropriate check(s).
7133 for (auto &It : AllocationInfos) {
7134 AllocationInfo &AI = *It.second;
7135 if (AI.Status == AllocationInfo::INVALID)
7136 continue;
7137
7138 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7139 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7140 if (!APAlign) {
7141 // Can't generate an alloca which respects the required alignment
7142 // on the allocation.
7143 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7144 << "\n");
7145 AI.Status = AllocationInfo::INVALID;
7147 continue;
7148 }
7149 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7150 !APAlign->isPowerOf2()) {
7151 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7152 << "\n");
7153 AI.Status = AllocationInfo::INVALID;
7155 continue;
7156 }
7157 }
7158
7159 std::optional<APInt> Size = getSize(A, *this, AI);
7160 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7161 MaxHeapToStackSize != -1) {
7162 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7163 LLVM_DEBUG({
7164 if (!Size)
7165 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7166 else
7167 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7168 << MaxHeapToStackSize << "\n";
7169 });
7170
7171 AI.Status = AllocationInfo::INVALID;
7173 continue;
7174 }
7175 }
7176
7177 switch (AI.Status) {
7178 case AllocationInfo::STACK_DUE_TO_USE:
7179 if (UsesCheck(AI))
7180 break;
7181 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7182 [[fallthrough]];
7183 case AllocationInfo::STACK_DUE_TO_FREE:
7184 if (FreeCheck(AI))
7185 break;
7186 AI.Status = AllocationInfo::INVALID;
7188 break;
7189 case AllocationInfo::INVALID:
7190 llvm_unreachable("Invalid allocations should never reach this point!");
7191 };
7192
7193 // Check if we still think we can move it into the entry block. If the
7194 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7195 // ignore the potential compilations associated with loops.
7196 bool IsGlobalizedLocal =
7197 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7198 if (AI.MoveAllocaIntoEntry &&
7199 (!Size.has_value() ||
7200 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7201 AI.MoveAllocaIntoEntry = false;
7202 }
7203
7204 return Changed;
7205}
7206} // namespace
7207
7208/// ----------------------- Privatizable Pointers ------------------------------
7209namespace {
7210struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7211 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7212 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7213
7214 ChangeStatus indicatePessimisticFixpoint() override {
7215 AAPrivatizablePtr::indicatePessimisticFixpoint();
7216 PrivatizableType = nullptr;
7217 return ChangeStatus::CHANGED;
7218 }
7219
7220 /// Identify the type we can chose for a private copy of the underlying
7221 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7222 /// none.
7223 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7224
7225 /// Return a privatizable type that encloses both T0 and T1.
7226 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7227 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7228 std::optional<Type *> T1) {
7229 if (!T0)
7230 return T1;
7231 if (!T1)
7232 return T0;
7233 if (T0 == T1)
7234 return T0;
7235 return nullptr;
7236 }
7237
7238 std::optional<Type *> getPrivatizableType() const override {
7239 return PrivatizableType;
7240 }
7241
7242 const std::string getAsStr(Attributor *A) const override {
7243 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7244 }
7245
7246protected:
7247 std::optional<Type *> PrivatizableType;
7248};
7249
7250// TODO: Do this for call site arguments (probably also other values) as well.
7251
7252struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7253 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7254 : AAPrivatizablePtrImpl(IRP, A) {}
7255
7256 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7257 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7258 // If this is a byval argument and we know all the call sites (so we can
7259 // rewrite them), there is no need to check them explicitly.
7260 bool UsedAssumedInformation = false;
7262 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7263 /* IgnoreSubsumingPositions */ true);
7264 if (!Attrs.empty() &&
7265 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7266 true, UsedAssumedInformation))
7267 return Attrs[0].getValueAsType();
7268
7269 std::optional<Type *> Ty;
7270 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7271
7272 // Make sure the associated call site argument has the same type at all call
7273 // sites and it is an allocation we know is safe to privatize, for now that
7274 // means we only allow alloca instructions.
7275 // TODO: We can additionally analyze the accesses in the callee to create
7276 // the type from that information instead. That is a little more
7277 // involved and will be done in a follow up patch.
7278 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7279 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7280 // Check if a coresponding argument was found or if it is one not
7281 // associated (which can happen for callback calls).
7282 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7283 return false;
7284
7285 // Check that all call sites agree on a type.
7286 auto *PrivCSArgAA =
7287 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7288 if (!PrivCSArgAA)
7289 return false;
7290 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7291
7292 LLVM_DEBUG({
7293 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7294 if (CSTy && *CSTy)
7295 (*CSTy)->print(dbgs());
7296 else if (CSTy)
7297 dbgs() << "<nullptr>";
7298 else
7299 dbgs() << "<none>";
7300 });
7301
7302 Ty = combineTypes(Ty, CSTy);
7303
7304 LLVM_DEBUG({
7305 dbgs() << " : New Type: ";
7306 if (Ty && *Ty)
7307 (*Ty)->print(dbgs());
7308 else if (Ty)
7309 dbgs() << "<nullptr>";
7310 else
7311 dbgs() << "<none>";
7312 dbgs() << "\n";
7313 });
7314
7315 return !Ty || *Ty;
7316 };
7317
7318 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7319 UsedAssumedInformation))
7320 return nullptr;
7321 return Ty;
7322 }
7323
7324 /// See AbstractAttribute::updateImpl(...).
7325 ChangeStatus updateImpl(Attributor &A) override {
7326 PrivatizableType = identifyPrivatizableType(A);
7327 if (!PrivatizableType)
7328 return ChangeStatus::UNCHANGED;
7329 if (!*PrivatizableType)
7330 return indicatePessimisticFixpoint();
7331
7332 // The dependence is optional so we don't give up once we give up on the
7333 // alignment.
7334 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7335 DepClassTy::OPTIONAL);
7336
7337 // Avoid arguments with padding for now.
7338 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7339 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7340 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7341 return indicatePessimisticFixpoint();
7342 }
7343
7344 // Collect the types that will replace the privatizable type in the function
7345 // signature.
7346 SmallVector<Type *, 16> ReplacementTypes;
7347 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7348
7349 // Verify callee and caller agree on how the promoted argument would be
7350 // passed.
7351 Function &Fn = *getIRPosition().getAnchorScope();
7352 const auto *TTI =
7353 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7354 if (!TTI) {
7355 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7356 << Fn.getName() << "\n");
7357 return indicatePessimisticFixpoint();
7358 }
7359
7360 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7361 CallBase *CB = ACS.getInstruction();
7362 return TTI->areTypesABICompatible(
7363 CB->getCaller(),
7365 ReplacementTypes);
7366 };
7367 bool UsedAssumedInformation = false;
7368 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7369 UsedAssumedInformation)) {
7370 LLVM_DEBUG(
7371 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7372 << Fn.getName() << "\n");
7373 return indicatePessimisticFixpoint();
7374 }
7375
7376 // Register a rewrite of the argument.
7377 Argument *Arg = getAssociatedArgument();
7378 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7379 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7380 return indicatePessimisticFixpoint();
7381 }
7382
7383 unsigned ArgNo = Arg->getArgNo();
7384
7385 // Helper to check if for the given call site the associated argument is
7386 // passed to a callback where the privatization would be different.
7387 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7388 SmallVector<const Use *, 4> CallbackUses;
7389 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7390 for (const Use *U : CallbackUses) {
7391 AbstractCallSite CBACS(U);
7392 assert(CBACS && CBACS.isCallbackCall());
7393 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7394 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7395
7396 LLVM_DEBUG({
7397 dbgs()
7398 << "[AAPrivatizablePtr] Argument " << *Arg
7399 << "check if can be privatized in the context of its parent ("
7400 << Arg->getParent()->getName()
7401 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7402 "callback ("
7403 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7404 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7405 << CBACS.getCallArgOperand(CBArg) << " vs "
7406 << CB.getArgOperand(ArgNo) << "\n"
7407 << "[AAPrivatizablePtr] " << CBArg << " : "
7408 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7409 });
7410
7411 if (CBArgNo != int(ArgNo))
7412 continue;
7413 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7414 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7415 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7416 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7417 if (!CBArgPrivTy)
7418 continue;
7419 if (*CBArgPrivTy == PrivatizableType)
7420 continue;
7421 }
7422
7423 LLVM_DEBUG({
7424 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7425 << " cannot be privatized in the context of its parent ("
7426 << Arg->getParent()->getName()
7427 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7428 "callback ("
7429 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7430 << ").\n[AAPrivatizablePtr] for which the argument "
7431 "privatization is not compatible.\n";
7432 });
7433 return false;
7434 }
7435 }
7436 return true;
7437 };
7438
7439 // Helper to check if for the given call site the associated argument is
7440 // passed to a direct call where the privatization would be different.
7441 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7442 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7443 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7444 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7445 "Expected a direct call operand for callback call operand");
7446
7447 Function *DCCallee =
7449 LLVM_DEBUG({
7450 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7451 << " check if be privatized in the context of its parent ("
7452 << Arg->getParent()->getName()
7453 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7454 "direct call of ("
7455 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7456 });
7457
7458 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7459 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7460 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7461 DepClassTy::REQUIRED);
7462 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7463 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7464 if (!DCArgPrivTy)
7465 return true;
7466 if (*DCArgPrivTy == PrivatizableType)
7467 return true;
7468 }
7469 }
7470
7471 LLVM_DEBUG({
7472 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7473 << " cannot be privatized in the context of its parent ("
7474 << Arg->getParent()->getName()
7475 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7476 "direct call of ("
7478 << ").\n[AAPrivatizablePtr] for which the argument "
7479 "privatization is not compatible.\n";
7480 });
7481 return false;
7482 };
7483
7484 // Helper to check if the associated argument is used at the given abstract
7485 // call site in a way that is incompatible with the privatization assumed
7486 // here.
7487 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7488 if (ACS.isDirectCall())
7489 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7490 if (ACS.isCallbackCall())
7491 return IsCompatiblePrivArgOfDirectCS(ACS);
7492 return false;
7493 };
7494
7495 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7496 UsedAssumedInformation))
7497 return indicatePessimisticFixpoint();
7498
7499 return ChangeStatus::UNCHANGED;
7500 }
7501
7502 /// Given a type to private \p PrivType, collect the constituates (which are
7503 /// used) in \p ReplacementTypes.
7504 static void
7505 identifyReplacementTypes(Type *PrivType,
7506 SmallVectorImpl<Type *> &ReplacementTypes) {
7507 // TODO: For now we expand the privatization type to the fullest which can
7508 // lead to dead arguments that need to be removed later.
7509 assert(PrivType && "Expected privatizable type!");
7510
7511 // Traverse the type, extract constituate types on the outermost level.
7512 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7513 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7514 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7515 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7516 ReplacementTypes.append(PrivArrayType->getNumElements(),
7517 PrivArrayType->getElementType());
7518 } else {
7519 ReplacementTypes.push_back(PrivType);
7520 }
7521 }
7522
7523 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7524 /// The values needed are taken from the arguments of \p F starting at
7525 /// position \p ArgNo.
7526 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7527 unsigned ArgNo, BasicBlock::iterator IP) {
7528 assert(PrivType && "Expected privatizable type!");
7529
7530 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7531 const DataLayout &DL = F.getDataLayout();
7532
7533 // Traverse the type, build GEPs and stores.
7534 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7535 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7536 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7537 Value *Ptr =
7538 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7539 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7540 }
7541 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7542 Type *PointeeTy = PrivArrayType->getElementType();
7543 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7544 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7545 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7546 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7547 }
7548 } else {
7549 new StoreInst(F.getArg(ArgNo), &Base, IP);
7550 }
7551 }
7552
7553 /// Extract values from \p Base according to the type \p PrivType at the
7554 /// call position \p ACS. The values are appended to \p ReplacementValues.
7555 void createReplacementValues(Align Alignment, Type *PrivType,
7556 AbstractCallSite ACS, Value *Base,
7557 SmallVectorImpl<Value *> &ReplacementValues) {
7558 assert(Base && "Expected base value!");
7559 assert(PrivType && "Expected privatizable type!");
7560 Instruction *IP = ACS.getInstruction();
7561
7562 IRBuilder<NoFolder> IRB(IP);
7563 const DataLayout &DL = IP->getDataLayout();
7564
7565 // Traverse the type, build GEPs and loads.
7566 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7567 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7568 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7569 Type *PointeeTy = PrivStructType->getElementType(u);
7570 Value *Ptr =
7571 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7572 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7573 L->setAlignment(Alignment);
7574 ReplacementValues.push_back(L);
7575 }
7576 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7577 Type *PointeeTy = PrivArrayType->getElementType();
7578 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7579 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7580 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7581 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7582 L->setAlignment(Alignment);
7583 ReplacementValues.push_back(L);
7584 }
7585 } else {
7586 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7587 L->setAlignment(Alignment);
7588 ReplacementValues.push_back(L);
7589 }
7590 }
7591
7592 /// See AbstractAttribute::manifest(...)
7593 ChangeStatus manifest(Attributor &A) override {
7594 if (!PrivatizableType)
7595 return ChangeStatus::UNCHANGED;
7596 assert(*PrivatizableType && "Expected privatizable type!");
7597
7598 // Collect all tail calls in the function as we cannot allow new allocas to
7599 // escape into tail recursion.
7600 // TODO: Be smarter about new allocas escaping into tail calls.
7602 bool UsedAssumedInformation = false;
7603 if (!A.checkForAllInstructions(
7604 [&](Instruction &I) {
7605 CallInst &CI = cast<CallInst>(I);
7606 if (CI.isTailCall())
7607 TailCalls.push_back(&CI);
7608 return true;
7609 },
7610 *this, {Instruction::Call}, UsedAssumedInformation))
7611 return ChangeStatus::UNCHANGED;
7612
7613 Argument *Arg = getAssociatedArgument();
7614 // Query AAAlign attribute for alignment of associated argument to
7615 // determine the best alignment of loads.
7616 const auto *AlignAA =
7617 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7618
7619 // Callback to repair the associated function. A new alloca is placed at the
7620 // beginning and initialized with the values passed through arguments. The
7621 // new alloca replaces the use of the old pointer argument.
7623 [=](const Attributor::ArgumentReplacementInfo &ARI,
7624 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7625 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7627 const DataLayout &DL = IP->getDataLayout();
7628 unsigned AS = DL.getAllocaAddrSpace();
7629 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7630 Arg->getName() + ".priv", IP);
7631 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7632 ArgIt->getArgNo(), IP);
7633
7634 if (AI->getType() != Arg->getType())
7635 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7636 AI, Arg->getType(), "", IP);
7637 Arg->replaceAllUsesWith(AI);
7638
7639 for (CallInst *CI : TailCalls)
7640 CI->setTailCall(false);
7641 };
7642
7643 // Callback to repair a call site of the associated function. The elements
7644 // of the privatizable type are loaded prior to the call and passed to the
7645 // new function version.
7647 [=](const Attributor::ArgumentReplacementInfo &ARI,
7648 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7649 // When no alignment is specified for the load instruction,
7650 // natural alignment is assumed.
7651 createReplacementValues(
7652 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7653 *PrivatizableType, ACS,
7654 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7655 NewArgOperands);
7656 };
7657
7658 // Collect the types that will replace the privatizable type in the function
7659 // signature.
7660 SmallVector<Type *, 16> ReplacementTypes;
7661 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7662
7663 // Register a rewrite of the argument.
7664 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7665 std::move(FnRepairCB),
7666 std::move(ACSRepairCB)))
7667 return ChangeStatus::CHANGED;
7668 return ChangeStatus::UNCHANGED;
7669 }
7670
7671 /// See AbstractAttribute::trackStatistics()
7672 void trackStatistics() const override {
7673 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7674 }
7675};
7676
7677struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7678 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7679 : AAPrivatizablePtrImpl(IRP, A) {}
7680
7681 /// See AbstractAttribute::initialize(...).
7682 void initialize(Attributor &A) override {
7683 // TODO: We can privatize more than arguments.
7684 indicatePessimisticFixpoint();
7685 }
7686
7687 ChangeStatus updateImpl(Attributor &A) override {
7688 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7689 "updateImpl will not be called");
7690 }
7691
7692 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7693 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7694 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7695 if (!Obj) {
7696 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7697 return nullptr;
7698 }
7699
7700 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7701 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7702 if (CI->isOne())
7703 return AI->getAllocatedType();
7704 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7705 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7706 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7707 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7708 return PrivArgAA->getPrivatizableType();
7709 }
7710
7711 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7712 "alloca nor privatizable argument: "
7713 << *Obj << "!\n");
7714 return nullptr;
7715 }
7716
7717 /// See AbstractAttribute::trackStatistics()
7718 void trackStatistics() const override {
7719 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7720 }
7721};
7722
7723struct AAPrivatizablePtrCallSiteArgument final
7724 : public AAPrivatizablePtrFloating {
7725 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7726 : AAPrivatizablePtrFloating(IRP, A) {}
7727
7728 /// See AbstractAttribute::initialize(...).
7729 void initialize(Attributor &A) override {
7730 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7731 indicateOptimisticFixpoint();
7732 }
7733
7734 /// See AbstractAttribute::updateImpl(...).
7735 ChangeStatus updateImpl(Attributor &A) override {
7736 PrivatizableType = identifyPrivatizableType(A);
7737 if (!PrivatizableType)
7738 return ChangeStatus::UNCHANGED;
7739 if (!*PrivatizableType)
7740 return indicatePessimisticFixpoint();
7741
7742 const IRPosition &IRP = getIRPosition();
7743 bool IsKnownNoCapture;
7744 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7745 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7746 if (!IsAssumedNoCapture) {
7747 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7748 return indicatePessimisticFixpoint();
7749 }
7750
7751 bool IsKnownNoAlias;
7753 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7754 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7755 return indicatePessimisticFixpoint();
7756 }
7757
7758 bool IsKnown;
7759 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7760 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7761 return indicatePessimisticFixpoint();
7762 }
7763
7764 return ChangeStatus::UNCHANGED;
7765 }
7766
7767 /// See AbstractAttribute::trackStatistics()
7768 void trackStatistics() const override {
7769 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7770 }
7771};
7772
7773struct AAPrivatizablePtrCallSiteReturned final
7774 : public AAPrivatizablePtrFloating {
7775 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7776 : AAPrivatizablePtrFloating(IRP, A) {}
7777
7778 /// See AbstractAttribute::initialize(...).
7779 void initialize(Attributor &A) override {
7780 // TODO: We can privatize more than arguments.
7781 indicatePessimisticFixpoint();
7782 }
7783
7784 /// See AbstractAttribute::trackStatistics()
7785 void trackStatistics() const override {
7786 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7787 }
7788};
7789
7790struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7791 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7792 : AAPrivatizablePtrFloating(IRP, A) {}
7793
7794 /// See AbstractAttribute::initialize(...).
7795 void initialize(Attributor &A) override {
7796 // TODO: We can privatize more than arguments.
7797 indicatePessimisticFixpoint();
7798 }
7799
7800 /// See AbstractAttribute::trackStatistics()
7801 void trackStatistics() const override {
7802 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7803 }
7804};
7805} // namespace
7806
7807/// -------------------- Memory Behavior Attributes ----------------------------
7808/// Includes read-none, read-only, and write-only.
7809/// ----------------------------------------------------------------------------
7810namespace {
7811struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7812 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7813 : AAMemoryBehavior(IRP, A) {}
7814
7815 /// See AbstractAttribute::initialize(...).
7816 void initialize(Attributor &A) override {
7817 intersectAssumedBits(BEST_STATE);
7818 getKnownStateFromValue(A, getIRPosition(), getState());
7819 AAMemoryBehavior::initialize(A);
7820 }
7821
7822 /// Return the memory behavior information encoded in the IR for \p IRP.
7823 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7824 BitIntegerState &State,
7825 bool IgnoreSubsumingPositions = false) {
7827 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7828 for (const Attribute &Attr : Attrs) {
7829 switch (Attr.getKindAsEnum()) {
7830 case Attribute::ReadNone:
7831 State.addKnownBits(NO_ACCESSES);
7832 break;
7833 case Attribute::ReadOnly:
7834 State.addKnownBits(NO_WRITES);
7835 break;
7836 case Attribute::WriteOnly:
7837 State.addKnownBits(NO_READS);
7838 break;
7839 default:
7840 llvm_unreachable("Unexpected attribute!");
7841 }
7842 }
7843
7844 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7845 if (!I->mayReadFromMemory())
7846 State.addKnownBits(NO_READS);
7847 if (!I->mayWriteToMemory())
7848 State.addKnownBits(NO_WRITES);
7849 }
7850 }
7851
7852 /// See AbstractAttribute::getDeducedAttributes(...).
7853 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7854 SmallVectorImpl<Attribute> &Attrs) const override {
7855 assert(Attrs.size() == 0);
7856 if (isAssumedReadNone())
7857 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7858 else if (isAssumedReadOnly())
7859 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7860 else if (isAssumedWriteOnly())
7861 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7862 assert(Attrs.size() <= 1);
7863 }
7864
7865 /// See AbstractAttribute::manifest(...).
7866 ChangeStatus manifest(Attributor &A) override {
7867 const IRPosition &IRP = getIRPosition();
7868
7869 if (A.hasAttr(IRP, Attribute::ReadNone,
7870 /* IgnoreSubsumingPositions */ true))
7871 return ChangeStatus::UNCHANGED;
7872
7873 // Check if we would improve the existing attributes first.
7874 SmallVector<Attribute, 4> DeducedAttrs;
7875 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7876 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7877 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7878 /* IgnoreSubsumingPositions */ true);
7879 }))
7880 return ChangeStatus::UNCHANGED;
7881
7882 // Clear existing attributes.
7883 A.removeAttrs(IRP, AttrKinds);
7884 // Clear conflicting writable attribute.
7885 if (isAssumedReadOnly())
7886 A.removeAttrs(IRP, Attribute::Writable);
7887
7888 // Use the generic manifest method.
7889 return IRAttribute::manifest(A);
7890 }
7891
7892 /// See AbstractState::getAsStr().
7893 const std::string getAsStr(Attributor *A) const override {
7894 if (isAssumedReadNone())
7895 return "readnone";
7896 if (isAssumedReadOnly())
7897 return "readonly";
7898 if (isAssumedWriteOnly())
7899 return "writeonly";
7900 return "may-read/write";
7901 }
7902
7903 /// The set of IR attributes AAMemoryBehavior deals with.
7904 static const Attribute::AttrKind AttrKinds[3];
7905};
7906
7907const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7908 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7909
7910/// Memory behavior attribute for a floating value.
7911struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7912 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7913 : AAMemoryBehaviorImpl(IRP, A) {}
7914
7915 /// See AbstractAttribute::updateImpl(...).
7916 ChangeStatus updateImpl(Attributor &A) override;
7917
7918 /// See AbstractAttribute::trackStatistics()
7919 void trackStatistics() const override {
7920 if (isAssumedReadNone())
7922 else if (isAssumedReadOnly())
7924 else if (isAssumedWriteOnly())
7926 }
7927
7928private:
7929 /// Return true if users of \p UserI might access the underlying
7930 /// variable/location described by \p U and should therefore be analyzed.
7931 bool followUsersOfUseIn(Attributor &A, const Use &U,
7932 const Instruction *UserI);
7933
7934 /// Update the state according to the effect of use \p U in \p UserI.
7935 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7936};
7937
7938/// Memory behavior attribute for function argument.
7939struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7940 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
7941 : AAMemoryBehaviorFloating(IRP, A) {}
7942
7943 /// See AbstractAttribute::initialize(...).
7944 void initialize(Attributor &A) override {
7945 intersectAssumedBits(BEST_STATE);
7946 const IRPosition &IRP = getIRPosition();
7947 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7948 // can query it when we use has/getAttr. That would allow us to reuse the
7949 // initialize of the base class here.
7950 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
7951 /* IgnoreSubsumingPositions */ true);
7952 getKnownStateFromValue(A, IRP, getState(),
7953 /* IgnoreSubsumingPositions */ HasByVal);
7954 }
7955
7956 ChangeStatus manifest(Attributor &A) override {
7957 // TODO: Pointer arguments are not supported on vectors of pointers yet.
7958 if (!getAssociatedValue().getType()->isPointerTy())
7959 return ChangeStatus::UNCHANGED;
7960
7961 // TODO: From readattrs.ll: "inalloca parameters are always
7962 // considered written"
7963 if (A.hasAttr(getIRPosition(),
7964 {Attribute::InAlloca, Attribute::Preallocated})) {
7965 removeKnownBits(NO_WRITES);
7966 removeAssumedBits(NO_WRITES);
7967 }
7968 A.removeAttrs(getIRPosition(), AttrKinds);
7969 return AAMemoryBehaviorFloating::manifest(A);
7970 }
7971
7972 /// See AbstractAttribute::trackStatistics()
7973 void trackStatistics() const override {
7974 if (isAssumedReadNone())
7975 STATS_DECLTRACK_ARG_ATTR(readnone)
7976 else if (isAssumedReadOnly())
7977 STATS_DECLTRACK_ARG_ATTR(readonly)
7978 else if (isAssumedWriteOnly())
7979 STATS_DECLTRACK_ARG_ATTR(writeonly)
7980 }
7981};
7982
7983struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
7984 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
7985 : AAMemoryBehaviorArgument(IRP, A) {}
7986
7987 /// See AbstractAttribute::initialize(...).
7988 void initialize(Attributor &A) override {
7989 // If we don't have an associated attribute this is either a variadic call
7990 // or an indirect call, either way, nothing to do here.
7991 Argument *Arg = getAssociatedArgument();
7992 if (!Arg) {
7993 indicatePessimisticFixpoint();
7994 return;
7995 }
7996 if (Arg->hasByValAttr()) {
7997 addKnownBits(NO_WRITES);
7998 removeKnownBits(NO_READS);
7999 removeAssumedBits(NO_READS);
8000 }
8001 AAMemoryBehaviorArgument::initialize(A);
8002 if (getAssociatedFunction()->isDeclaration())
8003 indicatePessimisticFixpoint();
8004 }
8005
8006 /// See AbstractAttribute::updateImpl(...).
8007 ChangeStatus updateImpl(Attributor &A) override {
8008 // TODO: Once we have call site specific value information we can provide
8009 // call site specific liveness liveness information and then it makes
8010 // sense to specialize attributes for call sites arguments instead of
8011 // redirecting requests to the callee argument.
8012 Argument *Arg = getAssociatedArgument();
8013 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8014 auto *ArgAA =
8015 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8016 if (!ArgAA)
8017 return indicatePessimisticFixpoint();
8018 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8019 }
8020
8021 /// See AbstractAttribute::trackStatistics()
8022 void trackStatistics() const override {
8023 if (isAssumedReadNone())
8025 else if (isAssumedReadOnly())
8027 else if (isAssumedWriteOnly())
8029 }
8030};
8031
8032/// Memory behavior attribute for a call site return position.
8033struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8034 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8035 : AAMemoryBehaviorFloating(IRP, A) {}
8036
8037 /// See AbstractAttribute::initialize(...).
8038 void initialize(Attributor &A) override {
8039 AAMemoryBehaviorImpl::initialize(A);
8040 }
8041 /// See AbstractAttribute::manifest(...).
8042 ChangeStatus manifest(Attributor &A) override {
8043 // We do not annotate returned values.
8044 return ChangeStatus::UNCHANGED;
8045 }
8046
8047 /// See AbstractAttribute::trackStatistics()
8048 void trackStatistics() const override {}
8049};
8050
8051/// An AA to represent the memory behavior function attributes.
8052struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8053 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8054 : AAMemoryBehaviorImpl(IRP, A) {}
8055
8056 /// See AbstractAttribute::updateImpl(Attributor &A).
8057 ChangeStatus updateImpl(Attributor &A) override;
8058
8059 /// See AbstractAttribute::manifest(...).
8060 ChangeStatus manifest(Attributor &A) override {
8061 // TODO: It would be better to merge this with AAMemoryLocation, so that
8062 // we could determine read/write per location. This would also have the
8063 // benefit of only one place trying to manifest the memory attribute.
8064 Function &F = cast<Function>(getAnchorValue());
8066 if (isAssumedReadNone())
8067 ME = MemoryEffects::none();
8068 else if (isAssumedReadOnly())
8070 else if (isAssumedWriteOnly())
8072
8073 A.removeAttrs(getIRPosition(), AttrKinds);
8074 // Clear conflicting writable attribute.
8075 if (ME.onlyReadsMemory())
8076 for (Argument &Arg : F.args())
8077 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8078 return A.manifestAttrs(getIRPosition(),
8079 Attribute::getWithMemoryEffects(F.getContext(), ME));
8080 }
8081
8082 /// See AbstractAttribute::trackStatistics()
8083 void trackStatistics() const override {
8084 if (isAssumedReadNone())
8085 STATS_DECLTRACK_FN_ATTR(readnone)
8086 else if (isAssumedReadOnly())
8087 STATS_DECLTRACK_FN_ATTR(readonly)
8088 else if (isAssumedWriteOnly())
8089 STATS_DECLTRACK_FN_ATTR(writeonly)
8090 }
8091};
8092
8093/// AAMemoryBehavior attribute for call sites.
8094struct AAMemoryBehaviorCallSite final
8095 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8096 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8097 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8098
8099 /// See AbstractAttribute::manifest(...).
8100 ChangeStatus manifest(Attributor &A) override {
8101 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8102 CallBase &CB = cast<CallBase>(getAnchorValue());
8104 if (isAssumedReadNone())
8105 ME = MemoryEffects::none();
8106 else if (isAssumedReadOnly())
8108 else if (isAssumedWriteOnly())
8110
8111 A.removeAttrs(getIRPosition(), AttrKinds);
8112 // Clear conflicting writable attribute.
8113 if (ME.onlyReadsMemory())
8114 for (Use &U : CB.args())
8115 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8116 Attribute::Writable);
8117 return A.manifestAttrs(
8118 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8119 }
8120
8121 /// See AbstractAttribute::trackStatistics()
8122 void trackStatistics() const override {
8123 if (isAssumedReadNone())
8124 STATS_DECLTRACK_CS_ATTR(readnone)
8125 else if (isAssumedReadOnly())
8126 STATS_DECLTRACK_CS_ATTR(readonly)
8127 else if (isAssumedWriteOnly())
8128 STATS_DECLTRACK_CS_ATTR(writeonly)
8129 }
8130};
8131
8132ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8133
8134 // The current assumed state used to determine a change.
8135 auto AssumedState = getAssumed();
8136
8137 auto CheckRWInst = [&](Instruction &I) {
8138 // If the instruction has an own memory behavior state, use it to restrict
8139 // the local state. No further analysis is required as the other memory
8140 // state is as optimistic as it gets.
8141 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8142 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8144 if (MemBehaviorAA) {
8145 intersectAssumedBits(MemBehaviorAA->getAssumed());
8146 return !isAtFixpoint();
8147 }
8148 }
8149
8150 // Remove access kind modifiers if necessary.
8151 if (I.mayReadFromMemory())
8152 removeAssumedBits(NO_READS);
8153 if (I.mayWriteToMemory())
8154 removeAssumedBits(NO_WRITES);
8155 return !isAtFixpoint();
8156 };
8157
8158 bool UsedAssumedInformation = false;
8159 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8160 UsedAssumedInformation))
8161 return indicatePessimisticFixpoint();
8162
8163 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8165}
8166
8167ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8168
8169 const IRPosition &IRP = getIRPosition();
8170 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8171 AAMemoryBehavior::StateType &S = getState();
8172
8173 // First, check the function scope. We take the known information and we avoid
8174 // work if the assumed information implies the current assumed information for
8175 // this attribute. This is a valid for all but byval arguments.
8176 Argument *Arg = IRP.getAssociatedArgument();
8177 AAMemoryBehavior::base_t FnMemAssumedState =
8179 if (!Arg || !Arg->hasByValAttr()) {
8180 const auto *FnMemAA =
8181 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8182 if (FnMemAA) {
8183 FnMemAssumedState = FnMemAA->getAssumed();
8184 S.addKnownBits(FnMemAA->getKnown());
8185 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8187 }
8188 }
8189
8190 // The current assumed state used to determine a change.
8191 auto AssumedState = S.getAssumed();
8192
8193 // Make sure the value is not captured (except through "return"), if
8194 // it is, any information derived would be irrelevant anyway as we cannot
8195 // check the potential aliases introduced by the capture. However, no need
8196 // to fall back to anythign less optimistic than the function state.
8197 bool IsKnownNoCapture;
8198 const AANoCapture *ArgNoCaptureAA = nullptr;
8199 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8200 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8201 &ArgNoCaptureAA);
8202
8203 if (!IsAssumedNoCapture &&
8204 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8205 S.intersectAssumedBits(FnMemAssumedState);
8206 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8208 }
8209
8210 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8211 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8212 Instruction *UserI = cast<Instruction>(U.getUser());
8213 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8214 << " \n");
8215
8216 // Droppable users, e.g., llvm::assume does not actually perform any action.
8217 if (UserI->isDroppable())
8218 return true;
8219
8220 // Check if the users of UserI should also be visited.
8221 Follow = followUsersOfUseIn(A, U, UserI);
8222
8223 // If UserI might touch memory we analyze the use in detail.
8224 if (UserI->mayReadOrWriteMemory())
8225 analyzeUseIn(A, U, UserI);
8226
8227 return !isAtFixpoint();
8228 };
8229
8230 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8231 return indicatePessimisticFixpoint();
8232
8233 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8235}
8236
8237bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8238 const Instruction *UserI) {
8239 // The loaded value is unrelated to the pointer argument, no need to
8240 // follow the users of the load.
8241 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8242 return false;
8243
8244 // By default we follow all uses assuming UserI might leak information on U,
8245 // we have special handling for call sites operands though.
8246 const auto *CB = dyn_cast<CallBase>(UserI);
8247 if (!CB || !CB->isArgOperand(&U))
8248 return true;
8249
8250 // If the use is a call argument known not to be captured, the users of
8251 // the call do not need to be visited because they have to be unrelated to
8252 // the input. Note that this check is not trivial even though we disallow
8253 // general capturing of the underlying argument. The reason is that the
8254 // call might the argument "through return", which we allow and for which we
8255 // need to check call users.
8256 if (U.get()->getType()->isPointerTy()) {
8257 unsigned ArgNo = CB->getArgOperandNo(&U);
8258 bool IsKnownNoCapture;
8260 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8261 DepClassTy::OPTIONAL, IsKnownNoCapture);
8262 }
8263
8264 return true;
8265}
8266
8267void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8268 const Instruction *UserI) {
8269 assert(UserI->mayReadOrWriteMemory());
8270
8271 switch (UserI->getOpcode()) {
8272 default:
8273 // TODO: Handle all atomics and other side-effect operations we know of.
8274 break;
8275 case Instruction::Load:
8276 // Loads cause the NO_READS property to disappear.
8277 removeAssumedBits(NO_READS);
8278 return;
8279
8280 case Instruction::Store:
8281 // Stores cause the NO_WRITES property to disappear if the use is the
8282 // pointer operand. Note that while capturing was taken care of somewhere
8283 // else we need to deal with stores of the value that is not looked through.
8284 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8285 removeAssumedBits(NO_WRITES);
8286 else
8287 indicatePessimisticFixpoint();
8288 return;
8289
8290 case Instruction::Call:
8291 case Instruction::CallBr:
8292 case Instruction::Invoke: {
8293 // For call sites we look at the argument memory behavior attribute (this
8294 // could be recursive!) in order to restrict our own state.
8295 const auto *CB = cast<CallBase>(UserI);
8296
8297 // Give up on operand bundles.
8298 if (CB->isBundleOperand(&U)) {
8299 indicatePessimisticFixpoint();
8300 return;
8301 }
8302
8303 // Calling a function does read the function pointer, maybe write it if the
8304 // function is self-modifying.
8305 if (CB->isCallee(&U)) {
8306 removeAssumedBits(NO_READS);
8307 break;
8308 }
8309
8310 // Adjust the possible access behavior based on the information on the
8311 // argument.
8312 IRPosition Pos;
8313 if (U.get()->getType()->isPointerTy())
8315 else
8317 const auto *MemBehaviorAA =
8318 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8319 if (!MemBehaviorAA)
8320 break;
8321 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8322 // and at least "known".
8323 intersectAssumedBits(MemBehaviorAA->getAssumed());
8324 return;
8325 }
8326 };
8327
8328 // Generally, look at the "may-properties" and adjust the assumed state if we
8329 // did not trigger special handling before.
8330 if (UserI->mayReadFromMemory())
8331 removeAssumedBits(NO_READS);
8332 if (UserI->mayWriteToMemory())
8333 removeAssumedBits(NO_WRITES);
8334}
8335} // namespace
8336
8337/// -------------------- Memory Locations Attributes ---------------------------
8338/// Includes read-none, argmemonly, inaccessiblememonly,
8339/// inaccessiblememorargmemonly
8340/// ----------------------------------------------------------------------------
8341
8344 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8345 return "all memory";
8347 return "no memory";
8348 std::string S = "memory:";
8349 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8350 S += "stack,";
8351 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8352 S += "constant,";
8354 S += "internal global,";
8356 S += "external global,";
8357 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8358 S += "argument,";
8360 S += "inaccessible,";
8361 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8362 S += "malloced,";
8363 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8364 S += "unknown,";
8365 S.pop_back();
8366 return S;
8367}
8368
8369namespace {
8370struct AAMemoryLocationImpl : public AAMemoryLocation {
8371
8372 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8373 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8374 AccessKind2Accesses.fill(nullptr);
8375 }
8376
8377 ~AAMemoryLocationImpl() {
8378 // The AccessSets are allocated via a BumpPtrAllocator, we call
8379 // the destructor manually.
8380 for (AccessSet *AS : AccessKind2Accesses)
8381 if (AS)
8382 AS->~AccessSet();
8383 }
8384
8385 /// See AbstractAttribute::initialize(...).
8386 void initialize(Attributor &A) override {
8387 intersectAssumedBits(BEST_STATE);
8388 getKnownStateFromValue(A, getIRPosition(), getState());
8389 AAMemoryLocation::initialize(A);
8390 }
8391
8392 /// Return the memory behavior information encoded in the IR for \p IRP.
8393 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8394 BitIntegerState &State,
8395 bool IgnoreSubsumingPositions = false) {
8396 // For internal functions we ignore `argmemonly` and
8397 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8398 // constant propagation. It is unclear if this is the best way but it is
8399 // unlikely this will cause real performance problems. If we are deriving
8400 // attributes for the anchor function we even remove the attribute in
8401 // addition to ignoring it.
8402 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8403 // MemoryEffects::Other as a possible location.
8404 bool UseArgMemOnly = true;
8405 Function *AnchorFn = IRP.getAnchorScope();
8406 if (AnchorFn && A.isRunOn(*AnchorFn))
8407 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8408
8410 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8411 for (const Attribute &Attr : Attrs) {
8412 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8413 MemoryEffects ME = Attr.getMemoryEffects();
8414 if (ME.doesNotAccessMemory()) {
8415 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8416 continue;
8417 }
8418 if (ME.onlyAccessesInaccessibleMem()) {
8419 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8420 continue;
8421 }
8422 if (ME.onlyAccessesArgPointees()) {
8423 if (UseArgMemOnly)
8424 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8425 else {
8426 // Remove location information, only keep read/write info.
8427 ME = MemoryEffects(ME.getModRef());
8428 A.manifestAttrs(IRP,
8429 Attribute::getWithMemoryEffects(
8430 IRP.getAnchorValue().getContext(), ME),
8431 /*ForceReplace*/ true);
8432 }
8433 continue;
8434 }
8436 if (UseArgMemOnly)
8437 State.addKnownBits(inverseLocation(
8438 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8439 else {
8440 // Remove location information, only keep read/write info.
8441 ME = MemoryEffects(ME.getModRef());
8442 A.manifestAttrs(IRP,
8443 Attribute::getWithMemoryEffects(
8444 IRP.getAnchorValue().getContext(), ME),
8445 /*ForceReplace*/ true);
8446 }
8447 continue;
8448 }
8449 }
8450 }
8451
8452 /// See AbstractAttribute::getDeducedAttributes(...).
8453 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8454 SmallVectorImpl<Attribute> &Attrs) const override {
8455 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8456 assert(Attrs.size() == 0);
8457 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8458 if (isAssumedReadNone())
8459 Attrs.push_back(
8460 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8461 else if (isAssumedInaccessibleMemOnly())
8462 Attrs.push_back(Attribute::getWithMemoryEffects(
8464 else if (isAssumedArgMemOnly())
8465 Attrs.push_back(
8466 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8467 else if (isAssumedInaccessibleOrArgMemOnly())
8468 Attrs.push_back(Attribute::getWithMemoryEffects(
8470 }
8471 assert(Attrs.size() <= 1);
8472 }
8473
8474 /// See AbstractAttribute::manifest(...).
8475 ChangeStatus manifest(Attributor &A) override {
8476 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8477 // provide per-location modref information here.
8478 const IRPosition &IRP = getIRPosition();
8479
8480 SmallVector<Attribute, 1> DeducedAttrs;
8481 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8482 if (DeducedAttrs.size() != 1)
8483 return ChangeStatus::UNCHANGED;
8484 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8485
8486 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8487 IRP.getAnchorValue().getContext(), ME));
8488 }
8489
8490 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8491 bool checkForAllAccessesToMemoryKind(
8492 function_ref<bool(const Instruction *, const Value *, AccessKind,
8493 MemoryLocationsKind)>
8494 Pred,
8495 MemoryLocationsKind RequestedMLK) const override {
8496 if (!isValidState())
8497 return false;
8498
8499 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8500 if (AssumedMLK == NO_LOCATIONS)
8501 return true;
8502
8503 unsigned Idx = 0;
8504 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8505 CurMLK *= 2, ++Idx) {
8506 if (CurMLK & RequestedMLK)
8507 continue;
8508
8509 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8510 for (const AccessInfo &AI : *Accesses)
8511 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8512 return false;
8513 }
8514
8515 return true;
8516 }
8517
8518 ChangeStatus indicatePessimisticFixpoint() override {
8519 // If we give up and indicate a pessimistic fixpoint this instruction will
8520 // become an access for all potential access kinds:
8521 // TODO: Add pointers for argmemonly and globals to improve the results of
8522 // checkForAllAccessesToMemoryKind.
8523 bool Changed = false;
8524 MemoryLocationsKind KnownMLK = getKnown();
8525 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8526 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8527 if (!(CurMLK & KnownMLK))
8528 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8529 getAccessKindFromInst(I));
8530 return AAMemoryLocation::indicatePessimisticFixpoint();
8531 }
8532
8533protected:
8534 /// Helper struct to tie together an instruction that has a read or write
8535 /// effect with the pointer it accesses (if any).
8536 struct AccessInfo {
8537
8538 /// The instruction that caused the access.
8539 const Instruction *I;
8540
8541 /// The base pointer that is accessed, or null if unknown.
8542 const Value *Ptr;
8543
8544 /// The kind of access (read/write/read+write).
8546
8547 bool operator==(const AccessInfo &RHS) const {
8548 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8549 }
8550 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8551 if (LHS.I != RHS.I)
8552 return LHS.I < RHS.I;
8553 if (LHS.Ptr != RHS.Ptr)
8554 return LHS.Ptr < RHS.Ptr;
8555 if (LHS.Kind != RHS.Kind)
8556 return LHS.Kind < RHS.Kind;
8557 return false;
8558 }
8559 };
8560
8561 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8562 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8563 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8564 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8565 AccessKind2Accesses;
8566
8567 /// Categorize the pointer arguments of CB that might access memory in
8568 /// AccessedLoc and update the state and access map accordingly.
8569 void
8570 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8571 AAMemoryLocation::StateType &AccessedLocs,
8572 bool &Changed);
8573
8574 /// Return the kind(s) of location that may be accessed by \p V.
8576 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8577
8578 /// Return the access kind as determined by \p I.
8579 AccessKind getAccessKindFromInst(const Instruction *I) {
8580 AccessKind AK = READ_WRITE;
8581 if (I) {
8582 AK = I->mayReadFromMemory() ? READ : NONE;
8583 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8584 }
8585 return AK;
8586 }
8587
8588 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8589 /// an access of kind \p AK to a \p MLK memory location with the access
8590 /// pointer \p Ptr.
8591 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8592 MemoryLocationsKind MLK, const Instruction *I,
8593 const Value *Ptr, bool &Changed,
8594 AccessKind AK = READ_WRITE) {
8595
8596 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8597 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8598 if (!Accesses)
8599 Accesses = new (Allocator) AccessSet();
8600 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8601 if (MLK == NO_UNKOWN_MEM)
8602 MLK = NO_LOCATIONS;
8603 State.removeAssumedBits(MLK);
8604 }
8605
8606 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8607 /// arguments, and update the state and access map accordingly.
8608 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8609 AAMemoryLocation::StateType &State, bool &Changed,
8610 unsigned AccessAS = 0);
8611
8612 /// Used to allocate access sets.
8614};
8615
8616void AAMemoryLocationImpl::categorizePtrValue(
8617 Attributor &A, const Instruction &I, const Value &Ptr,
8618 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8619 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8620 << Ptr << " ["
8621 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8622
8623 auto Pred = [&](Value &Obj) {
8624 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8625 // TODO: recognize the TBAA used for constant accesses.
8626 MemoryLocationsKind MLK = NO_LOCATIONS;
8627
8628 // Filter accesses to constant (GPU) memory if we have an AS at the access
8629 // site or the object is known to actually have the associated AS.
8630 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8631 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8632 isIdentifiedObject(&Obj))) &&
8633 AA::isGPU(*I.getModule()))
8634 return true;
8635
8636 if (isa<UndefValue>(&Obj))
8637 return true;
8638 if (isa<Argument>(&Obj)) {
8639 // TODO: For now we do not treat byval arguments as local copies performed
8640 // on the call edge, though, we should. To make that happen we need to
8641 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8642 // would also allow us to mark functions only accessing byval arguments as
8643 // readnone again, arguably their accesses have no effect outside of the
8644 // function, like accesses to allocas.
8645 MLK = NO_ARGUMENT_MEM;
8646 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8647 // Reading constant memory is not treated as a read "effect" by the
8648 // function attr pass so we won't neither. Constants defined by TBAA are
8649 // similar. (We know we do not write it because it is constant.)
8650 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8651 if (GVar->isConstant())
8652 return true;
8653
8654 if (GV->hasLocalLinkage())
8655 MLK = NO_GLOBAL_INTERNAL_MEM;
8656 else
8657 MLK = NO_GLOBAL_EXTERNAL_MEM;
8658 } else if (isa<ConstantPointerNull>(&Obj) &&
8659 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8660 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8661 return true;
8662 } else if (isa<AllocaInst>(&Obj)) {
8663 MLK = NO_LOCAL_MEM;
8664 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8665 bool IsKnownNoAlias;
8668 IsKnownNoAlias))
8669 MLK = NO_MALLOCED_MEM;
8670 else
8671 MLK = NO_UNKOWN_MEM;
8672 } else {
8673 MLK = NO_UNKOWN_MEM;
8674 }
8675
8676 assert(MLK != NO_LOCATIONS && "No location specified!");
8677 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8678 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8679 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8680 getAccessKindFromInst(&I));
8681
8682 return true;
8683 };
8684
8685 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8687 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8688 LLVM_DEBUG(
8689 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8690 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8691 getAccessKindFromInst(&I));
8692 return;
8693 }
8694
8695 LLVM_DEBUG(
8696 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8697 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8698}
8699
8700void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8701 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8702 bool &Changed) {
8703 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8704
8705 // Skip non-pointer arguments.
8706 const Value *ArgOp = CB.getArgOperand(ArgNo);
8707 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8708 continue;
8709
8710 // Skip readnone arguments.
8711 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8712 const auto *ArgOpMemLocationAA =
8713 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8714
8715 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8716 continue;
8717
8718 // Categorize potentially accessed pointer arguments as if there was an
8719 // access instruction with them as pointer.
8720 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8721 }
8722}
8723
8725AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8726 bool &Changed) {
8727 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8728 << I << "\n");
8729
8730 AAMemoryLocation::StateType AccessedLocs;
8731 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8732
8733 if (auto *CB = dyn_cast<CallBase>(&I)) {
8734
8735 // First check if we assume any memory is access is visible.
8736 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8738 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8739 << " [" << CBMemLocationAA << "]\n");
8740 if (!CBMemLocationAA) {
8741 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8742 Changed, getAccessKindFromInst(&I));
8743 return NO_UNKOWN_MEM;
8744 }
8745
8746 if (CBMemLocationAA->isAssumedReadNone())
8747 return NO_LOCATIONS;
8748
8749 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8750 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8751 Changed, getAccessKindFromInst(&I));
8752 return AccessedLocs.getAssumed();
8753 }
8754
8755 uint32_t CBAssumedNotAccessedLocs =
8756 CBMemLocationAA->getAssumedNotAccessedLocation();
8757
8758 // Set the argmemonly and global bit as we handle them separately below.
8759 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8760 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8761
8762 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8763 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8764 continue;
8765 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8766 getAccessKindFromInst(&I));
8767 }
8768
8769 // Now handle global memory if it might be accessed. This is slightly tricky
8770 // as NO_GLOBAL_MEM has multiple bits set.
8771 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8772 if (HasGlobalAccesses) {
8773 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8774 AccessKind Kind, MemoryLocationsKind MLK) {
8775 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8776 getAccessKindFromInst(&I));
8777 return true;
8778 };
8779 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8780 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8781 return AccessedLocs.getWorstState();
8782 }
8783
8784 LLVM_DEBUG(
8785 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8786 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8787
8788 // Now handle argument memory if it might be accessed.
8789 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8790 if (HasArgAccesses)
8791 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8792
8793 LLVM_DEBUG(
8794 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8795 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8796
8797 return AccessedLocs.getAssumed();
8798 }
8799
8800 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8801 LLVM_DEBUG(
8802 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8803 << I << " [" << *Ptr << "]\n");
8804 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8805 Ptr->getType()->getPointerAddressSpace());
8806 return AccessedLocs.getAssumed();
8807 }
8808
8809 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8810 << I << "\n");
8811 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8812 getAccessKindFromInst(&I));
8813 return AccessedLocs.getAssumed();
8814}
8815
8816/// An AA to represent the memory behavior function attributes.
8817struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8818 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8819 : AAMemoryLocationImpl(IRP, A) {}
8820
8821 /// See AbstractAttribute::updateImpl(Attributor &A).
8822 ChangeStatus updateImpl(Attributor &A) override {
8823
8824 const auto *MemBehaviorAA =
8825 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8826 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8827 if (MemBehaviorAA->isKnownReadNone())
8828 return indicateOptimisticFixpoint();
8830 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8831 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8832 return ChangeStatus::UNCHANGED;
8833 }
8834
8835 // The current assumed state used to determine a change.
8836 auto AssumedState = getAssumed();
8837 bool Changed = false;
8838
8839 auto CheckRWInst = [&](Instruction &I) {
8840 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8841 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8842 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8843 removeAssumedBits(inverseLocation(MLK, false, false));
8844 // Stop once only the valid bit set in the *not assumed location*, thus
8845 // once we don't actually exclude any memory locations in the state.
8846 return getAssumedNotAccessedLocation() != VALID_STATE;
8847 };
8848
8849 bool UsedAssumedInformation = false;
8850 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8851 UsedAssumedInformation))
8852 return indicatePessimisticFixpoint();
8853
8854 Changed |= AssumedState != getAssumed();
8855 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8856 }
8857
8858 /// See AbstractAttribute::trackStatistics()
8859 void trackStatistics() const override {
8860 if (isAssumedReadNone())
8861 STATS_DECLTRACK_FN_ATTR(readnone)
8862 else if (isAssumedArgMemOnly())
8863 STATS_DECLTRACK_FN_ATTR(argmemonly)
8864 else if (isAssumedInaccessibleMemOnly())
8865 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8866 else if (isAssumedInaccessibleOrArgMemOnly())
8867 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8868 }
8869};
8870
8871/// AAMemoryLocation attribute for call sites.
8872struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8873 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8874 : AAMemoryLocationImpl(IRP, A) {}
8875
8876 /// See AbstractAttribute::updateImpl(...).
8877 ChangeStatus updateImpl(Attributor &A) override {
8878 // TODO: Once we have call site specific value information we can provide
8879 // call site specific liveness liveness information and then it makes
8880 // sense to specialize attributes for call sites arguments instead of
8881 // redirecting requests to the callee argument.
8882 Function *F = getAssociatedFunction();
8883 const IRPosition &FnPos = IRPosition::function(*F);
8884 auto *FnAA =
8885 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8886 if (!FnAA)
8887 return indicatePessimisticFixpoint();
8888 bool Changed = false;
8889 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8890 AccessKind Kind, MemoryLocationsKind MLK) {
8891 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8892 getAccessKindFromInst(I));
8893 return true;
8894 };
8895 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8896 return indicatePessimisticFixpoint();
8897 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8898 }
8899
8900 /// See AbstractAttribute::trackStatistics()
8901 void trackStatistics() const override {
8902 if (isAssumedReadNone())
8903 STATS_DECLTRACK_CS_ATTR(readnone)
8904 }
8905};
8906} // namespace
8907
8908/// ------------------ denormal-fp-math Attribute -------------------------
8909
8910namespace {
8911struct AADenormalFPMathImpl : public AADenormalFPMath {
8912 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8913 : AADenormalFPMath(IRP, A) {}
8914
8915 const std::string getAsStr(Attributor *A) const override {
8916 std::string Str("AADenormalFPMath[");
8917 raw_string_ostream OS(Str);
8918
8919 DenormalState Known = getKnown();
8920 if (Known.Mode.isValid())
8921 OS << "denormal-fp-math=" << Known.Mode;
8922 else
8923 OS << "invalid";
8924
8925 if (Known.ModeF32.isValid())
8926 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8927 OS << ']';
8928 return Str;
8929 }
8930};
8931
8932struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8933 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8934 : AADenormalFPMathImpl(IRP, A) {}
8935
8936 void initialize(Attributor &A) override {
8937 const Function *F = getAnchorScope();
8938 DenormalMode Mode = F->getDenormalModeRaw();
8939 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8940
8941 // TODO: Handling this here prevents handling the case where a callee has a
8942 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8943 // a function with a fully fixed mode.
8944 if (ModeF32 == DenormalMode::getInvalid())
8945 ModeF32 = Mode;
8946 Known = DenormalState{Mode, ModeF32};
8947 if (isModeFixed())
8948 indicateFixpoint();
8949 }
8950
8951 ChangeStatus updateImpl(Attributor &A) override {
8952 ChangeStatus Change = ChangeStatus::UNCHANGED;
8953
8954 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
8955 Function *Caller = CS.getInstruction()->getFunction();
8956 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
8957 << "->" << getAssociatedFunction()->getName() << '\n');
8958
8959 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
8960 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
8961 if (!CallerInfo)
8962 return false;
8963
8964 Change = Change | clampStateAndIndicateChange(this->getState(),
8965 CallerInfo->getState());
8966 return true;
8967 };
8968
8969 bool AllCallSitesKnown = true;
8970 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
8971 return indicatePessimisticFixpoint();
8972
8973 if (Change == ChangeStatus::CHANGED && isModeFixed())
8974 indicateFixpoint();
8975 return Change;
8976 }
8977
8978 ChangeStatus manifest(Attributor &A) override {
8979 LLVMContext &Ctx = getAssociatedFunction()->getContext();
8980
8981 SmallVector<Attribute, 2> AttrToAdd;
8982 SmallVector<StringRef, 2> AttrToRemove;
8983 if (Known.Mode == DenormalMode::getDefault()) {
8984 AttrToRemove.push_back("denormal-fp-math");
8985 } else {
8986 AttrToAdd.push_back(
8987 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
8988 }
8989
8990 if (Known.ModeF32 != Known.Mode) {
8991 AttrToAdd.push_back(
8992 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
8993 } else {
8994 AttrToRemove.push_back("denormal-fp-math-f32");
8995 }
8996
8997 auto &IRP = getIRPosition();
8998
8999 // TODO: There should be a combined add and remove API.
9000 return A.removeAttrs(IRP, AttrToRemove) |
9001 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9002 }
9003
9004 void trackStatistics() const override {
9005 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
9006 }
9007};
9008} // namespace
9009
9010/// ------------------ Value Constant Range Attribute -------------------------
9011
9012namespace {
9013struct AAValueConstantRangeImpl : AAValueConstantRange {
9014 using StateType = IntegerRangeState;
9015 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9016 : AAValueConstantRange(IRP, A) {}
9017
9018 /// See AbstractAttribute::initialize(..).
9019 void initialize(Attributor &A) override {
9020 if (A.hasSimplificationCallback(getIRPosition())) {
9021 indicatePessimisticFixpoint();
9022 return;
9023 }
9024
9025 // Intersect a range given by SCEV.
9026 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9027
9028 // Intersect a range given by LVI.
9029 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9030 }
9031
9032 /// See AbstractAttribute::getAsStr().
9033 const std::string getAsStr(Attributor *A) const override {
9034 std::string Str;
9035 llvm::raw_string_ostream OS(Str);
9036 OS << "range(" << getBitWidth() << ")<";
9037 getKnown().print(OS);
9038 OS << " / ";
9039 getAssumed().print(OS);
9040 OS << ">";
9041 return Str;
9042 }
9043
9044 /// Helper function to get a SCEV expr for the associated value at program
9045 /// point \p I.
9046 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9047 if (!getAnchorScope())
9048 return nullptr;
9049
9050 ScalarEvolution *SE =
9051 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9052 *getAnchorScope());
9053
9054 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9055 *getAnchorScope());
9056
9057 if (!SE || !LI)
9058 return nullptr;
9059
9060 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9061 if (!I)
9062 return S;
9063
9064 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9065 }
9066
9067 /// Helper function to get a range from SCEV for the associated value at
9068 /// program point \p I.
9069 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9070 const Instruction *I = nullptr) const {
9071 if (!getAnchorScope())
9072 return getWorstState(getBitWidth());
9073
9074 ScalarEvolution *SE =
9075 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9076 *getAnchorScope());
9077
9078 const SCEV *S = getSCEV(A, I);
9079 if (!SE || !S)
9080 return getWorstState(getBitWidth());
9081
9082 return SE->getUnsignedRange(S);
9083 }
9084
9085 /// Helper function to get a range from LVI for the associated value at
9086 /// program point \p I.
9087 ConstantRange
9088 getConstantRangeFromLVI(Attributor &A,
9089 const Instruction *CtxI = nullptr) const {
9090 if (!getAnchorScope())
9091 return getWorstState(getBitWidth());
9092
9093 LazyValueInfo *LVI =
9094 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9095 *getAnchorScope());
9096
9097 if (!LVI || !CtxI)
9098 return getWorstState(getBitWidth());
9099 return LVI->getConstantRange(&getAssociatedValue(),
9100 const_cast<Instruction *>(CtxI),
9101 /*UndefAllowed*/ false);
9102 }
9103
9104 /// Return true if \p CtxI is valid for querying outside analyses.
9105 /// This basically makes sure we do not ask intra-procedural analysis
9106 /// about a context in the wrong function or a context that violates
9107 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9108 /// if the original context of this AA is OK or should be considered invalid.
9109 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9110 const Instruction *CtxI,
9111 bool AllowAACtxI) const {
9112 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9113 return false;
9114
9115 // Our context might be in a different function, neither intra-procedural
9116 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9117 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9118 return false;
9119
9120 // If the context is not dominated by the value there are paths to the
9121 // context that do not define the value. This cannot be handled by
9122 // LazyValueInfo so we need to bail.
9123 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9124 InformationCache &InfoCache = A.getInfoCache();
9125 const DominatorTree *DT =
9126 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9127 *I->getFunction());
9128 return DT && DT->dominates(I, CtxI);
9129 }
9130
9131 return true;
9132 }
9133
9134 /// See AAValueConstantRange::getKnownConstantRange(..).
9135 ConstantRange
9136 getKnownConstantRange(Attributor &A,
9137 const Instruction *CtxI = nullptr) const override {
9138 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9139 /* AllowAACtxI */ false))
9140 return getKnown();
9141
9142 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9143 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9144 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9145 }
9146
9147 /// See AAValueConstantRange::getAssumedConstantRange(..).
9148 ConstantRange
9149 getAssumedConstantRange(Attributor &A,
9150 const Instruction *CtxI = nullptr) const override {
9151 // TODO: Make SCEV use Attributor assumption.
9152 // We may be able to bound a variable range via assumptions in
9153 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9154 // evolve to x^2 + x, then we can say that y is in [2, 12].
9155 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9156 /* AllowAACtxI */ false))
9157 return getAssumed();
9158
9159 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9160 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9161 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9162 }
9163
9164 /// Helper function to create MDNode for range metadata.
9165 static MDNode *
9166 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9167 const ConstantRange &AssumedConstantRange) {
9168 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9169 Ty, AssumedConstantRange.getLower())),
9170 ConstantAsMetadata::get(ConstantInt::get(
9171 Ty, AssumedConstantRange.getUpper()))};
9172 return MDNode::get(Ctx, LowAndHigh);
9173 }
9174
9175 /// Return true if \p Assumed is included in ranges from instruction \p I.
9176 static bool isBetterRange(const ConstantRange &Assumed,
9177 const Instruction &I) {
9178 if (Assumed.isFullSet())
9179 return false;
9180
9181 std::optional<ConstantRange> Known;
9182
9183 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9184 Known = CB->getRange();
9185 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9186 // If multiple ranges are annotated in IR, we give up to annotate assumed
9187 // range for now.
9188
9189 // TODO: If there exists a known range which containts assumed range, we
9190 // can say assumed range is better.
9191 if (KnownRanges->getNumOperands() > 2)
9192 return false;
9193
9194 ConstantInt *Lower =
9195 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9196 ConstantInt *Upper =
9197 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9198
9199 Known.emplace(Lower->getValue(), Upper->getValue());
9200 }
9201 return !Known || (*Known != Assumed && Known->contains(Assumed));
9202 }
9203
9204 /// Helper function to set range metadata.
9205 static bool
9206 setRangeMetadataIfisBetterRange(Instruction *I,
9207 const ConstantRange &AssumedConstantRange) {
9208 if (isBetterRange(AssumedConstantRange, *I)) {
9209 I->setMetadata(LLVMContext::MD_range,
9210 getMDNodeForConstantRange(I->getType(), I->getContext(),
9211 AssumedConstantRange));
9212 return true;
9213 }
9214 return false;
9215 }
9216 /// Helper function to set range return attribute.
9217 static bool
9218 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9219 Instruction *I,
9220 const ConstantRange &AssumedConstantRange) {
9221 if (isBetterRange(AssumedConstantRange, *I)) {
9222 A.manifestAttrs(IRP,
9223 Attribute::get(I->getContext(), Attribute::Range,
9224 AssumedConstantRange),
9225 /*ForceReplace*/ true);
9226 return true;
9227 }
9228 return false;
9229 }
9230
9231 /// See AbstractAttribute::manifest()
9232 ChangeStatus manifest(Attributor &A) override {
9233 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9234 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9235 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9236
9237 auto &V = getAssociatedValue();
9238 if (!AssumedConstantRange.isEmptySet() &&
9239 !AssumedConstantRange.isSingleElement()) {
9240 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9241 assert(I == getCtxI() && "Should not annotate an instruction which is "
9242 "not the context instruction");
9243 if (isa<LoadInst>(I))
9244 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9245 Changed = ChangeStatus::CHANGED;
9246 if (isa<CallInst>(I))
9247 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9248 AssumedConstantRange))
9249 Changed = ChangeStatus::CHANGED;
9250 }
9251 }
9252
9253 return Changed;
9254 }
9255};
9256
9257struct AAValueConstantRangeArgument final
9258 : AAArgumentFromCallSiteArguments<
9259 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9260 true /* BridgeCallBaseContext */> {
9261 using Base = AAArgumentFromCallSiteArguments<
9262 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9263 true /* BridgeCallBaseContext */>;
9264 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9265 : Base(IRP, A) {}
9266
9267 /// See AbstractAttribute::trackStatistics()
9268 void trackStatistics() const override {
9269 STATS_DECLTRACK_ARG_ATTR(value_range)
9270 }
9271};
9272
9273struct AAValueConstantRangeReturned
9274 : AAReturnedFromReturnedValues<AAValueConstantRange,
9275 AAValueConstantRangeImpl,
9276 AAValueConstantRangeImpl::StateType,
9277 /* PropagateCallBaseContext */ true> {
9278 using Base =
9279 AAReturnedFromReturnedValues<AAValueConstantRange,
9280 AAValueConstantRangeImpl,
9281 AAValueConstantRangeImpl::StateType,
9282 /* PropagateCallBaseContext */ true>;
9283 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9284 : Base(IRP, A) {}
9285
9286 /// See AbstractAttribute::initialize(...).
9287 void initialize(Attributor &A) override {
9288 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9289 indicatePessimisticFixpoint();
9290 }
9291
9292 /// See AbstractAttribute::trackStatistics()
9293 void trackStatistics() const override {
9294 STATS_DECLTRACK_FNRET_ATTR(value_range)
9295 }
9296};
9297
9298struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9299 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9300 : AAValueConstantRangeImpl(IRP, A) {}
9301
9302 /// See AbstractAttribute::initialize(...).
9303 void initialize(Attributor &A) override {
9304 AAValueConstantRangeImpl::initialize(A);
9305 if (isAtFixpoint())
9306 return;
9307
9308 Value &V = getAssociatedValue();
9309
9310 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9311 unionAssumed(ConstantRange(C->getValue()));
9312 indicateOptimisticFixpoint();
9313 return;
9314 }
9315
9316 if (isa<UndefValue>(&V)) {
9317 // Collapse the undef state to 0.
9318 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9319 indicateOptimisticFixpoint();
9320 return;
9321 }
9322
9323 if (isa<CallBase>(&V))
9324 return;
9325
9326 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9327 return;
9328
9329 // If it is a load instruction with range metadata, use it.
9330 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9331 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9332 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9333 return;
9334 }
9335
9336 // We can work with PHI and select instruction as we traverse their operands
9337 // during update.
9338 if (isa<SelectInst>(V) || isa<PHINode>(V))
9339 return;
9340
9341 // Otherwise we give up.
9342 indicatePessimisticFixpoint();
9343
9344 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9345 << getAssociatedValue() << "\n");
9346 }
9347
9348 bool calculateBinaryOperator(
9349 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9350 const Instruction *CtxI,
9351 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9352 Value *LHS = BinOp->getOperand(0);
9353 Value *RHS = BinOp->getOperand(1);
9354
9355 // Simplify the operands first.
9356 bool UsedAssumedInformation = false;
9357 const auto &SimplifiedLHS = A.getAssumedSimplified(
9358 IRPosition::value(*LHS, getCallBaseContext()), *this,
9359 UsedAssumedInformation, AA::Interprocedural);
9360 if (!SimplifiedLHS.has_value())
9361 return true;
9362 if (!*SimplifiedLHS)
9363 return false;
9364 LHS = *SimplifiedLHS;
9365
9366 const auto &SimplifiedRHS = A.getAssumedSimplified(
9367 IRPosition::value(*RHS, getCallBaseContext()), *this,
9368 UsedAssumedInformation, AA::Interprocedural);
9369 if (!SimplifiedRHS.has_value())
9370 return true;
9371 if (!*SimplifiedRHS)
9372 return false;
9373 RHS = *SimplifiedRHS;
9374
9375 // TODO: Allow non integers as well.
9376 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9377 return false;
9378
9379 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9380 *this, IRPosition::value(*LHS, getCallBaseContext()),
9381 DepClassTy::REQUIRED);
9382 if (!LHSAA)
9383 return false;
9384 QuerriedAAs.push_back(LHSAA);
9385 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9386
9387 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9388 *this, IRPosition::value(*RHS, getCallBaseContext()),
9389 DepClassTy::REQUIRED);
9390 if (!RHSAA)
9391 return false;
9392 QuerriedAAs.push_back(RHSAA);
9393 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9394
9395 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9396
9397 T.unionAssumed(AssumedRange);
9398
9399 // TODO: Track a known state too.
9400
9401 return T.isValidState();
9402 }
9403
9404 bool calculateCastInst(
9405 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9406 const Instruction *CtxI,
9407 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9408 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9409 // TODO: Allow non integers as well.
9410 Value *OpV = CastI->getOperand(0);
9411
9412 // Simplify the operand first.
9413 bool UsedAssumedInformation = false;
9414 const auto &SimplifiedOpV = A.getAssumedSimplified(
9415 IRPosition::value(*OpV, getCallBaseContext()), *this,
9416 UsedAssumedInformation, AA::Interprocedural);
9417 if (!SimplifiedOpV.has_value())
9418 return true;
9419 if (!*SimplifiedOpV)
9420 return false;
9421 OpV = *SimplifiedOpV;
9422
9423 if (!OpV->getType()->isIntegerTy())
9424 return false;
9425
9426 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9427 *this, IRPosition::value(*OpV, getCallBaseContext()),
9428 DepClassTy::REQUIRED);
9429 if (!OpAA)
9430 return false;
9431 QuerriedAAs.push_back(OpAA);
9432 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9433 getState().getBitWidth()));
9434 return T.isValidState();
9435 }
9436
9437 bool
9438 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9439 const Instruction *CtxI,
9440 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9441 Value *LHS = CmpI->getOperand(0);
9442 Value *RHS = CmpI->getOperand(1);
9443
9444 // Simplify the operands first.
9445 bool UsedAssumedInformation = false;
9446 const auto &SimplifiedLHS = A.getAssumedSimplified(
9447 IRPosition::value(*LHS, getCallBaseContext()), *this,
9448 UsedAssumedInformation, AA::Interprocedural);
9449 if (!SimplifiedLHS.has_value())
9450 return true;
9451 if (!*SimplifiedLHS)
9452 return false;
9453 LHS = *SimplifiedLHS;
9454
9455 const auto &SimplifiedRHS = A.getAssumedSimplified(
9456 IRPosition::value(*RHS, getCallBaseContext()), *this,
9457 UsedAssumedInformation, AA::Interprocedural);
9458 if (!SimplifiedRHS.has_value())
9459 return true;
9460 if (!*SimplifiedRHS)
9461 return false;
9462 RHS = *SimplifiedRHS;
9463
9464 // TODO: Allow non integers as well.
9465 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9466 return false;
9467
9468 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9469 *this, IRPosition::value(*LHS, getCallBaseContext()),
9470 DepClassTy::REQUIRED);
9471 if (!LHSAA)
9472 return false;
9473 QuerriedAAs.push_back(LHSAA);
9474 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9475 *this, IRPosition::value(*RHS, getCallBaseContext()),
9476 DepClassTy::REQUIRED);
9477 if (!RHSAA)
9478 return false;
9479 QuerriedAAs.push_back(RHSAA);
9480 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9481 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9482
9483 // If one of them is empty set, we can't decide.
9484 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9485 return true;
9486
9487 bool MustTrue = false, MustFalse = false;
9488
9489 auto AllowedRegion =
9491
9492 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9493 MustFalse = true;
9494
9495 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9496 MustTrue = true;
9497
9498 assert((!MustTrue || !MustFalse) &&
9499 "Either MustTrue or MustFalse should be false!");
9500
9501 if (MustTrue)
9502 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9503 else if (MustFalse)
9504 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9505 else
9506 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9507
9508 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9509 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9510 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9511 << *RHSAA);
9512
9513 // TODO: Track a known state too.
9514 return T.isValidState();
9515 }
9516
9517 /// See AbstractAttribute::updateImpl(...).
9518 ChangeStatus updateImpl(Attributor &A) override {
9519
9520 IntegerRangeState T(getBitWidth());
9521 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9523 if (!I || isa<CallBase>(I)) {
9524
9525 // Simplify the operand first.
9526 bool UsedAssumedInformation = false;
9527 const auto &SimplifiedOpV = A.getAssumedSimplified(
9528 IRPosition::value(V, getCallBaseContext()), *this,
9529 UsedAssumedInformation, AA::Interprocedural);
9530 if (!SimplifiedOpV.has_value())
9531 return true;
9532 if (!*SimplifiedOpV)
9533 return false;
9534 Value *VPtr = *SimplifiedOpV;
9535
9536 // If the value is not instruction, we query AA to Attributor.
9537 const auto *AA = A.getAAFor<AAValueConstantRange>(
9538 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9539 DepClassTy::REQUIRED);
9540
9541 // Clamp operator is not used to utilize a program point CtxI.
9542 if (AA)
9543 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9544 else
9545 return false;
9546
9547 return T.isValidState();
9548 }
9549
9551 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9552 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9553 return false;
9554 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9555 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9556 return false;
9557 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9558 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9559 return false;
9560 } else {
9561 // Give up with other instructions.
9562 // TODO: Add other instructions
9563
9564 T.indicatePessimisticFixpoint();
9565 return false;
9566 }
9567
9568 // Catch circular reasoning in a pessimistic way for now.
9569 // TODO: Check how the range evolves and if we stripped anything, see also
9570 // AADereferenceable or AAAlign for similar situations.
9571 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9572 if (QueriedAA != this)
9573 continue;
9574 // If we are in a stady state we do not need to worry.
9575 if (T.getAssumed() == getState().getAssumed())
9576 continue;
9577 T.indicatePessimisticFixpoint();
9578 }
9579
9580 return T.isValidState();
9581 };
9582
9583 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9584 return indicatePessimisticFixpoint();
9585
9586 // Ensure that long def-use chains can't cause circular reasoning either by
9587 // introducing a cutoff below.
9588 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9589 return ChangeStatus::UNCHANGED;
9590 if (++NumChanges > MaxNumChanges) {
9591 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9592 << " but only " << MaxNumChanges
9593 << " are allowed to avoid cyclic reasoning.");
9594 return indicatePessimisticFixpoint();
9595 }
9596 return ChangeStatus::CHANGED;
9597 }
9598
9599 /// See AbstractAttribute::trackStatistics()
9600 void trackStatistics() const override {
9602 }
9603
9604 /// Tracker to bail after too many widening steps of the constant range.
9605 int NumChanges = 0;
9606
9607 /// Upper bound for the number of allowed changes (=widening steps) for the
9608 /// constant range before we give up.
9609 static constexpr int MaxNumChanges = 5;
9610};
9611
9612struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9613 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9614 : AAValueConstantRangeImpl(IRP, A) {}
9615
9616 /// See AbstractAttribute::initialize(...).
9617 ChangeStatus updateImpl(Attributor &A) override {
9618 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9619 "not be called");
9620 }
9621
9622 /// See AbstractAttribute::trackStatistics()
9623 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9624};
9625
9626struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9627 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9628 : AAValueConstantRangeFunction(IRP, A) {}
9629
9630 /// See AbstractAttribute::trackStatistics()
9631 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9632};
9633
9634struct AAValueConstantRangeCallSiteReturned
9635 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9636 AAValueConstantRangeImpl::StateType,
9637 /* IntroduceCallBaseContext */ true> {
9638 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9639 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9640 AAValueConstantRangeImpl::StateType,
9641 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9642
9643 /// See AbstractAttribute::initialize(...).
9644 void initialize(Attributor &A) override {
9645 // If it is a call instruction with range attribute, use the range.
9646 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9647 if (std::optional<ConstantRange> Range = CI->getRange())
9648 intersectKnown(*Range);
9649 }
9650
9651 AAValueConstantRangeImpl::initialize(A);
9652 }
9653
9654 /// See AbstractAttribute::trackStatistics()
9655 void trackStatistics() const override {
9656 STATS_DECLTRACK_CSRET_ATTR(value_range)
9657 }
9658};
9659struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9660 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9661 : AAValueConstantRangeFloating(IRP, A) {}
9662
9663 /// See AbstractAttribute::manifest()
9664 ChangeStatus manifest(Attributor &A) override {
9665 return ChangeStatus::UNCHANGED;
9666 }
9667
9668 /// See AbstractAttribute::trackStatistics()
9669 void trackStatistics() const override {
9670 STATS_DECLTRACK_CSARG_ATTR(value_range)
9671 }
9672};
9673} // namespace
9674
9675/// ------------------ Potential Values Attribute -------------------------
9676
9677namespace {
9678struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9679 using StateType = PotentialConstantIntValuesState;
9680
9681 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9682 : AAPotentialConstantValues(IRP, A) {}
9683
9684 /// See AbstractAttribute::initialize(..).
9685 void initialize(Attributor &A) override {
9686 if (A.hasSimplificationCallback(getIRPosition()))
9687 indicatePessimisticFixpoint();
9688 else
9689 AAPotentialConstantValues::initialize(A);
9690 }
9691
9692 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9693 bool &ContainsUndef, bool ForSelf) {
9695 bool UsedAssumedInformation = false;
9696 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9697 UsedAssumedInformation)) {
9698 // Avoid recursion when the caller is computing constant values for this
9699 // IRP itself.
9700 if (ForSelf)
9701 return false;
9702 if (!IRP.getAssociatedType()->isIntegerTy())
9703 return false;
9704 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9705 *this, IRP, DepClassTy::REQUIRED);
9706 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9707 return false;
9708 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9709 S = PotentialValuesAA->getState().getAssumedSet();
9710 return true;
9711 }
9712
9713 // Copy all the constant values, except UndefValue. ContainsUndef is true
9714 // iff Values contains only UndefValue instances. If there are other known
9715 // constants, then UndefValue is dropped.
9716 ContainsUndef = false;
9717 for (auto &It : Values) {
9718 if (isa<UndefValue>(It.getValue())) {
9719 ContainsUndef = true;
9720 continue;
9721 }
9722 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9723 if (!CI)
9724 return false;
9725 S.insert(CI->getValue());
9726 }
9727 ContainsUndef &= S.empty();
9728
9729 return true;
9730 }
9731
9732 /// See AbstractAttribute::getAsStr().
9733 const std::string getAsStr(Attributor *A) const override {
9734 std::string Str;
9735 llvm::raw_string_ostream OS(Str);
9736 OS << getState();
9737 return Str;
9738 }
9739
9740 /// See AbstractAttribute::updateImpl(...).
9741 ChangeStatus updateImpl(Attributor &A) override {
9742 return indicatePessimisticFixpoint();
9743 }
9744};
9745
9746struct AAPotentialConstantValuesArgument final
9747 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9748 AAPotentialConstantValuesImpl,
9749 PotentialConstantIntValuesState> {
9750 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9751 AAPotentialConstantValuesImpl,
9753 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9754 : Base(IRP, A) {}
9755
9756 /// See AbstractAttribute::trackStatistics()
9757 void trackStatistics() const override {
9758 STATS_DECLTRACK_ARG_ATTR(potential_values)
9759 }
9760};
9761
9762struct AAPotentialConstantValuesReturned
9763 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9764 AAPotentialConstantValuesImpl> {
9765 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9766 AAPotentialConstantValuesImpl>;
9767 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9768 : Base(IRP, A) {}
9769
9770 void initialize(Attributor &A) override {
9771 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9772 indicatePessimisticFixpoint();
9773 Base::initialize(A);
9774 }
9775
9776 /// See AbstractAttribute::trackStatistics()
9777 void trackStatistics() const override {
9778 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9779 }
9780};
9781
9782struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9783 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9784 : AAPotentialConstantValuesImpl(IRP, A) {}
9785
9786 /// See AbstractAttribute::initialize(..).
9787 void initialize(Attributor &A) override {
9788 AAPotentialConstantValuesImpl::initialize(A);
9789 if (isAtFixpoint())
9790 return;
9791
9792 Value &V = getAssociatedValue();
9793
9794 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9795 unionAssumed(C->getValue());
9796 indicateOptimisticFixpoint();
9797 return;
9798 }
9799
9800 if (isa<UndefValue>(&V)) {
9801 unionAssumedWithUndef();
9802 indicateOptimisticFixpoint();
9803 return;
9804 }
9805
9806 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9807 return;
9808
9809 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9810 return;
9811
9812 indicatePessimisticFixpoint();
9813
9814 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9815 << getAssociatedValue() << "\n");
9816 }
9817
9818 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9819 const APInt &RHS) {
9820 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9821 }
9822
9823 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9824 uint32_t ResultBitWidth) {
9825 Instruction::CastOps CastOp = CI->getOpcode();
9826 switch (CastOp) {
9827 default:
9828 llvm_unreachable("unsupported or not integer cast");
9829 case Instruction::Trunc:
9830 return Src.trunc(ResultBitWidth);
9831 case Instruction::SExt:
9832 return Src.sext(ResultBitWidth);
9833 case Instruction::ZExt:
9834 return Src.zext(ResultBitWidth);
9835 case Instruction::BitCast:
9836 return Src;
9837 }
9838 }
9839
9840 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9841 const APInt &LHS, const APInt &RHS,
9842 bool &SkipOperation, bool &Unsupported) {
9843 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9844 // Unsupported is set to true when the binary operator is not supported.
9845 // SkipOperation is set to true when UB occur with the given operand pair
9846 // (LHS, RHS).
9847 // TODO: we should look at nsw and nuw keywords to handle operations
9848 // that create poison or undef value.
9849 switch (BinOpcode) {
9850 default:
9851 Unsupported = true;
9852 return LHS;
9853 case Instruction::Add:
9854 return LHS + RHS;
9855 case Instruction::Sub:
9856 return LHS - RHS;
9857 case Instruction::Mul:
9858 return LHS * RHS;
9859 case Instruction::UDiv:
9860 if (RHS.isZero()) {
9861 SkipOperation = true;
9862 return LHS;
9863 }
9864 return LHS.udiv(RHS);
9865 case Instruction::SDiv:
9866 if (RHS.isZero()) {
9867 SkipOperation = true;
9868 return LHS;
9869 }
9870 return LHS.sdiv(RHS);
9871 case Instruction::URem:
9872 if (RHS.isZero()) {
9873 SkipOperation = true;
9874 return LHS;
9875 }
9876 return LHS.urem(RHS);
9877 case Instruction::SRem:
9878 if (RHS.isZero()) {
9879 SkipOperation = true;
9880 return LHS;
9881 }
9882 return LHS.srem(RHS);
9883 case Instruction::Shl:
9884 return LHS.shl(RHS);
9885 case Instruction::LShr:
9886 return LHS.lshr(RHS);
9887 case Instruction::AShr:
9888 return LHS.ashr(RHS);
9889 case Instruction::And:
9890 return LHS & RHS;
9891 case Instruction::Or:
9892 return LHS | RHS;
9893 case Instruction::Xor:
9894 return LHS ^ RHS;
9895 }
9896 }
9897
9898 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9899 const APInt &LHS, const APInt &RHS) {
9900 bool SkipOperation = false;
9901 bool Unsupported = false;
9902 APInt Result =
9903 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9904 if (Unsupported)
9905 return false;
9906 // If SkipOperation is true, we can ignore this operand pair (L, R).
9907 if (!SkipOperation)
9908 unionAssumed(Result);
9909 return isValidState();
9910 }
9911
9912 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9913 auto AssumedBefore = getAssumed();
9914 Value *LHS = ICI->getOperand(0);
9915 Value *RHS = ICI->getOperand(1);
9916
9917 bool LHSContainsUndef = false, RHSContainsUndef = false;
9918 SetTy LHSAAPVS, RHSAAPVS;
9919 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9920 LHSContainsUndef, /* ForSelf */ false) ||
9921 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9922 RHSContainsUndef, /* ForSelf */ false))
9923 return indicatePessimisticFixpoint();
9924
9925 // TODO: make use of undef flag to limit potential values aggressively.
9926 bool MaybeTrue = false, MaybeFalse = false;
9927 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9928 if (LHSContainsUndef && RHSContainsUndef) {
9929 // The result of any comparison between undefs can be soundly replaced
9930 // with undef.
9931 unionAssumedWithUndef();
9932 } else if (LHSContainsUndef) {
9933 for (const APInt &R : RHSAAPVS) {
9934 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9935 MaybeTrue |= CmpResult;
9936 MaybeFalse |= !CmpResult;
9937 if (MaybeTrue & MaybeFalse)
9938 return indicatePessimisticFixpoint();
9939 }
9940 } else if (RHSContainsUndef) {
9941 for (const APInt &L : LHSAAPVS) {
9942 bool CmpResult = calculateICmpInst(ICI, L, Zero);
9943 MaybeTrue |= CmpResult;
9944 MaybeFalse |= !CmpResult;
9945 if (MaybeTrue & MaybeFalse)
9946 return indicatePessimisticFixpoint();
9947 }
9948 } else {
9949 for (const APInt &L : LHSAAPVS) {
9950 for (const APInt &R : RHSAAPVS) {
9951 bool CmpResult = calculateICmpInst(ICI, L, R);
9952 MaybeTrue |= CmpResult;
9953 MaybeFalse |= !CmpResult;
9954 if (MaybeTrue & MaybeFalse)
9955 return indicatePessimisticFixpoint();
9956 }
9957 }
9958 }
9959 if (MaybeTrue)
9960 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9961 if (MaybeFalse)
9962 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
9963 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9964 : ChangeStatus::CHANGED;
9965 }
9966
9967 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
9968 auto AssumedBefore = getAssumed();
9969 Value *LHS = SI->getTrueValue();
9970 Value *RHS = SI->getFalseValue();
9971
9972 bool UsedAssumedInformation = false;
9973 std::optional<Constant *> C = A.getAssumedConstant(
9974 *SI->getCondition(), *this, UsedAssumedInformation);
9975
9976 // Check if we only need one operand.
9977 bool OnlyLeft = false, OnlyRight = false;
9978 if (C && *C && (*C)->isOneValue())
9979 OnlyLeft = true;
9980 else if (C && *C && (*C)->isZeroValue())
9981 OnlyRight = true;
9982
9983 bool LHSContainsUndef = false, RHSContainsUndef = false;
9984 SetTy LHSAAPVS, RHSAAPVS;
9985 if (!OnlyRight &&
9986 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9987 LHSContainsUndef, /* ForSelf */ false))
9988 return indicatePessimisticFixpoint();
9989
9990 if (!OnlyLeft &&
9991 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9992 RHSContainsUndef, /* ForSelf */ false))
9993 return indicatePessimisticFixpoint();
9994
9995 if (OnlyLeft || OnlyRight) {
9996 // select (true/false), lhs, rhs
9997 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
9998 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
9999
10000 if (Undef)
10001 unionAssumedWithUndef();
10002 else {
10003 for (const auto &It : *OpAA)
10004 unionAssumed(It);
10005 }
10006
10007 } else if (LHSContainsUndef && RHSContainsUndef) {
10008 // select i1 *, undef , undef => undef
10009 unionAssumedWithUndef();
10010 } else {
10011 for (const auto &It : LHSAAPVS)
10012 unionAssumed(It);
10013 for (const auto &It : RHSAAPVS)
10014 unionAssumed(It);
10015 }
10016 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10017 : ChangeStatus::CHANGED;
10018 }
10019
10020 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10021 auto AssumedBefore = getAssumed();
10022 if (!CI->isIntegerCast())
10023 return indicatePessimisticFixpoint();
10024 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10025 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10026 Value *Src = CI->getOperand(0);
10027
10028 bool SrcContainsUndef = false;
10029 SetTy SrcPVS;
10030 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10031 SrcContainsUndef, /* ForSelf */ false))
10032 return indicatePessimisticFixpoint();
10033
10034 if (SrcContainsUndef)
10035 unionAssumedWithUndef();
10036 else {
10037 for (const APInt &S : SrcPVS) {
10038 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10039 unionAssumed(T);
10040 }
10041 }
10042 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10043 : ChangeStatus::CHANGED;
10044 }
10045
10046 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10047 auto AssumedBefore = getAssumed();
10048 Value *LHS = BinOp->getOperand(0);
10049 Value *RHS = BinOp->getOperand(1);
10050
10051 bool LHSContainsUndef = false, RHSContainsUndef = false;
10052 SetTy LHSAAPVS, RHSAAPVS;
10053 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10054 LHSContainsUndef, /* ForSelf */ false) ||
10055 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10056 RHSContainsUndef, /* ForSelf */ false))
10057 return indicatePessimisticFixpoint();
10058
10059 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10060
10061 // TODO: make use of undef flag to limit potential values aggressively.
10062 if (LHSContainsUndef && RHSContainsUndef) {
10063 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10064 return indicatePessimisticFixpoint();
10065 } else if (LHSContainsUndef) {
10066 for (const APInt &R : RHSAAPVS) {
10067 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10068 return indicatePessimisticFixpoint();
10069 }
10070 } else if (RHSContainsUndef) {
10071 for (const APInt &L : LHSAAPVS) {
10072 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10073 return indicatePessimisticFixpoint();
10074 }
10075 } else {
10076 for (const APInt &L : LHSAAPVS) {
10077 for (const APInt &R : RHSAAPVS) {
10078 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10079 return indicatePessimisticFixpoint();
10080 }
10081 }
10082 }
10083 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10084 : ChangeStatus::CHANGED;
10085 }
10086
10087 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10088 auto AssumedBefore = getAssumed();
10089 SetTy Incoming;
10090 bool ContainsUndef;
10091 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10092 ContainsUndef, /* ForSelf */ true))
10093 return indicatePessimisticFixpoint();
10094 if (ContainsUndef) {
10095 unionAssumedWithUndef();
10096 } else {
10097 for (const auto &It : Incoming)
10098 unionAssumed(It);
10099 }
10100 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10101 : ChangeStatus::CHANGED;
10102 }
10103
10104 /// See AbstractAttribute::updateImpl(...).
10105 ChangeStatus updateImpl(Attributor &A) override {
10106 Value &V = getAssociatedValue();
10108
10109 if (auto *ICI = dyn_cast<ICmpInst>(I))
10110 return updateWithICmpInst(A, ICI);
10111
10112 if (auto *SI = dyn_cast<SelectInst>(I))
10113 return updateWithSelectInst(A, SI);
10114
10115 if (auto *CI = dyn_cast<CastInst>(I))
10116 return updateWithCastInst(A, CI);
10117
10118 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10119 return updateWithBinaryOperator(A, BinOp);
10120
10121 if (isa<PHINode>(I) || isa<LoadInst>(I))
10122 return updateWithInstruction(A, I);
10123
10124 return indicatePessimisticFixpoint();
10125 }
10126
10127 /// See AbstractAttribute::trackStatistics()
10128 void trackStatistics() const override {
10129 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10130 }
10131};
10132
10133struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10134 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10135 : AAPotentialConstantValuesImpl(IRP, A) {}
10136
10137 /// See AbstractAttribute::initialize(...).
10138 ChangeStatus updateImpl(Attributor &A) override {
10140 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10141 "not be called");
10142 }
10143
10144 /// See AbstractAttribute::trackStatistics()
10145 void trackStatistics() const override {
10146 STATS_DECLTRACK_FN_ATTR(potential_values)
10147 }
10148};
10149
10150struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10151 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10152 : AAPotentialConstantValuesFunction(IRP, A) {}
10153
10154 /// See AbstractAttribute::trackStatistics()
10155 void trackStatistics() const override {
10156 STATS_DECLTRACK_CS_ATTR(potential_values)
10157 }
10158};
10159
10160struct AAPotentialConstantValuesCallSiteReturned
10161 : AACalleeToCallSite<AAPotentialConstantValues,
10162 AAPotentialConstantValuesImpl> {
10163 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10164 Attributor &A)
10165 : AACalleeToCallSite<AAPotentialConstantValues,
10166 AAPotentialConstantValuesImpl>(IRP, A) {}
10167
10168 /// See AbstractAttribute::trackStatistics()
10169 void trackStatistics() const override {
10170 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10171 }
10172};
10173
10174struct AAPotentialConstantValuesCallSiteArgument
10175 : AAPotentialConstantValuesFloating {
10176 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10177 Attributor &A)
10178 : AAPotentialConstantValuesFloating(IRP, A) {}
10179
10180 /// See AbstractAttribute::initialize(..).
10181 void initialize(Attributor &A) override {
10182 AAPotentialConstantValuesImpl::initialize(A);
10183 if (isAtFixpoint())
10184 return;
10185
10186 Value &V = getAssociatedValue();
10187
10188 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10189 unionAssumed(C->getValue());
10190 indicateOptimisticFixpoint();
10191 return;
10192 }
10193
10194 if (isa<UndefValue>(&V)) {
10195 unionAssumedWithUndef();
10196 indicateOptimisticFixpoint();
10197 return;
10198 }
10199 }
10200
10201 /// See AbstractAttribute::updateImpl(...).
10202 ChangeStatus updateImpl(Attributor &A) override {
10203 Value &V = getAssociatedValue();
10204 auto AssumedBefore = getAssumed();
10205 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10206 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10207 if (!AA)
10208 return indicatePessimisticFixpoint();
10209 const auto &S = AA->getAssumed();
10210 unionAssumed(S);
10211 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10212 : ChangeStatus::CHANGED;
10213 }
10214
10215 /// See AbstractAttribute::trackStatistics()
10216 void trackStatistics() const override {
10217 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10218 }
10219};
10220} // namespace
10221
10222/// ------------------------ NoUndef Attribute ---------------------------------
10224 Attribute::AttrKind ImpliedAttributeKind,
10225 bool IgnoreSubsumingPositions) {
10226 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10227 "Unexpected attribute kind");
10228 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10229 Attribute::NoUndef))
10230 return true;
10231
10232 Value &Val = IRP.getAssociatedValue();
10235 LLVMContext &Ctx = Val.getContext();
10236 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10237 return true;
10238 }
10239
10240 return false;
10241}
10242
10243namespace {
10244struct AANoUndefImpl : AANoUndef {
10245 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10246
10247 /// See AbstractAttribute::initialize(...).
10248 void initialize(Attributor &A) override {
10249 Value &V = getAssociatedValue();
10250 if (isa<UndefValue>(V))
10251 indicatePessimisticFixpoint();
10252 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10253 }
10254
10255 /// See followUsesInMBEC
10256 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10257 AANoUndef::StateType &State) {
10258 const Value *UseV = U->get();
10259 const DominatorTree *DT = nullptr;
10260 AssumptionCache *AC = nullptr;
10261 InformationCache &InfoCache = A.getInfoCache();
10262 if (Function *F = getAnchorScope()) {
10263 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10264 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10265 }
10266 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10267 bool TrackUse = false;
10268 // Track use for instructions which must produce undef or poison bits when
10269 // at least one operand contains such bits.
10271 TrackUse = true;
10272 return TrackUse;
10273 }
10274
10275 /// See AbstractAttribute::getAsStr().
10276 const std::string getAsStr(Attributor *A) const override {
10277 return getAssumed() ? "noundef" : "may-undef-or-poison";
10278 }
10279
10280 ChangeStatus manifest(Attributor &A) override {
10281 // We don't manifest noundef attribute for dead positions because the
10282 // associated values with dead positions would be replaced with undef
10283 // values.
10284 bool UsedAssumedInformation = false;
10285 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10286 UsedAssumedInformation))
10287 return ChangeStatus::UNCHANGED;
10288 // A position whose simplified value does not have any value is
10289 // considered to be dead. We don't manifest noundef in such positions for
10290 // the same reason above.
10291 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10293 .has_value())
10294 return ChangeStatus::UNCHANGED;
10295 return AANoUndef::manifest(A);
10296 }
10297};
10298
10299struct AANoUndefFloating : public AANoUndefImpl {
10300 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10301 : AANoUndefImpl(IRP, A) {}
10302
10303 /// See AbstractAttribute::initialize(...).
10304 void initialize(Attributor &A) override {
10305 AANoUndefImpl::initialize(A);
10306 if (!getState().isAtFixpoint() && getAnchorScope() &&
10307 !getAnchorScope()->isDeclaration())
10308 if (Instruction *CtxI = getCtxI())
10309 followUsesInMBEC(*this, A, getState(), *CtxI);
10310 }
10311
10312 /// See AbstractAttribute::updateImpl(...).
10313 ChangeStatus updateImpl(Attributor &A) override {
10314 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10315 bool IsKnownNoUndef;
10317 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10318 };
10319
10320 bool Stripped;
10321 bool UsedAssumedInformation = false;
10322 Value *AssociatedValue = &getAssociatedValue();
10324 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10325 AA::AnyScope, UsedAssumedInformation))
10326 Stripped = false;
10327 else
10328 Stripped =
10329 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10330
10331 if (!Stripped) {
10332 // If we haven't stripped anything we might still be able to use a
10333 // different AA, but only if the IRP changes. Effectively when we
10334 // interpret this not as a call site value but as a floating/argument
10335 // value.
10336 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10337 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10338 return indicatePessimisticFixpoint();
10339 return ChangeStatus::UNCHANGED;
10340 }
10341
10342 for (const auto &VAC : Values)
10343 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10344 return indicatePessimisticFixpoint();
10345
10346 return ChangeStatus::UNCHANGED;
10347 }
10348
10349 /// See AbstractAttribute::trackStatistics()
10350 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10351};
10352
10353struct AANoUndefReturned final
10354 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10355 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10356 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10357
10358 /// See AbstractAttribute::trackStatistics()
10359 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10360};
10361
10362struct AANoUndefArgument final
10363 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10364 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10365 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10366
10367 /// See AbstractAttribute::trackStatistics()
10368 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10369};
10370
10371struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10372 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10373 : AANoUndefFloating(IRP, A) {}
10374
10375 /// See AbstractAttribute::trackStatistics()
10376 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10377};
10378
10379struct AANoUndefCallSiteReturned final
10380 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10381 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10382 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10383
10384 /// See AbstractAttribute::trackStatistics()
10385 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10386};
10387
10388/// ------------------------ NoFPClass Attribute -------------------------------
10389
10390struct AANoFPClassImpl : AANoFPClass {
10391 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10392
10393 void initialize(Attributor &A) override {
10394 const IRPosition &IRP = getIRPosition();
10395
10396 Value &V = IRP.getAssociatedValue();
10397 if (isa<UndefValue>(V)) {
10398 indicateOptimisticFixpoint();
10399 return;
10400 }
10401
10403 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10404 for (const auto &Attr : Attrs) {
10405 addKnownBits(Attr.getNoFPClass());
10406 }
10407
10408 const DataLayout &DL = A.getDataLayout();
10409 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10410 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL);
10411 addKnownBits(~KnownFPClass.KnownFPClasses);
10412 }
10413
10414 if (Instruction *CtxI = getCtxI())
10415 followUsesInMBEC(*this, A, getState(), *CtxI);
10416 }
10417
10418 /// See followUsesInMBEC
10419 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10420 AANoFPClass::StateType &State) {
10421 // TODO: Determine what instructions can be looked through.
10422 auto *CB = dyn_cast<CallBase>(I);
10423 if (!CB)
10424 return false;
10425
10426 if (!CB->isArgOperand(U))
10427 return false;
10428
10429 unsigned ArgNo = CB->getArgOperandNo(U);
10430 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10431 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10432 State.addKnownBits(NoFPAA->getState().getKnown());
10433 return false;
10434 }
10435
10436 const std::string getAsStr(Attributor *A) const override {
10437 std::string Result = "nofpclass";
10438 raw_string_ostream OS(Result);
10439 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10440 return Result;
10441 }
10442
10443 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10444 SmallVectorImpl<Attribute> &Attrs) const override {
10445 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10446 }
10447};
10448
10449struct AANoFPClassFloating : public AANoFPClassImpl {
10450 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10451 : AANoFPClassImpl(IRP, A) {}
10452
10453 /// See AbstractAttribute::updateImpl(...).
10454 ChangeStatus updateImpl(Attributor &A) override {
10456 bool UsedAssumedInformation = false;
10457 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10458 AA::AnyScope, UsedAssumedInformation)) {
10459 Values.push_back({getAssociatedValue(), getCtxI()});
10460 }
10461
10462 StateType T;
10463 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10464 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10465 DepClassTy::REQUIRED);
10466 if (!AA || this == AA) {
10467 T.indicatePessimisticFixpoint();
10468 } else {
10469 const AANoFPClass::StateType &S =
10470 static_cast<const AANoFPClass::StateType &>(AA->getState());
10471 T ^= S;
10472 }
10473 return T.isValidState();
10474 };
10475
10476 for (const auto &VAC : Values)
10477 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10478 return indicatePessimisticFixpoint();
10479
10480 return clampStateAndIndicateChange(getState(), T);
10481 }
10482
10483 /// See AbstractAttribute::trackStatistics()
10484 void trackStatistics() const override {
10486 }
10487};
10488
10489struct AANoFPClassReturned final
10490 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10491 AANoFPClassImpl::StateType, false,
10492 Attribute::None, false> {
10493 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10494 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10495 AANoFPClassImpl::StateType, false,
10496 Attribute::None, false>(IRP, A) {}
10497
10498 /// See AbstractAttribute::trackStatistics()
10499 void trackStatistics() const override {
10501 }
10502};
10503
10504struct AANoFPClassArgument final
10505 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10506 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10507 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10508
10509 /// See AbstractAttribute::trackStatistics()
10510 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10511};
10512
10513struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10514 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10515 : AANoFPClassFloating(IRP, A) {}
10516
10517 /// See AbstractAttribute::trackStatistics()
10518 void trackStatistics() const override {
10520 }
10521};
10522
10523struct AANoFPClassCallSiteReturned final
10524 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10525 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10526 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10527
10528 /// See AbstractAttribute::trackStatistics()
10529 void trackStatistics() const override {
10531 }
10532};
10533
10534struct AACallEdgesImpl : public AACallEdges {
10535 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10536
10537 const SetVector<Function *> &getOptimisticEdges() const override {
10538 return CalledFunctions;
10539 }
10540
10541 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10542
10543 bool hasNonAsmUnknownCallee() const override {
10544 return HasUnknownCalleeNonAsm;
10545 }
10546
10547 const std::string getAsStr(Attributor *A) const override {
10548 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10549 std::to_string(CalledFunctions.size()) + "]";
10550 }
10551
10552 void trackStatistics() const override {}
10553
10554protected:
10555 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10556 if (CalledFunctions.insert(Fn)) {
10557 Change = ChangeStatus::CHANGED;
10558 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10559 << "\n");
10560 }
10561 }
10562
10563 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10564 if (!HasUnknownCallee)
10565 Change = ChangeStatus::CHANGED;
10566 if (NonAsm && !HasUnknownCalleeNonAsm)
10567 Change = ChangeStatus::CHANGED;
10568 HasUnknownCalleeNonAsm |= NonAsm;
10569 HasUnknownCallee = true;
10570 }
10571
10572private:
10573 /// Optimistic set of functions that might be called by this position.
10574 SetVector<Function *> CalledFunctions;
10575
10576 /// Is there any call with a unknown callee.
10577 bool HasUnknownCallee = false;
10578
10579 /// Is there any call with a unknown callee, excluding any inline asm.
10580 bool HasUnknownCalleeNonAsm = false;
10581};
10582
10583struct AACallEdgesCallSite : public AACallEdgesImpl {
10584 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10585 : AACallEdgesImpl(IRP, A) {}
10586 /// See AbstractAttribute::updateImpl(...).
10587 ChangeStatus updateImpl(Attributor &A) override {
10588 ChangeStatus Change = ChangeStatus::UNCHANGED;
10589
10590 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10591 if (Function *Fn = dyn_cast<Function>(&V)) {
10592 addCalledFunction(Fn, Change);
10593 } else {
10594 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10595 setHasUnknownCallee(true, Change);
10596 }
10597
10598 // Explore all values.
10599 return true;
10600 };
10601
10603 // Process any value that we might call.
10604 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10605 if (isa<Constant>(V)) {
10606 VisitValue(*V, CtxI);
10607 return;
10608 }
10609
10610 bool UsedAssumedInformation = false;
10611 Values.clear();
10612 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10613 AA::AnyScope, UsedAssumedInformation)) {
10614 Values.push_back({*V, CtxI});
10615 }
10616 for (auto &VAC : Values)
10617 VisitValue(*VAC.getValue(), VAC.getCtxI());
10618 };
10619
10620 CallBase *CB = cast<CallBase>(getCtxI());
10621
10622 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10623 if (IA->hasSideEffects() &&
10624 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10625 !hasAssumption(*CB, "ompx_no_call_asm")) {
10626 setHasUnknownCallee(false, Change);
10627 }
10628 return Change;
10629 }
10630
10631 if (CB->isIndirectCall())
10632 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10633 *this, getIRPosition(), DepClassTy::OPTIONAL))
10634 if (IndirectCallAA->foreachCallee(
10635 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10636 return Change;
10637
10638 // The most simple case.
10639 ProcessCalledOperand(CB->getCalledOperand(), CB);
10640
10641 // Process callback functions.
10642 SmallVector<const Use *, 4u> CallbackUses;
10643 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10644 for (const Use *U : CallbackUses)
10645 ProcessCalledOperand(U->get(), CB);
10646
10647 return Change;
10648 }
10649};
10650
10651struct AACallEdgesFunction : public AACallEdgesImpl {
10652 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10653 : AACallEdgesImpl(IRP, A) {}
10654
10655 /// See AbstractAttribute::updateImpl(...).
10656 ChangeStatus updateImpl(Attributor &A) override {
10657 ChangeStatus Change = ChangeStatus::UNCHANGED;
10658
10659 auto ProcessCallInst = [&](Instruction &Inst) {
10660 CallBase &CB = cast<CallBase>(Inst);
10661
10662 auto *CBEdges = A.getAAFor<AACallEdges>(
10663 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10664 if (!CBEdges)
10665 return false;
10666 if (CBEdges->hasNonAsmUnknownCallee())
10667 setHasUnknownCallee(true, Change);
10668 if (CBEdges->hasUnknownCallee())
10669 setHasUnknownCallee(false, Change);
10670
10671 for (Function *F : CBEdges->getOptimisticEdges())
10672 addCalledFunction(F, Change);
10673
10674 return true;
10675 };
10676
10677 // Visit all callable instructions.
10678 bool UsedAssumedInformation = false;
10679 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10680 UsedAssumedInformation,
10681 /* CheckBBLivenessOnly */ true)) {
10682 // If we haven't looked at all call like instructions, assume that there
10683 // are unknown callees.
10684 setHasUnknownCallee(true, Change);
10685 }
10686
10687 return Change;
10688 }
10689};
10690
10691/// -------------------AAInterFnReachability Attribute--------------------------
10692
10693struct AAInterFnReachabilityFunction
10694 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10695 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10696 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10697 : Base(IRP, A) {}
10698
10699 bool instructionCanReach(
10700 Attributor &A, const Instruction &From, const Function &To,
10701 const AA::InstExclusionSetTy *ExclusionSet) const override {
10702 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10703 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10704
10705 RQITy StackRQI(A, From, To, ExclusionSet, false);
10706 typename RQITy::Reachable Result;
10707 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10708 return NonConstThis->isReachableImpl(A, StackRQI,
10709 /*IsTemporaryRQI=*/true);
10710 return Result == RQITy::Reachable::Yes;
10711 }
10712
10713 bool isReachableImpl(Attributor &A, RQITy &RQI,
10714 bool IsTemporaryRQI) override {
10715 const Instruction *EntryI =
10716 &RQI.From->getFunction()->getEntryBlock().front();
10717 if (EntryI != RQI.From &&
10718 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10719 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10720 IsTemporaryRQI);
10721
10722 auto CheckReachableCallBase = [&](CallBase *CB) {
10723 auto *CBEdges = A.getAAFor<AACallEdges>(
10724 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10725 if (!CBEdges || !CBEdges->getState().isValidState())
10726 return false;
10727 // TODO Check To backwards in this case.
10728 if (CBEdges->hasUnknownCallee())
10729 return false;
10730
10731 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10732 if (Fn == RQI.To)
10733 return false;
10734
10735 if (Fn->isDeclaration()) {
10736 if (Fn->hasFnAttribute(Attribute::NoCallback))
10737 continue;
10738 // TODO Check To backwards in this case.
10739 return false;
10740 }
10741
10742 if (Fn == getAnchorScope()) {
10743 if (EntryI == RQI.From)
10744 continue;
10745 return false;
10746 }
10747
10748 const AAInterFnReachability *InterFnReachability =
10749 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10750 DepClassTy::OPTIONAL);
10751
10752 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10753 if (!InterFnReachability ||
10754 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10755 RQI.ExclusionSet))
10756 return false;
10757 }
10758 return true;
10759 };
10760
10761 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10762 *this, IRPosition::function(*RQI.From->getFunction()),
10763 DepClassTy::OPTIONAL);
10764
10765 // Determine call like instructions that we can reach from the inst.
10766 auto CheckCallBase = [&](Instruction &CBInst) {
10767 // There are usually less nodes in the call graph, check inter function
10768 // reachability first.
10769 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10770 return true;
10771 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10772 A, *RQI.From, CBInst, RQI.ExclusionSet);
10773 };
10774
10775 bool UsedExclusionSet = /* conservative */ true;
10776 bool UsedAssumedInformation = false;
10777 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10778 UsedAssumedInformation,
10779 /* CheckBBLivenessOnly */ true))
10780 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10781 IsTemporaryRQI);
10782
10783 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10784 IsTemporaryRQI);
10785 }
10786
10787 void trackStatistics() const override {}
10788};
10789} // namespace
10790
10791template <typename AAType>
10792static std::optional<Constant *>
10794 const IRPosition &IRP, Type &Ty) {
10795 if (!Ty.isIntegerTy())
10796 return nullptr;
10797
10798 // This will also pass the call base context.
10799 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10800 if (!AA)
10801 return nullptr;
10802
10803 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10804
10805 if (!COpt.has_value()) {
10806 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10807 return std::nullopt;
10808 }
10809 if (auto *C = *COpt) {
10810 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10811 return C;
10812 }
10813 return nullptr;
10814}
10815
10817 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10819 Type &Ty = *IRP.getAssociatedType();
10820 std::optional<Value *> V;
10821 for (auto &It : Values) {
10822 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10823 if (V.has_value() && !*V)
10824 break;
10825 }
10826 if (!V.has_value())
10827 return UndefValue::get(&Ty);
10828 return *V;
10829}
10830
10831namespace {
10832struct AAPotentialValuesImpl : AAPotentialValues {
10833 using StateType = PotentialLLVMValuesState;
10834
10835 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10836 : AAPotentialValues(IRP, A) {}
10837
10838 /// See AbstractAttribute::initialize(..).
10839 void initialize(Attributor &A) override {
10840 if (A.hasSimplificationCallback(getIRPosition())) {
10841 indicatePessimisticFixpoint();
10842 return;
10843 }
10844 Value *Stripped = getAssociatedValue().stripPointerCasts();
10845 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10846 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10847 getAnchorScope());
10848 indicateOptimisticFixpoint();
10849 return;
10850 }
10851 AAPotentialValues::initialize(A);
10852 }
10853
10854 /// See AbstractAttribute::getAsStr().
10855 const std::string getAsStr(Attributor *A) const override {
10856 std::string Str;
10857 llvm::raw_string_ostream OS(Str);
10858 OS << getState();
10859 return Str;
10860 }
10861
10862 template <typename AAType>
10863 static std::optional<Value *> askOtherAA(Attributor &A,
10864 const AbstractAttribute &AA,
10865 const IRPosition &IRP, Type &Ty) {
10867 return &IRP.getAssociatedValue();
10868 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10869 if (!C)
10870 return std::nullopt;
10871 if (*C)
10872 if (auto *CC = AA::getWithType(**C, Ty))
10873 return CC;
10874 return nullptr;
10875 }
10876
10877 virtual void addValue(Attributor &A, StateType &State, Value &V,
10878 const Instruction *CtxI, AA::ValueScope S,
10879 Function *AnchorScope) const {
10880
10881 IRPosition ValIRP = IRPosition::value(V);
10882 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10883 for (const auto &U : CB->args()) {
10884 if (U.get() != &V)
10885 continue;
10886 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10887 break;
10888 }
10889 }
10890
10891 Value *VPtr = &V;
10892 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10893 Type &Ty = *getAssociatedType();
10894 std::optional<Value *> SimpleV =
10895 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10896 if (SimpleV.has_value() && !*SimpleV) {
10897 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10898 *this, ValIRP, DepClassTy::OPTIONAL);
10899 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10900 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10901 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10902 if (PotentialConstantsAA->undefIsContained())
10903 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10904 return;
10905 }
10906 }
10907 if (!SimpleV.has_value())
10908 return;
10909
10910 if (*SimpleV)
10911 VPtr = *SimpleV;
10912 }
10913
10914 if (isa<ConstantInt>(VPtr))
10915 CtxI = nullptr;
10916 if (!AA::isValidInScope(*VPtr, AnchorScope))
10918
10919 State.unionAssumed({{*VPtr, CtxI}, S});
10920 }
10921
10922 /// Helper struct to tie a value+context pair together with the scope for
10923 /// which this is the simplified version.
10924 struct ItemInfo {
10925 AA::ValueAndContext I;
10927
10928 bool operator==(const ItemInfo &II) const {
10929 return II.I == I && II.S == S;
10930 };
10931 bool operator<(const ItemInfo &II) const {
10932 return std::tie(I, S) < std::tie(II.I, II.S);
10933 };
10934 };
10935
10936 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10937 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
10938 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10939 if (!(CS & S))
10940 continue;
10941
10942 bool UsedAssumedInformation = false;
10944 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10945 UsedAssumedInformation))
10946 return false;
10947
10948 for (auto &It : Values)
10949 ValueScopeMap[It] += CS;
10950 }
10951 for (auto &It : ValueScopeMap)
10952 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
10953 AA::ValueScope(It.second), getAnchorScope());
10954
10955 return true;
10956 }
10957
10958 void giveUpOnIntraprocedural(Attributor &A) {
10959 auto NewS = StateType::getBestState(getState());
10960 for (const auto &It : getAssumedSet()) {
10961 if (It.second == AA::Intraprocedural)
10962 continue;
10963 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
10964 AA::Interprocedural, getAnchorScope());
10965 }
10966 assert(!undefIsContained() && "Undef should be an explicit value!");
10967 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
10968 getAnchorScope());
10969 getState() = NewS;
10970 }
10971
10972 /// See AbstractState::indicatePessimisticFixpoint(...).
10973 ChangeStatus indicatePessimisticFixpoint() override {
10974 getState() = StateType::getBestState(getState());
10975 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
10976 AAPotentialValues::indicateOptimisticFixpoint();
10977 return ChangeStatus::CHANGED;
10978 }
10979
10980 /// See AbstractAttribute::updateImpl(...).
10981 ChangeStatus updateImpl(Attributor &A) override {
10982 return indicatePessimisticFixpoint();
10983 }
10984
10985 /// See AbstractAttribute::manifest(...).
10986 ChangeStatus manifest(Attributor &A) override {
10989 Values.clear();
10990 if (!getAssumedSimplifiedValues(A, Values, S))
10991 continue;
10992 Value &OldV = getAssociatedValue();
10993 if (isa<UndefValue>(OldV))
10994 continue;
10995 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
10996 if (!NewV || NewV == &OldV)
10997 continue;
10998 if (getCtxI() &&
10999 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11000 continue;
11001 if (A.changeAfterManifest(getIRPosition(), *NewV))
11002 return ChangeStatus::CHANGED;
11003 }
11004 return ChangeStatus::UNCHANGED;
11005 }
11006
11007 bool getAssumedSimplifiedValues(
11008 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11009 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11010 if (!isValidState())
11011 return false;
11012 bool UsedAssumedInformation = false;
11013 for (const auto &It : getAssumedSet())
11014 if (It.second & S) {
11015 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11016 isa<SelectInst>(It.first.getValue()))) {
11017 if (A.getAssumedSimplifiedValues(
11018 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11019 this, Values, S, UsedAssumedInformation))
11020 continue;
11021 }
11022 Values.push_back(It.first);
11023 }
11024 assert(!undefIsContained() && "Undef should be an explicit value!");
11025 return true;
11026 }
11027};
11028
11029struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11030 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11031 : AAPotentialValuesImpl(IRP, A) {}
11032
11033 /// See AbstractAttribute::updateImpl(...).
11034 ChangeStatus updateImpl(Attributor &A) override {
11035 auto AssumedBefore = getAssumed();
11036
11037 genericValueTraversal(A, &getAssociatedValue());
11038
11039 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11040 : ChangeStatus::CHANGED;
11041 }
11042
11043 /// Helper struct to remember which AAIsDead instances we actually used.
11044 struct LivenessInfo {
11045 const AAIsDead *LivenessAA = nullptr;
11046 bool AnyDead = false;
11047 };
11048
11049 /// Check if \p Cmp is a comparison we can simplify.
11050 ///
11051 /// We handle multiple cases, one in which at least one operand is an
11052 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11053 /// operand. Return true if successful, in that case Worklist will be updated.
11054 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11055 CmpInst::Predicate Pred, ItemInfo II,
11056 SmallVectorImpl<ItemInfo> &Worklist) {
11057
11058 // Simplify the operands first.
11059 bool UsedAssumedInformation = false;
11060 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11061 auto GetSimplifiedValues = [&](Value &V,
11063 if (!A.getAssumedSimplifiedValues(
11064 IRPosition::value(V, getCallBaseContext()), this, Values,
11065 AA::Intraprocedural, UsedAssumedInformation)) {
11066 Values.clear();
11067 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11068 }
11069 return Values.empty();
11070 };
11071 if (GetSimplifiedValues(*LHS, LHSValues))
11072 return true;
11073 if (GetSimplifiedValues(*RHS, RHSValues))
11074 return true;
11075
11076 LLVMContext &Ctx = LHS->getContext();
11077
11078 InformationCache &InfoCache = A.getInfoCache();
11079 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11080 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11081 const auto *DT =
11082 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11083 : nullptr;
11084 const auto *TLI =
11085 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11086 auto *AC =
11087 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11088 : nullptr;
11089
11090 const DataLayout &DL = A.getDataLayout();
11091 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11092
11093 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11094 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11095 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11096 /* CtxI */ nullptr, II.S, getAnchorScope());
11097 return true;
11098 }
11099
11100 // Handle the trivial case first in which we don't even need to think
11101 // about null or non-null.
11102 if (&LHSV == &RHSV &&
11104 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11106 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11107 getAnchorScope());
11108 return true;
11109 }
11110
11111 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11112 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11113 if (TypedLHS && TypedRHS) {
11114 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11115 if (NewV && NewV != &Cmp) {
11116 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11117 getAnchorScope());
11118 return true;
11119 }
11120 }
11121
11122 // From now on we only handle equalities (==, !=).
11123 if (!CmpInst::isEquality(Pred))
11124 return false;
11125
11126 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11127 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11128 if (!LHSIsNull && !RHSIsNull)
11129 return false;
11130
11131 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11132 // non-nullptr operand and if we assume it's non-null we can conclude the
11133 // result of the comparison.
11134 assert((LHSIsNull || RHSIsNull) &&
11135 "Expected nullptr versus non-nullptr comparison at this point");
11136
11137 // The index is the operand that we assume is not null.
11138 unsigned PtrIdx = LHSIsNull;
11139 bool IsKnownNonNull;
11140 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11141 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11142 DepClassTy::REQUIRED, IsKnownNonNull);
11143 if (!IsAssumedNonNull)
11144 return false;
11145
11146 // The new value depends on the predicate, true for != and false for ==.
11147 Constant *NewV =
11148 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11149 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11150 getAnchorScope());
11151 return true;
11152 };
11153
11154 for (auto &LHSValue : LHSValues)
11155 for (auto &RHSValue : RHSValues)
11156 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11157 return false;
11158 return true;
11159 }
11160
11161 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11162 SmallVectorImpl<ItemInfo> &Worklist) {
11163 const Instruction *CtxI = II.I.getCtxI();
11164 bool UsedAssumedInformation = false;
11165
11166 std::optional<Constant *> C =
11167 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11168 bool NoValueYet = !C.has_value();
11169 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11170 return true;
11171 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11172 if (CI->isZero())
11173 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11174 else
11175 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11176 } else if (&SI == &getAssociatedValue()) {
11177 // We could not simplify the condition, assume both values.
11178 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11179 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11180 } else {
11181 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11182 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11183 if (!SimpleV.has_value())
11184 return true;
11185 if (*SimpleV) {
11186 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11187 return true;
11188 }
11189 return false;
11190 }
11191 return true;
11192 }
11193
11194 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11195 SmallVectorImpl<ItemInfo> &Worklist) {
11196 SmallSetVector<Value *, 4> PotentialCopies;
11197 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11198 bool UsedAssumedInformation = false;
11199 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11200 PotentialValueOrigins, *this,
11201 UsedAssumedInformation,
11202 /* OnlyExact */ true)) {
11203 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11204 "loaded values for load instruction "
11205 << LI << "\n");
11206 return false;
11207 }
11208
11209 // Do not simplify loads that are only used in llvm.assume if we cannot also
11210 // remove all stores that may feed into the load. The reason is that the
11211 // assume is probably worth something as long as the stores are around.
11212 InformationCache &InfoCache = A.getInfoCache();
11213 if (InfoCache.isOnlyUsedByAssume(LI)) {
11214 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11215 if (!I || isa<AssumeInst>(I))
11216 return true;
11217 if (auto *SI = dyn_cast<StoreInst>(I))
11218 return A.isAssumedDead(SI->getOperandUse(0), this,
11219 /* LivenessAA */ nullptr,
11220 UsedAssumedInformation,
11221 /* CheckBBLivenessOnly */ false);
11222 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11223 UsedAssumedInformation,
11224 /* CheckBBLivenessOnly */ false);
11225 })) {
11226 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11227 "and we cannot delete all the stores: "
11228 << LI << "\n");
11229 return false;
11230 }
11231 }
11232
11233 // Values have to be dynamically unique or we loose the fact that a
11234 // single llvm::Value might represent two runtime values (e.g.,
11235 // stack locations in different recursive calls).
11236 const Instruction *CtxI = II.I.getCtxI();
11237 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11238 bool AllLocal = ScopeIsLocal;
11239 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11240 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11241 return AA::isDynamicallyUnique(A, *this, *PC);
11242 });
11243 if (!DynamicallyUnique) {
11244 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11245 "values are dynamically unique: "
11246 << LI << "\n");
11247 return false;
11248 }
11249
11250 for (auto *PotentialCopy : PotentialCopies) {
11251 if (AllLocal) {
11252 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11253 } else {
11254 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11255 }
11256 }
11257 if (!AllLocal && ScopeIsLocal)
11258 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11259 return true;
11260 }
11261
11262 bool handlePHINode(
11263 Attributor &A, PHINode &PHI, ItemInfo II,
11264 SmallVectorImpl<ItemInfo> &Worklist,
11265 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11266 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11267 LivenessInfo &LI = LivenessAAs[&F];
11268 if (!LI.LivenessAA)
11269 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11270 DepClassTy::NONE);
11271 return LI;
11272 };
11273
11274 if (&PHI == &getAssociatedValue()) {
11275 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11276 const auto *CI =
11277 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11278 *PHI.getFunction());
11279
11280 Cycle *C = nullptr;
11281 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11282 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11283 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11284 if (LI.LivenessAA &&
11285 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11286 LI.AnyDead = true;
11287 continue;
11288 }
11289 Value *V = PHI.getIncomingValue(u);
11290 if (V == &PHI)
11291 continue;
11292
11293 // If the incoming value is not the PHI but an instruction in the same
11294 // cycle we might have multiple versions of it flying around.
11295 if (CyclePHI && isa<Instruction>(V) &&
11296 (!C || C->contains(cast<Instruction>(V)->getParent())))
11297 return false;
11298
11299 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11300 }
11301 return true;
11302 }
11303
11304 bool UsedAssumedInformation = false;
11305 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11306 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11307 if (!SimpleV.has_value())
11308 return true;
11309 if (!(*SimpleV))
11310 return false;
11311 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11312 return true;
11313 }
11314
11315 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11316 /// simplify any operand of the instruction \p I. Return true if successful,
11317 /// in that case Worklist will be updated.
11318 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11319 SmallVectorImpl<ItemInfo> &Worklist) {
11320 bool SomeSimplified = false;
11321 bool UsedAssumedInformation = false;
11322
11323 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11324 int Idx = 0;
11325 for (Value *Op : I.operands()) {
11326 const auto &SimplifiedOp = A.getAssumedSimplified(
11327 IRPosition::value(*Op, getCallBaseContext()), *this,
11328 UsedAssumedInformation, AA::Intraprocedural);
11329 // If we are not sure about any operand we are not sure about the entire
11330 // instruction, we'll wait.
11331 if (!SimplifiedOp.has_value())
11332 return true;
11333
11334 if (*SimplifiedOp)
11335 NewOps[Idx] = *SimplifiedOp;
11336 else
11337 NewOps[Idx] = Op;
11338
11339 SomeSimplified |= (NewOps[Idx] != Op);
11340 ++Idx;
11341 }
11342
11343 // We won't bother with the InstSimplify interface if we didn't simplify any
11344 // operand ourselves.
11345 if (!SomeSimplified)
11346 return false;
11347
11348 InformationCache &InfoCache = A.getInfoCache();
11349 Function *F = I.getFunction();
11350 const auto *DT =
11351 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11352 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11353 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11354
11355 const DataLayout &DL = I.getDataLayout();
11356 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11357 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11358 if (!NewV || NewV == &I)
11359 return false;
11360
11361 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11362 << *NewV << "\n");
11363 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11364 return true;
11365 }
11366
11368 Attributor &A, Instruction &I, ItemInfo II,
11369 SmallVectorImpl<ItemInfo> &Worklist,
11370 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11371 if (auto *CI = dyn_cast<CmpInst>(&I))
11372 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11373 CI->getPredicate(), II, Worklist);
11374
11375 switch (I.getOpcode()) {
11376 case Instruction::Select:
11377 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11378 case Instruction::PHI:
11379 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11380 case Instruction::Load:
11381 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11382 default:
11383 return handleGenericInst(A, I, II, Worklist);
11384 };
11385 return false;
11386 }
11387
11388 void genericValueTraversal(Attributor &A, Value *InitialV) {
11389 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11390
11391 SmallSet<ItemInfo, 16> Visited;
11393 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11394
11395 int Iteration = 0;
11396 do {
11397 ItemInfo II = Worklist.pop_back_val();
11398 Value *V = II.I.getValue();
11399 assert(V);
11400 const Instruction *CtxI = II.I.getCtxI();
11401 AA::ValueScope S = II.S;
11402
11403 // Check if we should process the current value. To prevent endless
11404 // recursion keep a record of the values we followed!
11405 if (!Visited.insert(II).second)
11406 continue;
11407
11408 // Make sure we limit the compile time for complex expressions.
11409 if (Iteration++ >= MaxPotentialValuesIterations) {
11410 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11411 << Iteration << "!\n");
11412 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11413 continue;
11414 }
11415
11416 // Explicitly look through calls with a "returned" attribute if we do
11417 // not have a pointer as stripPointerCasts only works on them.
11418 Value *NewV = nullptr;
11419 if (V->getType()->isPointerTy()) {
11420 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11421 } else {
11422 if (auto *CB = dyn_cast<CallBase>(V))
11423 if (auto *Callee =
11425 for (Argument &Arg : Callee->args())
11426 if (Arg.hasReturnedAttr()) {
11427 NewV = CB->getArgOperand(Arg.getArgNo());
11428 break;
11429 }
11430 }
11431 }
11432 if (NewV && NewV != V) {
11433 Worklist.push_back({{*NewV, CtxI}, S});
11434 continue;
11435 }
11436
11437 if (auto *I = dyn_cast<Instruction>(V)) {
11438 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11439 continue;
11440 }
11441
11442 if (V != InitialV || isa<Argument>(V))
11443 if (recurseForValue(A, IRPosition::value(*V), II.S))
11444 continue;
11445
11446 // If we haven't stripped anything we give up.
11447 if (V == InitialV && CtxI == getCtxI()) {
11448 indicatePessimisticFixpoint();
11449 return;
11450 }
11451
11452 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11453 } while (!Worklist.empty());
11454
11455 // If we actually used liveness information so we have to record a
11456 // dependence.
11457 for (auto &It : LivenessAAs)
11458 if (It.second.AnyDead)
11459 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11460 }
11461
11462 /// See AbstractAttribute::trackStatistics()
11463 void trackStatistics() const override {
11464 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11465 }
11466};
11467
11468struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11469 using Base = AAPotentialValuesImpl;
11470 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11471 : Base(IRP, A) {}
11472
11473 /// See AbstractAttribute::initialize(..).
11474 void initialize(Attributor &A) override {
11475 auto &Arg = cast<Argument>(getAssociatedValue());
11477 indicatePessimisticFixpoint();
11478 }
11479
11480 /// See AbstractAttribute::updateImpl(...).
11481 ChangeStatus updateImpl(Attributor &A) override {
11482 auto AssumedBefore = getAssumed();
11483
11484 unsigned ArgNo = getCalleeArgNo();
11485
11486 bool UsedAssumedInformation = false;
11488 auto CallSitePred = [&](AbstractCallSite ACS) {
11489 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11490 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11491 return false;
11492
11493 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11495 UsedAssumedInformation))
11496 return false;
11497
11498 return isValidState();
11499 };
11500
11501 if (!A.checkForAllCallSites(CallSitePred, *this,
11502 /* RequireAllCallSites */ true,
11503 UsedAssumedInformation))
11504 return indicatePessimisticFixpoint();
11505
11506 Function *Fn = getAssociatedFunction();
11507 bool AnyNonLocal = false;
11508 for (auto &It : Values) {
11509 if (isa<Constant>(It.getValue())) {
11510 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11511 getAnchorScope());
11512 continue;
11513 }
11514 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11515 return indicatePessimisticFixpoint();
11516
11517 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11518 if (Arg->getParent() == Fn) {
11519 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11520 getAnchorScope());
11521 continue;
11522 }
11523 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11524 getAnchorScope());
11525 AnyNonLocal = true;
11526 }
11527 assert(!undefIsContained() && "Undef should be an explicit value!");
11528 if (AnyNonLocal)
11529 giveUpOnIntraprocedural(A);
11530
11531 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11532 : ChangeStatus::CHANGED;
11533 }
11534
11535 /// See AbstractAttribute::trackStatistics()
11536 void trackStatistics() const override {
11537 STATS_DECLTRACK_ARG_ATTR(potential_values)
11538 }
11539};
11540
11541struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11542 using Base = AAPotentialValuesFloating;
11543 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11544 : Base(IRP, A) {}
11545
11546 /// See AbstractAttribute::initialize(..).
11547 void initialize(Attributor &A) override {
11548 Function *F = getAssociatedFunction();
11549 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11550 indicatePessimisticFixpoint();
11551 return;
11552 }
11553
11554 for (Argument &Arg : F->args())
11555 if (Arg.hasReturnedAttr()) {
11556 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11557 ReturnedArg = &Arg;
11558 break;
11559 }
11560 if (!A.isFunctionIPOAmendable(*F) ||
11561 A.hasSimplificationCallback(getIRPosition())) {
11562 if (!ReturnedArg)
11563 indicatePessimisticFixpoint();
11564 else
11565 indicateOptimisticFixpoint();
11566 }
11567 }
11568
11569 /// See AbstractAttribute::updateImpl(...).
11570 ChangeStatus updateImpl(Attributor &A) override {
11571 auto AssumedBefore = getAssumed();
11572 bool UsedAssumedInformation = false;
11573
11575 Function *AnchorScope = getAnchorScope();
11576 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11577 bool AddValues) {
11579 Values.clear();
11580 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11581 UsedAssumedInformation,
11582 /* RecurseForSelectAndPHI */ true))
11583 return false;
11584 if (!AddValues)
11585 continue;
11586
11587 bool AllInterAreIntra = false;
11588 if (S == AA::Interprocedural)
11589 AllInterAreIntra =
11590 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11591 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11592 });
11593
11594 for (const AA::ValueAndContext &VAC : Values) {
11595 addValue(A, getState(), *VAC.getValue(),
11596 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11597 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11598 }
11599 if (AllInterAreIntra)
11600 break;
11601 }
11602 return true;
11603 };
11604
11605 if (ReturnedArg) {
11606 HandleReturnedValue(*ReturnedArg, nullptr, true);
11607 } else {
11608 auto RetInstPred = [&](Instruction &RetI) {
11609 bool AddValues = true;
11610 if (isa<PHINode>(RetI.getOperand(0)) ||
11611 isa<SelectInst>(RetI.getOperand(0))) {
11612 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11613 AnchorScope);
11614 AddValues = false;
11615 }
11616 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11617 };
11618
11619 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11620 UsedAssumedInformation,
11621 /* CheckBBLivenessOnly */ true))
11622 return indicatePessimisticFixpoint();
11623 }
11624
11625 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11626 : ChangeStatus::CHANGED;
11627 }
11628
11629 ChangeStatus manifest(Attributor &A) override {
11630 if (ReturnedArg)
11631 return ChangeStatus::UNCHANGED;
11633 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11634 /* RecurseForSelectAndPHI */ true))
11635 return ChangeStatus::UNCHANGED;
11636 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11637 if (!NewVal)
11638 return ChangeStatus::UNCHANGED;
11639
11640 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11641 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11642 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11643 "Number of function with unique return");
11644 Changed |= A.manifestAttrs(
11646 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11647 STATS_DECLTRACK_ARG_ATTR(returned);
11648 }
11649
11650 auto RetInstPred = [&](Instruction &RetI) {
11651 Value *RetOp = RetI.getOperand(0);
11652 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11653 return true;
11654 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11655 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11656 Changed = ChangeStatus::CHANGED;
11657 return true;
11658 };
11659 bool UsedAssumedInformation = false;
11660 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11661 UsedAssumedInformation,
11662 /* CheckBBLivenessOnly */ true);
11663 return Changed;
11664 }
11665
11666 ChangeStatus indicatePessimisticFixpoint() override {
11667 return AAPotentialValues::indicatePessimisticFixpoint();
11668 }
11669
11670 /// See AbstractAttribute::trackStatistics()
11671 void trackStatistics() const override{
11672 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11673
11674 /// The argumented with an existing `returned` attribute.
11675 Argument *ReturnedArg = nullptr;
11676};
11677
11678struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11679 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11680 : AAPotentialValuesImpl(IRP, A) {}
11681
11682 /// See AbstractAttribute::updateImpl(...).
11683 ChangeStatus updateImpl(Attributor &A) override {
11684 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11685 "not be called");
11686 }
11687
11688 /// See AbstractAttribute::trackStatistics()
11689 void trackStatistics() const override {
11690 STATS_DECLTRACK_FN_ATTR(potential_values)
11691 }
11692};
11693
11694struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11695 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11696 : AAPotentialValuesFunction(IRP, A) {}
11697
11698 /// See AbstractAttribute::trackStatistics()
11699 void trackStatistics() const override {
11700 STATS_DECLTRACK_CS_ATTR(potential_values)
11701 }
11702};
11703
11704struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11705 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11706 : AAPotentialValuesImpl(IRP, A) {}
11707
11708 /// See AbstractAttribute::updateImpl(...).
11709 ChangeStatus updateImpl(Attributor &A) override {
11710 auto AssumedBefore = getAssumed();
11711
11712 Function *Callee = getAssociatedFunction();
11713 if (!Callee)
11714 return indicatePessimisticFixpoint();
11715
11716 bool UsedAssumedInformation = false;
11717 auto *CB = cast<CallBase>(getCtxI());
11718 if (CB->isMustTailCall() &&
11719 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11720 UsedAssumedInformation))
11721 return indicatePessimisticFixpoint();
11722
11723 Function *Caller = CB->getCaller();
11724
11725 auto AddScope = [&](AA::ValueScope S) {
11727 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11728 Values, S, UsedAssumedInformation))
11729 return false;
11730
11731 for (auto &It : Values) {
11732 Value *V = It.getValue();
11733 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11734 V, *CB, *this, UsedAssumedInformation);
11735 if (!CallerV.has_value()) {
11736 // Nothing to do as long as no value was determined.
11737 continue;
11738 }
11739 V = *CallerV ? *CallerV : V;
11740 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11741 if (recurseForValue(A, IRPosition::value(*V), S))
11742 continue;
11743 }
11744 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11745 giveUpOnIntraprocedural(A);
11746 return true;
11747 }
11748 addValue(A, getState(), *V, CB, S, getAnchorScope());
11749 }
11750 return true;
11751 };
11752 if (!AddScope(AA::Intraprocedural))
11753 return indicatePessimisticFixpoint();
11754 if (!AddScope(AA::Interprocedural))
11755 return indicatePessimisticFixpoint();
11756 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11757 : ChangeStatus::CHANGED;
11758 }
11759
11760 ChangeStatus indicatePessimisticFixpoint() override {
11761 return AAPotentialValues::indicatePessimisticFixpoint();
11762 }
11763
11764 /// See AbstractAttribute::trackStatistics()
11765 void trackStatistics() const override {
11766 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11767 }
11768};
11769
11770struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11771 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11772 : AAPotentialValuesFloating(IRP, A) {}
11773
11774 /// See AbstractAttribute::trackStatistics()
11775 void trackStatistics() const override {
11776 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11777 }
11778};
11779} // namespace
11780
11781/// ---------------------- Assumption Propagation ------------------------------
11782namespace {
11783struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11784 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11785 const DenseSet<StringRef> &Known)
11786 : AAAssumptionInfo(IRP, A, Known) {}
11787
11788 /// See AbstractAttribute::manifest(...).
11789 ChangeStatus manifest(Attributor &A) override {
11790 // Don't manifest a universal set if it somehow made it here.
11791 if (getKnown().isUniversal())
11792 return ChangeStatus::UNCHANGED;
11793
11794 const IRPosition &IRP = getIRPosition();
11795 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11796 getAssumed().getSet().end());
11797 llvm::sort(Set);
11798 return A.manifestAttrs(IRP,
11799 Attribute::get(IRP.getAnchorValue().getContext(),
11801 llvm::join(Set, ",")),
11802 /*ForceReplace=*/true);
11803 }
11804
11805 bool hasAssumption(const StringRef Assumption) const override {
11806 return isValidState() && setContains(Assumption);
11807 }
11808
11809 /// See AbstractAttribute::getAsStr()
11810 const std::string getAsStr(Attributor *A) const override {
11811 const SetContents &Known = getKnown();
11812 const SetContents &Assumed = getAssumed();
11813
11814 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11815 llvm::sort(Set);
11816 const std::string KnownStr = llvm::join(Set, ",");
11817
11818 std::string AssumedStr = "Universal";
11819 if (!Assumed.isUniversal()) {
11820 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11821 AssumedStr = llvm::join(Set, ",");
11822 }
11823 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11824 }
11825};
11826
11827/// Propagates assumption information from parent functions to all of their
11828/// successors. An assumption can be propagated if the containing function
11829/// dominates the called function.
11830///
11831/// We start with a "known" set of assumptions already valid for the associated
11832/// function and an "assumed" set that initially contains all possible
11833/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11834/// contents as concrete values are known. The concrete values are seeded by the
11835/// first nodes that are either entries into the call graph, or contains no
11836/// assumptions. Each node is updated as the intersection of the assumed state
11837/// with all of its predecessors.
11838struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11839 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11840 : AAAssumptionInfoImpl(IRP, A,
11841 getAssumptions(*IRP.getAssociatedFunction())) {}
11842
11843 /// See AbstractAttribute::updateImpl(...).
11844 ChangeStatus updateImpl(Attributor &A) override {
11845 bool Changed = false;
11846
11847 auto CallSitePred = [&](AbstractCallSite ACS) {
11848 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11849 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11850 DepClassTy::REQUIRED);
11851 if (!AssumptionAA)
11852 return false;
11853 // Get the set of assumptions shared by all of this function's callers.
11854 Changed |= getIntersection(AssumptionAA->getAssumed());
11855 return !getAssumed().empty() || !getKnown().empty();
11856 };
11857
11858 bool UsedAssumedInformation = false;
11859 // Get the intersection of all assumptions held by this node's predecessors.
11860 // If we don't know all the call sites then this is either an entry into the
11861 // call graph or an empty node. This node is known to only contain its own
11862 // assumptions and can be propagated to its successors.
11863 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11864 UsedAssumedInformation))
11865 return indicatePessimisticFixpoint();
11866
11867 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11868 }
11869
11870 void trackStatistics() const override {}
11871};
11872
11873/// Assumption Info defined for call sites.
11874struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11875
11876 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11877 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11878
11879 /// See AbstractAttribute::initialize(...).
11880 void initialize(Attributor &A) override {
11881 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11882 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11883 }
11884
11885 /// See AbstractAttribute::updateImpl(...).
11886 ChangeStatus updateImpl(Attributor &A) override {
11887 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11888 auto *AssumptionAA =
11889 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11890 if (!AssumptionAA)
11891 return indicatePessimisticFixpoint();
11892 bool Changed = getIntersection(AssumptionAA->getAssumed());
11893 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11894 }
11895
11896 /// See AbstractAttribute::trackStatistics()
11897 void trackStatistics() const override {}
11898
11899private:
11900 /// Helper to initialized the known set as all the assumptions this call and
11901 /// the callee contain.
11902 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11903 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11904 auto Assumptions = getAssumptions(CB);
11905 if (const Function *F = CB.getCaller())
11906 set_union(Assumptions, getAssumptions(*F));
11907 if (Function *F = IRP.getAssociatedFunction())
11908 set_union(Assumptions, getAssumptions(*F));
11909 return Assumptions;
11910 }
11911};
11912} // namespace
11913
11915 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11916 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11917}
11918
11920
11921/// ------------------------ UnderlyingObjects ---------------------------------
11922
11923namespace {
11924struct AAUnderlyingObjectsImpl
11925 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11927 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11928
11929 /// See AbstractAttribute::getAsStr().
11930 const std::string getAsStr(Attributor *A) const override {
11931 if (!isValidState())
11932 return "<invalid>";
11933 std::string Str;
11935 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
11936 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
11937 << " objects.\n";
11938 if (!InterAssumedUnderlyingObjects.empty()) {
11939 OS << "inter objects:\n";
11940 for (auto *Obj : InterAssumedUnderlyingObjects)
11941 OS << *Obj << '\n';
11942 }
11943 if (!IntraAssumedUnderlyingObjects.empty()) {
11944 OS << "intra objects:\n";
11945 for (auto *Obj : IntraAssumedUnderlyingObjects)
11946 OS << *Obj << '\n';
11947 }
11948 return Str;
11949 }
11950
11951 /// See AbstractAttribute::trackStatistics()
11952 void trackStatistics() const override {}
11953
11954 /// See AbstractAttribute::updateImpl(...).
11955 ChangeStatus updateImpl(Attributor &A) override {
11956 auto &Ptr = getAssociatedValue();
11957
11958 bool UsedAssumedInformation = false;
11959 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
11961 SmallPtrSet<Value *, 8> SeenObjects;
11963
11964 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
11965 Scope, UsedAssumedInformation))
11966 return UnderlyingObjects.insert(&Ptr);
11967
11968 bool Changed = false;
11969
11970 for (unsigned I = 0; I < Values.size(); ++I) {
11971 auto &VAC = Values[I];
11972 auto *Obj = VAC.getValue();
11973 Value *UO = getUnderlyingObject(Obj);
11974 if (!SeenObjects.insert(UO ? UO : Obj).second)
11975 continue;
11976 if (UO && UO != Obj) {
11977 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
11978 Changed |= UnderlyingObjects.insert(UO);
11979 continue;
11980 }
11981
11982 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
11983 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
11984 auto Pred = [&](Value &V) {
11985 if (&V == UO)
11986 Changed |= UnderlyingObjects.insert(UO);
11987 else
11988 Values.emplace_back(V, nullptr);
11989 return true;
11990 };
11991
11992 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
11994 "The forall call should not return false at this position");
11995 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
11996 continue;
11997 }
11998
11999 if (isa<SelectInst>(Obj)) {
12000 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12001 UsedAssumedInformation);
12002 continue;
12003 }
12004 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12005 // Explicitly look through PHIs as we do not care about dynamically
12006 // uniqueness.
12007 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12008 Changed |=
12009 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12010 Scope, UsedAssumedInformation);
12011 }
12012 continue;
12013 }
12014
12015 Changed |= UnderlyingObjects.insert(Obj);
12016 }
12017
12018 return Changed;
12019 };
12020
12021 bool Changed = false;
12022 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12023 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12024 if (!UsedAssumedInformation)
12025 indicateOptimisticFixpoint();
12026 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12027 }
12028
12029 bool forallUnderlyingObjects(
12030 function_ref<bool(Value &)> Pred,
12031 AA::ValueScope Scope = AA::Interprocedural) const override {
12032 if (!isValidState())
12033 return Pred(getAssociatedValue());
12034
12035 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12036 ? IntraAssumedUnderlyingObjects
12037 : InterAssumedUnderlyingObjects;
12038 for (Value *Obj : AssumedUnderlyingObjects)
12039 if (!Pred(*Obj))
12040 return false;
12041
12042 return true;
12043 }
12044
12045private:
12046 /// Handle the case where the value is not the actual underlying value, such
12047 /// as a phi node or a select instruction.
12048 bool handleIndirect(Attributor &A, Value &V,
12049 SmallSetVector<Value *, 8> &UnderlyingObjects,
12050 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12051 bool Changed = false;
12052 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12053 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12054 auto Pred = [&](Value &V) {
12055 Changed |= UnderlyingObjects.insert(&V);
12056 return true;
12057 };
12058 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12060 "The forall call should not return false at this position");
12061 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12062 return Changed;
12063 }
12064
12065 /// All the underlying objects collected so far via intra procedural scope.
12066 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12067 /// All the underlying objects collected so far via inter procedural scope.
12068 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12069};
12070
12071struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12072 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12073 : AAUnderlyingObjectsImpl(IRP, A) {}
12074};
12075
12076struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12077 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12078 : AAUnderlyingObjectsImpl(IRP, A) {}
12079};
12080
12081struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12082 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12083 : AAUnderlyingObjectsImpl(IRP, A) {}
12084};
12085
12086struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12087 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12088 : AAUnderlyingObjectsImpl(IRP, A) {}
12089};
12090
12091struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12092 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12093 : AAUnderlyingObjectsImpl(IRP, A) {}
12094};
12095
12096struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12097 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12098 : AAUnderlyingObjectsImpl(IRP, A) {}
12099};
12100
12101struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12102 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12103 : AAUnderlyingObjectsImpl(IRP, A) {}
12104};
12105} // namespace
12106
12107/// ------------------------ Global Value Info -------------------------------
12108namespace {
12109struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12110 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12111 : AAGlobalValueInfo(IRP, A) {}
12112
12113 /// See AbstractAttribute::initialize(...).
12114 void initialize(Attributor &A) override {}
12115
12116 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12117 SmallVectorImpl<const Value *> &Worklist) {
12118 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12119 if (!UInst) {
12120 Follow = true;
12121 return true;
12122 }
12123
12124 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12125 << *UInst << "\n");
12126
12127 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12128 int Idx = &Cmp->getOperandUse(0) == &U;
12129 if (isa<Constant>(Cmp->getOperand(Idx)))
12130 return true;
12131 return U == &getAnchorValue();
12132 }
12133
12134 // Explicitly catch return instructions.
12135 if (isa<ReturnInst>(UInst)) {
12136 auto CallSitePred = [&](AbstractCallSite ACS) {
12137 Worklist.push_back(ACS.getInstruction());
12138 return true;
12139 };
12140 bool UsedAssumedInformation = false;
12141 // TODO: We should traverse the uses or add a "non-call-site" CB.
12142 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12143 /*RequireAllCallSites=*/true, this,
12144 UsedAssumedInformation))
12145 return false;
12146 return true;
12147 }
12148
12149 // For now we only use special logic for call sites. However, the tracker
12150 // itself knows about a lot of other non-capturing cases already.
12151 auto *CB = dyn_cast<CallBase>(UInst);
12152 if (!CB)
12153 return false;
12154 // Direct calls are OK uses.
12155 if (CB->isCallee(&U))
12156 return true;
12157 // Non-argument uses are scary.
12158 if (!CB->isArgOperand(&U))
12159 return false;
12160 // TODO: Iterate callees.
12161 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12162 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12163 return false;
12164
12165 unsigned ArgNo = CB->getArgOperandNo(&U);
12166 Worklist.push_back(Fn->getArg(ArgNo));
12167 return true;
12168 }
12169
12170 ChangeStatus updateImpl(Attributor &A) override {
12171 unsigned NumUsesBefore = Uses.size();
12172
12173 SmallPtrSet<const Value *, 8> Visited;
12175 Worklist.push_back(&getAnchorValue());
12176
12177 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12178 Uses.insert(&U);
12179 // TODO(captures): Make this more precise.
12180 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12181 if (CI.isPassthrough()) {
12182 Follow = true;
12183 return true;
12184 }
12185 return checkUse(A, U, Follow, Worklist);
12186 };
12187 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12188 Uses.insert(&OldU);
12189 return true;
12190 };
12191
12192 while (!Worklist.empty()) {
12193 const Value *V = Worklist.pop_back_val();
12194 if (!Visited.insert(V).second)
12195 continue;
12196 if (!A.checkForAllUses(UsePred, *this, *V,
12197 /* CheckBBLivenessOnly */ true,
12198 DepClassTy::OPTIONAL,
12199 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12200 return indicatePessimisticFixpoint();
12201 }
12202 }
12203
12204 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12205 : ChangeStatus::CHANGED;
12206 }
12207
12208 bool isPotentialUse(const Use &U) const override {
12209 return !isValidState() || Uses.contains(&U);
12210 }
12211
12212 /// See AbstractAttribute::manifest(...).
12213 ChangeStatus manifest(Attributor &A) override {
12214 return ChangeStatus::UNCHANGED;
12215 }
12216
12217 /// See AbstractAttribute::getAsStr().
12218 const std::string getAsStr(Attributor *A) const override {
12219 return "[" + std::to_string(Uses.size()) + " uses]";
12220 }
12221
12222 void trackStatistics() const override {
12223 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12224 }
12225
12226private:
12227 /// Set of (transitive) uses of this GlobalValue.
12228 SmallPtrSet<const Use *, 8> Uses;
12229};
12230} // namespace
12231
12232/// ------------------------ Indirect Call Info -------------------------------
12233namespace {
12234struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12235 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12236 : AAIndirectCallInfo(IRP, A) {}
12237
12238 /// See AbstractAttribute::initialize(...).
12239 void initialize(Attributor &A) override {
12240 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12241 if (!MD && !A.isClosedWorldModule())
12242 return;
12243
12244 if (MD) {
12245 for (const auto &Op : MD->operands())
12246 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12247 PotentialCallees.insert(Callee);
12248 } else if (A.isClosedWorldModule()) {
12249 ArrayRef<Function *> IndirectlyCallableFunctions =
12250 A.getInfoCache().getIndirectlyCallableFunctions(A);
12251 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12252 }
12253
12254 if (PotentialCallees.empty())
12255 indicateOptimisticFixpoint();
12256 }
12257
12258 ChangeStatus updateImpl(Attributor &A) override {
12259 CallBase *CB = cast<CallBase>(getCtxI());
12260 const Use &CalleeUse = CB->getCalledOperandUse();
12261 Value *FP = CB->getCalledOperand();
12262
12263 SmallSetVector<Function *, 4> AssumedCalleesNow;
12264 bool AllCalleesKnownNow = AllCalleesKnown;
12265
12266 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12267 bool &UsedAssumedInformation) {
12268 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12269 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12270 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12271 return true;
12272 UsedAssumedInformation = !GIAA->isAtFixpoint();
12273 return false;
12274 };
12275
12276 auto AddPotentialCallees = [&]() {
12277 for (auto *PotentialCallee : PotentialCallees) {
12278 bool UsedAssumedInformation = false;
12279 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12280 AssumedCalleesNow.insert(PotentialCallee);
12281 }
12282 };
12283
12284 // Use simplification to find potential callees, if !callees was present,
12285 // fallback to that set if necessary.
12286 bool UsedAssumedInformation = false;
12288 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12289 AA::ValueScope::AnyScope,
12290 UsedAssumedInformation)) {
12291 if (PotentialCallees.empty())
12292 return indicatePessimisticFixpoint();
12293 AddPotentialCallees();
12294 }
12295
12296 // Try to find a reason for \p Fn not to be a potential callee. If none was
12297 // found, add it to the assumed callees set.
12298 auto CheckPotentialCallee = [&](Function &Fn) {
12299 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12300 return false;
12301
12302 auto &CachedResult = FilterResults[&Fn];
12303 if (CachedResult.has_value())
12304 return CachedResult.value();
12305
12306 bool UsedAssumedInformation = false;
12307 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12308 if (!UsedAssumedInformation)
12309 CachedResult = false;
12310 return false;
12311 }
12312
12313 int NumFnArgs = Fn.arg_size();
12314 int NumCBArgs = CB->arg_size();
12315
12316 // Check if any excess argument (which we fill up with poison) is known to
12317 // be UB on undef.
12318 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12319 bool IsKnown = false;
12321 A, this, IRPosition::argument(*Fn.getArg(I)),
12322 DepClassTy::OPTIONAL, IsKnown)) {
12323 if (IsKnown)
12324 CachedResult = false;
12325 return false;
12326 }
12327 }
12328
12329 CachedResult = true;
12330 return true;
12331 };
12332
12333 // Check simplification result, prune known UB callees, also restrict it to
12334 // the !callees set, if present.
12335 for (auto &VAC : Values) {
12336 if (isa<UndefValue>(VAC.getValue()))
12337 continue;
12338 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12339 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12340 continue;
12341 // TODO: Check for known UB, e.g., poison + noundef.
12342 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12343 if (CheckPotentialCallee(*VACFn))
12344 AssumedCalleesNow.insert(VACFn);
12345 continue;
12346 }
12347 if (!PotentialCallees.empty()) {
12348 AddPotentialCallees();
12349 break;
12350 }
12351 AllCalleesKnownNow = false;
12352 }
12353
12354 if (AssumedCalleesNow == AssumedCallees &&
12355 AllCalleesKnown == AllCalleesKnownNow)
12356 return ChangeStatus::UNCHANGED;
12357
12358 std::swap(AssumedCallees, AssumedCalleesNow);
12359 AllCalleesKnown = AllCalleesKnownNow;
12360 return ChangeStatus::CHANGED;
12361 }
12362
12363 /// See AbstractAttribute::manifest(...).
12364 ChangeStatus manifest(Attributor &A) override {
12365 // If we can't specialize at all, give up now.
12366 if (!AllCalleesKnown && AssumedCallees.empty())
12367 return ChangeStatus::UNCHANGED;
12368
12369 CallBase *CB = cast<CallBase>(getCtxI());
12370 bool UsedAssumedInformation = false;
12371 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12372 UsedAssumedInformation))
12373 return ChangeStatus::UNCHANGED;
12374
12375 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12376 Value *FP = CB->getCalledOperand();
12377 if (FP->getType()->getPointerAddressSpace())
12378 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12379 FP->getName() + ".as0", CB->getIterator());
12380
12381 bool CBIsVoid = CB->getType()->isVoidTy();
12383 FunctionType *CSFT = CB->getFunctionType();
12384 SmallVector<Value *> CSArgs(CB->args());
12385
12386 // If we know all callees and there are none, the call site is (effectively)
12387 // dead (or UB).
12388 if (AssumedCallees.empty()) {
12389 assert(AllCalleesKnown &&
12390 "Expected all callees to be known if there are none.");
12391 A.changeToUnreachableAfterManifest(CB);
12392 return ChangeStatus::CHANGED;
12393 }
12394
12395 // Special handling for the single callee case.
12396 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12397 auto *NewCallee = AssumedCallees.front();
12398 if (isLegalToPromote(*CB, NewCallee)) {
12399 promoteCall(*CB, NewCallee, nullptr);
12400 NumIndirectCallsPromoted++;
12401 return ChangeStatus::CHANGED;
12402 }
12403 Instruction *NewCall =
12404 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12405 CB->getName(), CB->getIterator());
12406 if (!CBIsVoid)
12407 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12408 A.deleteAfterManifest(*CB);
12409 return ChangeStatus::CHANGED;
12410 }
12411
12412 // For each potential value we create a conditional
12413 //
12414 // ```
12415 // if (ptr == value) value(args);
12416 // else ...
12417 // ```
12418 //
12419 bool SpecializedForAnyCallees = false;
12420 bool SpecializedForAllCallees = AllCalleesKnown;
12421 ICmpInst *LastCmp = nullptr;
12422 SmallVector<Function *, 8> SkippedAssumedCallees;
12424 for (Function *NewCallee : AssumedCallees) {
12425 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12426 AssumedCallees.size())) {
12427 SkippedAssumedCallees.push_back(NewCallee);
12428 SpecializedForAllCallees = false;
12429 continue;
12430 }
12431 SpecializedForAnyCallees = true;
12432
12433 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12434 Instruction *ThenTI =
12435 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12436 BasicBlock *CBBB = CB->getParent();
12437 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12438 A.registerManifestAddedBasicBlock(*IP->getParent());
12439 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12440 BasicBlock *ElseBB;
12441 if (&*IP == CB) {
12442 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12443 ThenTI->getFunction(), CBBB);
12444 A.registerManifestAddedBasicBlock(*ElseBB);
12445 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12446 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12447 } else {
12448 ElseBB = IP->getParent();
12449 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12450 }
12451 CastInst *RetBC = nullptr;
12452 CallInst *NewCall = nullptr;
12453 if (isLegalToPromote(*CB, NewCallee)) {
12454 auto *CBClone = cast<CallBase>(CB->clone());
12455 CBClone->insertBefore(ThenTI->getIterator());
12456 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12457 NumIndirectCallsPromoted++;
12458 } else {
12459 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12460 CB->getName(), ThenTI->getIterator());
12461 }
12462 NewCalls.push_back({NewCall, RetBC});
12463 }
12464
12465 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12466 if (!AllCalleesKnown)
12467 return ChangeStatus::UNCHANGED;
12468 MDBuilder MDB(IndirectCB.getContext());
12469 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12470 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12471 return ChangeStatus::CHANGED;
12472 };
12473
12474 if (!SpecializedForAnyCallees)
12475 return AttachCalleeMetadata(*CB);
12476
12477 // Check if we need the fallback indirect call still.
12478 if (SpecializedForAllCallees) {
12480 LastCmp->eraseFromParent();
12481 new UnreachableInst(IP->getContext(), IP);
12482 IP->eraseFromParent();
12483 } else {
12484 auto *CBClone = cast<CallInst>(CB->clone());
12485 CBClone->setName(CB->getName());
12486 CBClone->insertBefore(*IP->getParent(), IP);
12487 NewCalls.push_back({CBClone, nullptr});
12488 AttachCalleeMetadata(*CBClone);
12489 }
12490
12491 // Check if we need a PHI to merge the results.
12492 if (!CBIsVoid) {
12493 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12494 CB->getName() + ".phi",
12495 CB->getParent()->getFirstInsertionPt());
12496 for (auto &It : NewCalls) {
12497 CallBase *NewCall = It.first;
12498 Instruction *CallRet = It.second ? It.second : It.first;
12499 if (CallRet->getType() == CB->getType())
12500 PHI->addIncoming(CallRet, CallRet->getParent());
12501 else if (NewCall->getType()->isVoidTy())
12502 PHI->addIncoming(PoisonValue::get(CB->getType()),
12503 NewCall->getParent());
12504 else
12505 llvm_unreachable("Call return should match or be void!");
12506 }
12507 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12508 }
12509
12510 A.deleteAfterManifest(*CB);
12511 Changed = ChangeStatus::CHANGED;
12512
12513 return Changed;
12514 }
12515
12516 /// See AbstractAttribute::getAsStr().
12517 const std::string getAsStr(Attributor *A) const override {
12518 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12519 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12520 " functions";
12521 }
12522
12523 void trackStatistics() const override {
12524 if (AllCalleesKnown) {
12526 Eliminated, CallSites,
12527 "Number of indirect call sites eliminated via specialization")
12528 } else {
12529 STATS_DECLTRACK(Specialized, CallSites,
12530 "Number of indirect call sites specialized")
12531 }
12532 }
12533
12534 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12535 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12536 }
12537
12538private:
12539 /// Map to remember filter results.
12540 DenseMap<Function *, std::optional<bool>> FilterResults;
12541
12542 /// If the !callee metadata was present, this set will contain all potential
12543 /// callees (superset).
12544 SmallSetVector<Function *, 4> PotentialCallees;
12545
12546 /// This set contains all currently assumed calllees, which might grow over
12547 /// time.
12548 SmallSetVector<Function *, 4> AssumedCallees;
12549
12550 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12551 /// if there could be others.
12552 bool AllCalleesKnown = true;
12553};
12554} // namespace
12555
12556/// --------------------- Invariant Load Pointer -------------------------------
12557namespace {
12558
12559struct AAInvariantLoadPointerImpl
12560 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12561 AAInvariantLoadPointer> {
12562
12563 enum {
12564 // pointer does not alias within the bounds of the function
12565 IS_NOALIAS = 1 << 0,
12566 // pointer is not involved in any effectful instructions within the bounds
12567 // of the function
12568 IS_NOEFFECT = 1 << 1,
12569 // loads are invariant within the bounds of the function
12570 IS_LOCALLY_INVARIANT = 1 << 2,
12571 // memory lifetime is constrained within the bounds of the function
12572 IS_LOCALLY_CONSTRAINED = 1 << 3,
12573
12574 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12575 IS_LOCALLY_CONSTRAINED,
12576 };
12577 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12578
12579 using Base =
12580 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12581
12582 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12583 // pessimistic about IS_KNOWN_INVARIANT
12584 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12585 : Base(IRP) {}
12586
12587 bool isKnownInvariant() const final {
12588 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12589 }
12590
12591 bool isKnownLocallyInvariant() const final {
12592 if (isKnown(IS_LOCALLY_INVARIANT))
12593 return true;
12594 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12595 }
12596
12597 bool isAssumedInvariant() const final {
12598 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12599 }
12600
12601 bool isAssumedLocallyInvariant() const final {
12602 if (isAssumed(IS_LOCALLY_INVARIANT))
12603 return true;
12604 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12605 }
12606
12607 ChangeStatus updateImpl(Attributor &A) override {
12608 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12609
12610 Changed |= updateNoAlias(A);
12611 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12612 return indicatePessimisticFixpoint();
12613
12614 Changed |= updateNoEffect(A);
12615
12616 Changed |= updateLocalInvariance(A);
12617
12618 return Changed;
12619 }
12620
12621 ChangeStatus manifest(Attributor &A) override {
12622 if (!isKnownInvariant())
12623 return ChangeStatus::UNCHANGED;
12624
12625 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12626 const Value *Ptr = &getAssociatedValue();
12627 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12628 if (U.get() != Ptr)
12629 return true;
12630 auto *I = dyn_cast<Instruction>(U.getUser());
12631 if (!I)
12632 return true;
12633
12634 // Ensure that we are only changing uses from the corresponding callgraph
12635 // SSC in the case that the AA isn't run on the entire module
12636 if (!A.isRunOn(I->getFunction()))
12637 return true;
12638
12639 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12640 return true;
12641
12642 if (auto *LI = dyn_cast<LoadInst>(I)) {
12643 LI->setMetadata(LLVMContext::MD_invariant_load,
12644 MDNode::get(LI->getContext(), {}));
12645 Changed = ChangeStatus::CHANGED;
12646 }
12647 return true;
12648 };
12649
12650 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12651 return Changed;
12652 }
12653
12654 /// See AbstractAttribute::getAsStr().
12655 const std::string getAsStr(Attributor *) const override {
12656 if (isKnownInvariant())
12657 return "load-invariant pointer";
12658 return "non-invariant pointer";
12659 }
12660
12661 /// See AbstractAttribute::trackStatistics().
12662 void trackStatistics() const override {}
12663
12664private:
12665 /// Indicate that noalias is required for the pointer to be invariant.
12666 bool requiresNoAlias() const {
12667 switch (getPositionKind()) {
12668 default:
12669 // Conservatively default to require noalias.
12670 return true;
12671 case IRP_FLOAT:
12672 case IRP_RETURNED:
12673 case IRP_CALL_SITE:
12674 return false;
12675 case IRP_CALL_SITE_RETURNED: {
12676 const auto &CB = cast<CallBase>(getAnchorValue());
12678 &CB, /*MustPreserveNullness=*/false);
12679 }
12680 case IRP_ARGUMENT: {
12681 const Function *F = getAssociatedFunction();
12682 assert(F && "no associated function for argument");
12683 return !isCallableCC(F->getCallingConv());
12684 }
12685 }
12686 }
12687
12688 bool isExternal() const {
12689 const Function *F = getAssociatedFunction();
12690 if (!F)
12691 return true;
12692 return isCallableCC(F->getCallingConv()) &&
12693 getPositionKind() != IRP_CALL_SITE_RETURNED;
12694 }
12695
12696 ChangeStatus updateNoAlias(Attributor &A) {
12697 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12698 return ChangeStatus::UNCHANGED;
12699
12700 // Try to use AANoAlias.
12701 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12702 getIRPosition(), this, DepClassTy::REQUIRED)) {
12703 if (ANoAlias->isKnownNoAlias()) {
12704 addKnownBits(IS_NOALIAS);
12705 return ChangeStatus::CHANGED;
12706 }
12707
12708 if (!ANoAlias->isAssumedNoAlias()) {
12709 removeAssumedBits(IS_NOALIAS);
12710 return ChangeStatus::CHANGED;
12711 }
12712
12713 return ChangeStatus::UNCHANGED;
12714 }
12715
12716 // Try to infer noalias from argument attribute, since it is applicable for
12717 // the duration of the function.
12718 if (const Argument *Arg = getAssociatedArgument()) {
12719 if (Arg->hasNoAliasAttr()) {
12720 addKnownBits(IS_NOALIAS);
12721 return ChangeStatus::UNCHANGED;
12722 }
12723
12724 // Noalias information is not provided, and cannot be inferred,
12725 // so we conservatively assume the pointer aliases.
12726 removeAssumedBits(IS_NOALIAS);
12727 return ChangeStatus::CHANGED;
12728 }
12729
12730 return ChangeStatus::UNCHANGED;
12731 }
12732
12733 ChangeStatus updateNoEffect(Attributor &A) {
12734 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12735 return ChangeStatus::UNCHANGED;
12736
12737 if (!getAssociatedFunction())
12738 return indicatePessimisticFixpoint();
12739
12740 if (isa<AllocaInst>(&getAssociatedValue()))
12741 return indicatePessimisticFixpoint();
12742
12743 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12744 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12745 return !LI || !LI->mayHaveSideEffects();
12746 };
12747 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12748 return indicatePessimisticFixpoint();
12749
12750 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12751 getIRPosition(), this, DepClassTy::REQUIRED)) {
12752 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12753 // attribute
12754 if (!AMemoryBehavior->isAssumedReadOnly())
12755 return indicatePessimisticFixpoint();
12756
12757 if (AMemoryBehavior->isKnownReadOnly()) {
12758 addKnownBits(IS_NOEFFECT);
12759 return ChangeStatus::UNCHANGED;
12760 }
12761
12762 return ChangeStatus::UNCHANGED;
12763 }
12764
12765 if (const Argument *Arg = getAssociatedArgument()) {
12766 if (Arg->onlyReadsMemory()) {
12767 addKnownBits(IS_NOEFFECT);
12768 return ChangeStatus::UNCHANGED;
12769 }
12770
12771 // Readonly information is not provided, and cannot be inferred from
12772 // AAMemoryBehavior.
12773 return indicatePessimisticFixpoint();
12774 }
12775
12776 return ChangeStatus::UNCHANGED;
12777 }
12778
12779 ChangeStatus updateLocalInvariance(Attributor &A) {
12780 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12781 return ChangeStatus::UNCHANGED;
12782
12783 // try to infer invariance from underlying objects
12784 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12785 getIRPosition(), this, DepClassTy::REQUIRED);
12786 if (!AUO)
12787 return ChangeStatus::UNCHANGED;
12788
12789 bool UsedAssumedInformation = false;
12790 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12791 if (!V.getType()->isPointerTy())
12792 return true;
12793 const auto *IsInvariantLoadPointer =
12794 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12795 DepClassTy::REQUIRED);
12796 // Conservatively fail if invariance cannot be inferred.
12797 if (!IsInvariantLoadPointer)
12798 return false;
12799
12800 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12801 return true;
12802 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12803 return false;
12804
12805 UsedAssumedInformation = true;
12806 return true;
12807 };
12808 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12809 return indicatePessimisticFixpoint();
12810
12811 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12813 CB, /*MustPreserveNullness=*/false)) {
12814 for (const Value *Arg : CB->args()) {
12815 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12816 return indicatePessimisticFixpoint();
12817 }
12818 }
12819 }
12820
12821 if (!UsedAssumedInformation) {
12822 // Pointer is known and not just assumed to be locally invariant.
12823 addKnownBits(IS_LOCALLY_INVARIANT);
12824 return ChangeStatus::CHANGED;
12825 }
12826
12827 return ChangeStatus::UNCHANGED;
12828 }
12829};
12830
12831struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12832 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12833 : AAInvariantLoadPointerImpl(IRP, A) {}
12834};
12835
12836struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12837 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12838 : AAInvariantLoadPointerImpl(IRP, A) {}
12839
12840 void initialize(Attributor &) override {
12841 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12842 }
12843};
12844
12845struct AAInvariantLoadPointerCallSiteReturned final
12846 : AAInvariantLoadPointerImpl {
12847 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12848 : AAInvariantLoadPointerImpl(IRP, A) {}
12849
12850 void initialize(Attributor &A) override {
12851 const Function *F = getAssociatedFunction();
12852 assert(F && "no associated function for return from call");
12853
12854 if (!F->isDeclaration() && !F->isIntrinsic())
12855 return AAInvariantLoadPointerImpl::initialize(A);
12856
12857 const auto &CB = cast<CallBase>(getAnchorValue());
12859 &CB, /*MustPreserveNullness=*/false))
12860 return AAInvariantLoadPointerImpl::initialize(A);
12861
12862 if (F->onlyReadsMemory() && F->hasNoSync())
12863 return AAInvariantLoadPointerImpl::initialize(A);
12864
12865 // At this point, the function is opaque, so we conservatively assume
12866 // non-invariance.
12867 indicatePessimisticFixpoint();
12868 }
12869};
12870
12871struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12872 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12873 : AAInvariantLoadPointerImpl(IRP, A) {}
12874
12875 void initialize(Attributor &) override {
12876 const Function *F = getAssociatedFunction();
12877 assert(F && "no associated function for argument");
12878
12879 if (!isCallableCC(F->getCallingConv())) {
12880 addKnownBits(IS_LOCALLY_CONSTRAINED);
12881 return;
12882 }
12883
12884 if (!F->hasLocalLinkage())
12885 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12886 }
12887};
12888
12889struct AAInvariantLoadPointerCallSiteArgument final
12890 : AAInvariantLoadPointerImpl {
12891 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12892 : AAInvariantLoadPointerImpl(IRP, A) {}
12893};
12894} // namespace
12895
12896/// ------------------------ Address Space ------------------------------------
12897namespace {
12898
12899template <typename InstType>
12900static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12901 Value *OriginalValue, PointerType *NewPtrTy,
12902 bool UseOriginalValue) {
12903 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12904 return false;
12905
12906 if (MemInst->isVolatile()) {
12907 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12908 *MemInst->getFunction());
12909 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12910 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12911 return false;
12912 }
12913
12914 if (UseOriginalValue) {
12915 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
12916 return true;
12917 }
12918
12919 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12920 CastInst->insertBefore(MemInst->getIterator());
12921 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
12922 return true;
12923}
12924
12925struct AAAddressSpaceImpl : public AAAddressSpace {
12926 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12927 : AAAddressSpace(IRP, A) {}
12928
12929 uint32_t getAddressSpace() const override {
12930 assert(isValidState() && "the AA is invalid");
12931 return AssumedAddressSpace;
12932 }
12933
12934 /// See AbstractAttribute::initialize(...).
12935 void initialize(Attributor &A) override {
12936 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12937 "Associated value is not a pointer");
12938
12939 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
12940 indicatePessimisticFixpoint();
12941 return;
12942 }
12943
12944 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12945 unsigned AS = getAssociatedType()->getPointerAddressSpace();
12946 if (AS != FlatAS) {
12947 [[maybe_unused]] bool R = takeAddressSpace(AS);
12948 assert(R && "The take should happen");
12949 indicateOptimisticFixpoint();
12950 }
12951 }
12952
12953 ChangeStatus updateImpl(Attributor &A) override {
12954 uint32_t OldAddressSpace = AssumedAddressSpace;
12955 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12956
12957 auto CheckAddressSpace = [&](Value &Obj) {
12958 // Ignore undef.
12959 if (isa<UndefValue>(&Obj))
12960 return true;
12961
12962 // If the object already has a non-flat address space, we simply take it.
12963 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
12964 if (ObjAS != FlatAS)
12965 return takeAddressSpace(ObjAS);
12966
12967 // At this point, we know Obj is in the flat address space. For a final
12968 // attempt, we want to use getAssumedAddrSpace, but first we must get the
12969 // associated function, if possible.
12970 Function *F = nullptr;
12971 if (auto *Arg = dyn_cast<Argument>(&Obj))
12972 F = Arg->getParent();
12973 else if (auto *I = dyn_cast<Instruction>(&Obj))
12974 F = I->getFunction();
12975
12976 // Use getAssumedAddrSpace if the associated function exists.
12977 if (F) {
12978 auto *TTI =
12979 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
12980 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
12981 if (AssumedAS != ~0U)
12982 return takeAddressSpace(AssumedAS);
12983 }
12984
12985 // Now we can't do anything else but to take the flat AS.
12986 return takeAddressSpace(FlatAS);
12987 };
12988
12989 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12990 DepClassTy::REQUIRED);
12991 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
12992 return indicatePessimisticFixpoint();
12993
12994 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
12995 : ChangeStatus::CHANGED;
12996 }
12997
12998 /// See AbstractAttribute::manifest(...).
12999 ChangeStatus manifest(Attributor &A) override {
13000 unsigned NewAS = getAddressSpace();
13001
13002 if (NewAS == InvalidAddressSpace ||
13003 NewAS == getAssociatedType()->getPointerAddressSpace())
13004 return ChangeStatus::UNCHANGED;
13005
13006 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13007
13008 Value *AssociatedValue = &getAssociatedValue();
13009 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13010
13011 PointerType *NewPtrTy =
13012 PointerType::get(getAssociatedType()->getContext(), NewAS);
13013 bool UseOriginalValue =
13014 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13015
13016 bool Changed = false;
13017
13018 auto Pred = [&](const Use &U, bool &) {
13019 if (U.get() != AssociatedValue)
13020 return true;
13021 auto *Inst = dyn_cast<Instruction>(U.getUser());
13022 if (!Inst)
13023 return true;
13024 // This is a WA to make sure we only change uses from the corresponding
13025 // CGSCC if the AA is run on CGSCC instead of the entire module.
13026 if (!A.isRunOn(Inst->getFunction()))
13027 return true;
13028 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13029 Changed |=
13030 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13031 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13032 Changed |=
13033 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13034 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13035 Changed |=
13036 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13037 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13038 Changed |=
13039 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13040 }
13041 return true;
13042 };
13043
13044 // It doesn't matter if we can't check all uses as we can simply
13045 // conservatively ignore those that can not be visited.
13046 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13047 /* CheckBBLivenessOnly */ true);
13048
13049 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13050 }
13051
13052 /// See AbstractAttribute::getAsStr().
13053 const std::string getAsStr(Attributor *A) const override {
13054 if (!isValidState())
13055 return "addrspace(<invalid>)";
13056 return "addrspace(" +
13057 (AssumedAddressSpace == InvalidAddressSpace
13058 ? "none"
13059 : std::to_string(AssumedAddressSpace)) +
13060 ")";
13061 }
13062
13063private:
13064 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13065
13066 bool takeAddressSpace(uint32_t AS) {
13067 if (AssumedAddressSpace == InvalidAddressSpace) {
13068 AssumedAddressSpace = AS;
13069 return true;
13070 }
13071 return AssumedAddressSpace == AS;
13072 }
13073
13074 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13075 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13076 assert(I->getSrcAddressSpace() != FlatAS &&
13077 "there should not be flat AS -> non-flat AS");
13078 return I->getPointerOperand();
13079 }
13080 if (auto *C = dyn_cast<ConstantExpr>(V))
13081 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13082 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13083 FlatAS &&
13084 "there should not be flat AS -> non-flat AS X");
13085 return C->getOperand(0);
13086 }
13087 return V;
13088 }
13089};
13090
13091struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13092 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13093 : AAAddressSpaceImpl(IRP, A) {}
13094
13095 void trackStatistics() const override {
13097 }
13098};
13099
13100struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13101 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13102 : AAAddressSpaceImpl(IRP, A) {}
13103
13104 /// See AbstractAttribute::initialize(...).
13105 void initialize(Attributor &A) override {
13106 // TODO: we don't rewrite function argument for now because it will need to
13107 // rewrite the function signature and all call sites.
13108 (void)indicatePessimisticFixpoint();
13109 }
13110
13111 void trackStatistics() const override {
13112 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13113 }
13114};
13115
13116struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13117 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13118 : AAAddressSpaceImpl(IRP, A) {}
13119
13120 void trackStatistics() const override {
13121 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13122 }
13123};
13124
13125struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13126 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13127 : AAAddressSpaceImpl(IRP, A) {}
13128
13129 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13130};
13131
13132struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13133 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13134 : AAAddressSpaceImpl(IRP, A) {}
13135
13136 /// See AbstractAttribute::initialize(...).
13137 void initialize(Attributor &A) override {
13138 // TODO: we don't rewrite call site argument for now because it will need to
13139 // rewrite the function signature of the callee.
13140 (void)indicatePessimisticFixpoint();
13141 }
13142
13143 void trackStatistics() const override {
13144 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13145 }
13146};
13147} // namespace
13148
13149/// ------------------------ No Alias Address Space ---------------------------
13150// This attribute assumes flat address space can alias all other address space
13151
13152// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13153// But merging it created failing cased on gateway test that cannot be
13154// reproduced locally. So should open a seperated PR to hande the merge of
13155// AANoAliasAddrSpace and AAAddressSpace attribute
13156
13157namespace {
13158struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13159 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13160 : AANoAliasAddrSpace(IRP, A) {}
13161
13162 void initialize(Attributor &A) override {
13163 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13164 "Associated value is not a pointer");
13165
13166 resetASRanges(A);
13167
13168 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13169 if (!FlatAS.has_value()) {
13170 indicatePessimisticFixpoint();
13171 return;
13172 }
13173
13174 removeAS(*FlatAS);
13175
13176 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13177 if (AS != *FlatAS) {
13178 removeAS(AS);
13179 indicateOptimisticFixpoint();
13180 }
13181 }
13182
13183 ChangeStatus updateImpl(Attributor &A) override {
13184 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13185 uint32_t OldAssumed = getAssumed();
13186
13187 auto CheckAddressSpace = [&](Value &Obj) {
13188 if (isa<PoisonValue>(&Obj))
13189 return true;
13190
13191 unsigned AS = Obj.getType()->getPointerAddressSpace();
13192 if (AS == FlatAS)
13193 return false;
13194
13195 removeAS(Obj.getType()->getPointerAddressSpace());
13196 return true;
13197 };
13198
13199 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13200 getIRPosition(), this, DepClassTy::REQUIRED);
13201 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13202 return indicatePessimisticFixpoint();
13203
13204 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13205 : ChangeStatus::CHANGED;
13206 }
13207
13208 /// See AbstractAttribute::manifest(...).
13209 ChangeStatus manifest(Attributor &A) override {
13210 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13211
13212 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13213 if (AS != FlatAS || Map.empty())
13214 return ChangeStatus::UNCHANGED;
13215
13216 LLVMContext &Ctx = getAssociatedValue().getContext();
13217 MDNode *NoAliasASNode = nullptr;
13218 MDBuilder MDB(Ctx);
13219 // Has to use iterator to get the range info.
13220 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13221 if (!I.value())
13222 continue;
13223 unsigned Upper = I.stop();
13224 unsigned Lower = I.start();
13225 if (!NoAliasASNode) {
13226 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13227 continue;
13228 }
13229 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13230 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13231 }
13232
13233 Value *AssociatedValue = &getAssociatedValue();
13234 bool Changed = false;
13235
13236 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13237 if (U.get() != AssociatedValue)
13238 return true;
13239 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13240 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13241 return true;
13242 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13244 return true;
13245 if (!A.isRunOn(Inst->getFunction()))
13246 return true;
13247 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13248 Changed = true;
13249 return true;
13250 };
13251 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13252 /*CheckBBLivenessOnly=*/true);
13253 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13254 }
13255
13256 /// See AbstractAttribute::getAsStr().
13257 const std::string getAsStr(Attributor *A) const override {
13258 if (!isValidState())
13259 return "<invalid>";
13260 std::string Str;
13261 raw_string_ostream OS(Str);
13262 OS << "CanNotBeAddrSpace(";
13263 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13264 unsigned Upper = I.stop();
13265 unsigned Lower = I.start();
13266 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13267 }
13268 OS << " )";
13269 return OS.str();
13270 }
13271
13272private:
13273 void removeAS(unsigned AS) {
13274 RangeMap::iterator I = Map.find(AS);
13275
13276 if (I != Map.end()) {
13277 unsigned Upper = I.stop();
13278 unsigned Lower = I.start();
13279 I.erase();
13280 if (Upper == Lower)
13281 return;
13282 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13283 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13284 if (AS != 0 && Lower <= AS - 1)
13285 Map.insert(Lower, AS - 1, true);
13286 }
13287 }
13288
13289 void resetASRanges(Attributor &A) {
13290 Map.clear();
13291 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13292 }
13293};
13294
13295struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13296 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13297 : AANoAliasAddrSpaceImpl(IRP, A) {}
13298
13299 void trackStatistics() const override {
13300 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13301 }
13302};
13303
13304struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13305 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13306 : AANoAliasAddrSpaceImpl(IRP, A) {}
13307
13308 void trackStatistics() const override {
13309 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13310 }
13311};
13312
13313struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13314 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13315 : AANoAliasAddrSpaceImpl(IRP, A) {}
13316
13317 void trackStatistics() const override {
13318 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13319 }
13320};
13321
13322struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13323 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13324 : AANoAliasAddrSpaceImpl(IRP, A) {}
13325
13326 void trackStatistics() const override {
13327 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13328 }
13329};
13330
13331struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13332 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13333 : AANoAliasAddrSpaceImpl(IRP, A) {}
13334
13335 void trackStatistics() const override {
13336 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13337 }
13338};
13339} // namespace
13340/// ----------- Allocation Info ----------
13341namespace {
13342struct AAAllocationInfoImpl : public AAAllocationInfo {
13343 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13344 : AAAllocationInfo(IRP, A) {}
13345
13346 std::optional<TypeSize> getAllocatedSize() const override {
13347 assert(isValidState() && "the AA is invalid");
13348 return AssumedAllocatedSize;
13349 }
13350
13351 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13352 const DataLayout &DL) {
13353
13354 // TODO: implement case for malloc like instructions
13355 switch (I->getOpcode()) {
13356 case Instruction::Alloca: {
13357 AllocaInst *AI = cast<AllocaInst>(I);
13358 return AI->getAllocationSize(DL);
13359 }
13360 default:
13361 return std::nullopt;
13362 }
13363 }
13364
13365 ChangeStatus updateImpl(Attributor &A) override {
13366
13367 const IRPosition &IRP = getIRPosition();
13368 Instruction *I = IRP.getCtxI();
13369
13370 // TODO: update check for malloc like calls
13371 if (!isa<AllocaInst>(I))
13372 return indicatePessimisticFixpoint();
13373
13374 bool IsKnownNoCapture;
13376 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13377 return indicatePessimisticFixpoint();
13378
13379 const AAPointerInfo *PI =
13380 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13381
13382 if (!PI)
13383 return indicatePessimisticFixpoint();
13384
13385 if (!PI->getState().isValidState() || PI->reachesReturn())
13386 return indicatePessimisticFixpoint();
13387
13388 const DataLayout &DL = A.getDataLayout();
13389 const auto AllocationSize = findInitialAllocationSize(I, DL);
13390
13391 // If allocation size is nullopt, we give up.
13392 if (!AllocationSize)
13393 return indicatePessimisticFixpoint();
13394
13395 // For zero sized allocations, we give up.
13396 // Since we can't reduce further
13397 if (*AllocationSize == 0)
13398 return indicatePessimisticFixpoint();
13399
13400 int64_t BinSize = PI->numOffsetBins();
13401
13402 // TODO: implement for multiple bins
13403 if (BinSize > 1)
13404 return indicatePessimisticFixpoint();
13405
13406 if (BinSize == 0) {
13407 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13408 if (!changeAllocationSize(NewAllocationSize))
13409 return ChangeStatus::UNCHANGED;
13410 return ChangeStatus::CHANGED;
13411 }
13412
13413 // TODO: refactor this to be part of multiple bin case
13414 const auto &It = PI->begin();
13415
13416 // TODO: handle if Offset is not zero
13417 if (It->first.Offset != 0)
13418 return indicatePessimisticFixpoint();
13419
13420 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13421
13422 if (SizeOfBin >= *AllocationSize)
13423 return indicatePessimisticFixpoint();
13424
13425 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13426
13427 if (!changeAllocationSize(NewAllocationSize))
13428 return ChangeStatus::UNCHANGED;
13429
13430 return ChangeStatus::CHANGED;
13431 }
13432
13433 /// See AbstractAttribute::manifest(...).
13434 ChangeStatus manifest(Attributor &A) override {
13435
13436 assert(isValidState() &&
13437 "Manifest should only be called if the state is valid.");
13438
13439 Instruction *I = getIRPosition().getCtxI();
13440
13441 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13442
13443 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13444
13445 switch (I->getOpcode()) {
13446 // TODO: add case for malloc like calls
13447 case Instruction::Alloca: {
13448
13449 AllocaInst *AI = cast<AllocaInst>(I);
13450
13451 Type *CharType = Type::getInt8Ty(I->getContext());
13452
13453 auto *NumBytesToValue =
13454 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13455
13456 BasicBlock::iterator insertPt = AI->getIterator();
13457 insertPt = std::next(insertPt);
13458 AllocaInst *NewAllocaInst =
13459 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13460 AI->getAlign(), AI->getName(), insertPt);
13461
13462 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13463 return ChangeStatus::CHANGED;
13464
13465 break;
13466 }
13467 default:
13468 break;
13469 }
13470
13471 return ChangeStatus::UNCHANGED;
13472 }
13473
13474 /// See AbstractAttribute::getAsStr().
13475 const std::string getAsStr(Attributor *A) const override {
13476 if (!isValidState())
13477 return "allocationinfo(<invalid>)";
13478 return "allocationinfo(" +
13479 (AssumedAllocatedSize == HasNoAllocationSize
13480 ? "none"
13481 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13482 ")";
13483 }
13484
13485private:
13486 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13487
13488 // Maintain the computed allocation size of the object.
13489 // Returns (bool) weather the size of the allocation was modified or not.
13490 bool changeAllocationSize(std::optional<TypeSize> Size) {
13491 if (AssumedAllocatedSize == HasNoAllocationSize ||
13492 AssumedAllocatedSize != Size) {
13493 AssumedAllocatedSize = Size;
13494 return true;
13495 }
13496 return false;
13497 }
13498};
13499
13500struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13501 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13502 : AAAllocationInfoImpl(IRP, A) {}
13503
13504 void trackStatistics() const override {
13505 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13506 }
13507};
13508
13509struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13510 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13511 : AAAllocationInfoImpl(IRP, A) {}
13512
13513 /// See AbstractAttribute::initialize(...).
13514 void initialize(Attributor &A) override {
13515 // TODO: we don't rewrite function argument for now because it will need to
13516 // rewrite the function signature and all call sites
13517 (void)indicatePessimisticFixpoint();
13518 }
13519
13520 void trackStatistics() const override {
13521 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13522 }
13523};
13524
13525struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13526 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13527 : AAAllocationInfoImpl(IRP, A) {}
13528
13529 void trackStatistics() const override {
13530 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13531 }
13532};
13533
13534struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13535 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13536 : AAAllocationInfoImpl(IRP, A) {}
13537
13538 void trackStatistics() const override {
13539 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13540 }
13541};
13542
13543struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13544 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13545 : AAAllocationInfoImpl(IRP, A) {}
13546
13547 /// See AbstractAttribute::initialize(...).
13548 void initialize(Attributor &A) override {
13549
13550 (void)indicatePessimisticFixpoint();
13551 }
13552
13553 void trackStatistics() const override {
13554 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13555 }
13556};
13557} // namespace
13558
13559const char AANoUnwind::ID = 0;
13560const char AANoSync::ID = 0;
13561const char AANoFree::ID = 0;
13562const char AANonNull::ID = 0;
13563const char AAMustProgress::ID = 0;
13564const char AANoRecurse::ID = 0;
13565const char AANonConvergent::ID = 0;
13566const char AAWillReturn::ID = 0;
13567const char AAUndefinedBehavior::ID = 0;
13568const char AANoAlias::ID = 0;
13569const char AAIntraFnReachability::ID = 0;
13570const char AANoReturn::ID = 0;
13571const char AAIsDead::ID = 0;
13572const char AADereferenceable::ID = 0;
13573const char AAAlign::ID = 0;
13574const char AAInstanceInfo::ID = 0;
13575const char AANoCapture::ID = 0;
13576const char AAValueSimplify::ID = 0;
13577const char AAHeapToStack::ID = 0;
13578const char AAPrivatizablePtr::ID = 0;
13579const char AAMemoryBehavior::ID = 0;
13580const char AAMemoryLocation::ID = 0;
13581const char AAValueConstantRange::ID = 0;
13582const char AAPotentialConstantValues::ID = 0;
13583const char AAPotentialValues::ID = 0;
13584const char AANoUndef::ID = 0;
13585const char AANoFPClass::ID = 0;
13586const char AACallEdges::ID = 0;
13587const char AAInterFnReachability::ID = 0;
13588const char AAPointerInfo::ID = 0;
13589const char AAAssumptionInfo::ID = 0;
13590const char AAUnderlyingObjects::ID = 0;
13591const char AAInvariantLoadPointer::ID = 0;
13592const char AAAddressSpace::ID = 0;
13593const char AANoAliasAddrSpace::ID = 0;
13594const char AAAllocationInfo::ID = 0;
13595const char AAIndirectCallInfo::ID = 0;
13596const char AAGlobalValueInfo::ID = 0;
13597const char AADenormalFPMath::ID = 0;
13598
13599// Macro magic to create the static generator function for attributes that
13600// follow the naming scheme.
13601
13602#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13603 case IRPosition::PK: \
13604 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13605
13606#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13607 case IRPosition::PK: \
13608 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13609 ++NumAAs; \
13610 break;
13611
13612#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13613 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13614 CLASS *AA = nullptr; \
13615 switch (IRP.getPositionKind()) { \
13616 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13617 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13618 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13619 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13620 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13621 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13622 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13623 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13624 } \
13625 return *AA; \
13626 }
13627
13628#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13629 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13630 CLASS *AA = nullptr; \
13631 switch (IRP.getPositionKind()) { \
13632 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13633 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13634 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13635 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13636 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13637 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13638 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13639 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13640 } \
13641 return *AA; \
13642 }
13643
13644#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13645 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13646 CLASS *AA = nullptr; \
13647 switch (IRP.getPositionKind()) { \
13648 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13649 default: \
13650 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13651 " position!"); \
13652 } \
13653 return *AA; \
13654 }
13655
13656#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13657 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13658 CLASS *AA = nullptr; \
13659 switch (IRP.getPositionKind()) { \
13660 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13661 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13662 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13663 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13664 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13665 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13666 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13667 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13668 } \
13669 return *AA; \
13670 }
13671
13672#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13673 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13674 CLASS *AA = nullptr; \
13675 switch (IRP.getPositionKind()) { \
13676 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13677 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13678 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13679 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13680 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13681 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13682 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13683 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13684 } \
13685 return *AA; \
13686 }
13687
13688#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13689 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13690 CLASS *AA = nullptr; \
13691 switch (IRP.getPositionKind()) { \
13692 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13693 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13694 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13695 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13696 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13697 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13698 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13699 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13700 } \
13701 return *AA; \
13702 }
13703
13713
13731
13736
13741
13748
13750
13751#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13752#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13753#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13754#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13755#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13756#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13757#undef SWITCH_PK_CREATE
13758#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...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition CFG.cpp:135
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
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
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
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, ArrayRef< StringLiteral > StandardNames)
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:1562
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:273
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:309
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:172
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:297
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:69
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:88
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:101
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:482
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:367
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:612
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:619
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:917
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:950
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:678
@ ICMP_NE
not equal
Definition InstrTypes.h:700
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:944
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:767
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:535
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:63
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:165
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:229
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:161
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:156
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:214
Analysis pass which computes a DominatorTree.
Definition Dominators.h:284
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
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:807
Argument * arg_iterator
Definition Function.h:72
iterator_range< arg_iterator > args()
Definition Function.h:890
const Function & getFunction() const
Definition Function.h:164
size_t arg_size() const
Definition Function.h:899
Argument * getArg(unsigned i) const
Definition Function.h:884
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
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:328
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:2036
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:527
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2780
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:1565
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:75
static MemoryEffectsBase readOnly()
Definition ModRef.h:125
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:215
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:135
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:141
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:234
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:188
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:224
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:218
static MemoryEffectsBase writeOnly()
Definition ModRef.h:130
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:158
static MemoryEffectsBase none()
Definition ModRef.h:120
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:245
static MemoryEffectsBase unknown()
Definition ModRef.h:115
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:59
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:104
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:168
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:181
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:621
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:652
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:657
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, const ArrayRef< Type * > &Types) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:267
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:270
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:139
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:21
const Use & getOperandUse(unsigned i) const
Definition User.h:245
Value * getOperand(unsigned i) const
Definition User.h:232
unsigned getNumOperands() const
Definition User.h:254
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:115
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:169
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
static constexpr uint64_t MaximumAlignment
Definition Value.h:830
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:546
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
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1101
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:322
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:194
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:169
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:134
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:359
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:323
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:182
@ Intraprocedural
Definition Attributor.h:183
@ Interprocedural
Definition Attributor.h:184
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
@ Undef
Value of the register doesn't matter.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
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:60
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:707
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:666
constexpr double e
Definition MathExtras.h:47
@ 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:477
@ Length
Definition DWP.cpp:477
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:362
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:1714
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:1666
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:294
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:296
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1563
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:738
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:296
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:682
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)
Definition STLExtras.h:359
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:759
CycleInfo::CycleT Cycle
Definition CycleInfo.h:24
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1721
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:342
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:288
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1633
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:288
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:421
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
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:548
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:565
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:363
ChangeStatus
{
Definition Attributor.h:496
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:111
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:508
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:509
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:507
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:299
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:315
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
GenericCycleInfo< SSAContext > CycleInfo
Definition CycleInfo.h:23
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
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-fp-math" and "denormal-fp-ma...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:241
static constexpr int64_t Unknown
Definition Attributor.h:320
static RangeTy getUnknown()
Definition Attributor.h:247
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)
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:85
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 DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
static constexpr DenormalMode getInvalid()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:593
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:724
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:661
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:643
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:617
CallBase CallBaseContext
Definition Attributor.h:596
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:811
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:629
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:666
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:607
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:603
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:606
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:604
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:605
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:608
@ IRP_INVALID
An invalid position.
Definition Attributor.h:600
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:777
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:650
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:800
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:636
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:939
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:791
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:710
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:820
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:689
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:889
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:921
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:656
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:765
Data structure to hold cached (LLVM-IR) information.
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.