LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static inline Access getEmptyKey();
749 static inline Access getTombstoneKey();
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
756 static inline AA::RangeTy getEmptyKey() {
757 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
758 return AA::RangeTy{EmptyKey, EmptyKey};
759 }
760
761 static inline AA::RangeTy getTombstoneKey() {
762 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
763 return AA::RangeTy{TombstoneKey, TombstoneKey};
764 }
765
771
772 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
773 return A == B;
774 }
775};
776
777/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
778/// but the instruction
779struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
782 static inline Access getEmptyKey();
783 static inline Access getTombstoneKey();
784 static unsigned getHashValue(const Access &A);
785 static bool isEqual(const Access &LHS, const Access &RHS);
786};
787
788} // namespace llvm
789
790/// A type to track pointer/struct usage and accesses for AAPointerInfo.
792 /// Return the best possible representable state.
793 static State getBestState(const State &SIS) { return State(); }
794
795 /// Return the worst possible representable state.
796 static State getWorstState(const State &SIS) {
797 State R;
798 R.indicatePessimisticFixpoint();
799 return R;
800 }
801
802 State() = default;
803 State(State &&SIS) = default;
804
805 const State &getAssumed() const { return *this; }
806
807 /// See AbstractState::isValidState().
808 bool isValidState() const override { return BS.isValidState(); }
809
810 /// See AbstractState::isAtFixpoint().
811 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
812
813 /// See AbstractState::indicateOptimisticFixpoint().
815 BS.indicateOptimisticFixpoint();
817 }
818
819 /// See AbstractState::indicatePessimisticFixpoint().
821 BS.indicatePessimisticFixpoint();
823 }
824
825 State &operator=(const State &R) {
826 if (this == &R)
827 return *this;
828 BS = R.BS;
829 AccessList = R.AccessList;
830 OffsetBins = R.OffsetBins;
831 RemoteIMap = R.RemoteIMap;
832 ReturnedOffsets = R.ReturnedOffsets;
833 return *this;
834 }
835
837 if (this == &R)
838 return *this;
839 std::swap(BS, R.BS);
840 std::swap(AccessList, R.AccessList);
841 std::swap(OffsetBins, R.OffsetBins);
842 std::swap(RemoteIMap, R.RemoteIMap);
843 std::swap(ReturnedOffsets, R.ReturnedOffsets);
844 return *this;
845 }
846
847 /// Add a new Access to the state at offset \p Offset and with size \p Size.
848 /// The access is associated with \p I, writes \p Content (if anything), and
849 /// is of kind \p Kind. If an Access already exists for the same \p I and same
850 /// \p RemoteI, the two are combined, potentially losing information about
851 /// offset and size. The resulting access must now be moved from its original
852 /// OffsetBin to the bin for its new offset.
853 ///
854 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
856 Instruction &I, std::optional<Value *> Content,
858 Instruction *RemoteI = nullptr);
859
862 int64_t numOffsetBins() const { return OffsetBins.size(); }
863
864 const AAPointerInfo::Access &getAccess(unsigned Index) const {
865 return AccessList[Index];
866 }
867
868protected:
869 // Every memory instruction results in an Access object. We maintain a list of
870 // all Access objects that we own, along with the following maps:
871 //
872 // - OffsetBins: RangeTy -> { Access }
873 // - RemoteIMap: RemoteI x LocalI -> Access
874 //
875 // A RemoteI is any instruction that accesses memory. RemoteI is different
876 // from LocalI if and only if LocalI is a call; then RemoteI is some
877 // instruction in the callgraph starting from LocalI. Multiple paths in the
878 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
879 // are all combined into a single Access object. This may result in loss of
880 // information in RangeTy in the Access object.
884
885 /// Flag to determine if the underlying pointer is reaching a return statement
886 /// in the associated function or not. Returns in other functions cause
887 /// invalidation.
889
890 /// See AAPointerInfo::forallInterferingAccesses.
891 template <typename F>
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 for (const auto &It : OffsetBins) {
897 AA::RangeTy ItRange = It.getFirst();
898 if (!Range.mayOverlap(ItRange))
899 continue;
900 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
901 for (auto Index : It.getSecond()) {
902 auto &Access = AccessList[Index];
903 if (!CB(Access, IsExact))
904 return false;
905 }
906 }
907 return true;
908 }
909
910 /// See AAPointerInfo::forallInterferingAccesses.
911 template <typename F>
913 AA::RangeTy &Range) const {
914 if (!isValidState() || !ReturnedOffsets.isUnassigned())
915 return false;
916
917 auto LocalList = RemoteIMap.find(&I);
918 if (LocalList == RemoteIMap.end()) {
919 return true;
920 }
921
922 for (unsigned Index : LocalList->getSecond()) {
923 for (auto &R : AccessList[Index]) {
924 Range &= R;
925 if (Range.offsetAndSizeAreUnknown())
926 break;
927 }
928 }
930 }
931
932private:
933 /// State to track fixpoint and validity.
934 BooleanState BS;
935};
936
939 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
940 Instruction *RemoteI) {
941 RemoteI = RemoteI ? RemoteI : &I;
942
943 // Check if we have an access for this instruction, if not, simply add it.
944 auto &LocalList = RemoteIMap[RemoteI];
945 bool AccExists = false;
946 unsigned AccIndex = AccessList.size();
947 for (auto Index : LocalList) {
948 auto &A = AccessList[Index];
949 if (A.getLocalInst() == &I) {
950 AccExists = true;
951 AccIndex = Index;
952 break;
953 }
954 }
955
956 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
957 LLVM_DEBUG(if (ToAdd.size()) dbgs()
958 << "[AAPointerInfo] Inserting access in new offset bins\n";);
959
960 for (auto Key : ToAdd) {
961 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
962 OffsetBins[Key].insert(AccIndex);
963 }
964 };
965
966 if (!AccExists) {
967 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
968 assert((AccessList.size() == AccIndex + 1) &&
969 "New Access should have been at AccIndex");
970 LocalList.push_back(AccIndex);
971 AddToBins(AccessList[AccIndex].getRanges());
973 }
974
975 // Combine the new Access with the existing Access, and then update the
976 // mapping in the offset bins.
977 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
978 auto &Current = AccessList[AccIndex];
979 auto Before = Current;
980 Current &= Acc;
981 if (Current == Before)
983
984 auto &ExistingRanges = Before.getRanges();
985 auto &NewRanges = Current.getRanges();
986
987 // Ranges that are in the old access but not the new access need to be removed
988 // from the offset bins.
990 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
991 LLVM_DEBUG(if (ToRemove.size()) dbgs()
992 << "[AAPointerInfo] Removing access from old offset bins\n";);
993
994 for (auto Key : ToRemove) {
995 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
996 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
997 auto &Bin = OffsetBins[Key];
998 assert(Bin.count(AccIndex) &&
999 "Expected bin to actually contain the Access.");
1000 Bin.erase(AccIndex);
1001 }
1002
1003 // Ranges that are in the new access but not the old access need to be added
1004 // to the offset bins.
1006 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1007 AddToBins(ToAdd);
1008 return ChangeStatus::CHANGED;
1009}
1010
1011namespace {
1012
1013#ifndef NDEBUG
1015 const AAPointerInfo::OffsetInfo &OI) {
1016 OS << llvm::interleaved_array(OI);
1017 return OS;
1018}
1019#endif // NDEBUG
1020
1021struct AAPointerInfoImpl
1022 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1024 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1025
1026 /// See AbstractAttribute::getAsStr().
1027 const std::string getAsStr(Attributor *A) const override {
1028 return std::string("PointerInfo ") +
1029 (isValidState() ? (std::string("#") +
1030 std::to_string(OffsetBins.size()) + " bins")
1031 : "<invalid>") +
1032 (reachesReturn()
1033 ? (" (returned:" +
1034 join(map_range(ReturnedOffsets,
1035 [](int64_t O) { return std::to_string(O); }),
1036 ", ") +
1037 ")")
1038 : "");
1039 }
1040
1041 /// See AbstractAttribute::manifest(...).
1042 ChangeStatus manifest(Attributor &A) override {
1043 return AAPointerInfo::manifest(A);
1044 }
1045
1046 const_bin_iterator begin() const override { return State::begin(); }
1047 const_bin_iterator end() const override { return State::end(); }
1048 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1049 bool reachesReturn() const override {
1050 return !ReturnedOffsets.isUnassigned();
1051 }
1052 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1053 if (ReturnedOffsets.isUnknown()) {
1054 OI.setUnknown();
1055 return;
1056 }
1057
1058 OffsetInfo MergedOI;
1059 for (auto Offset : ReturnedOffsets) {
1060 OffsetInfo TmpOI = OI;
1061 TmpOI.addToAll(Offset);
1062 MergedOI.merge(TmpOI);
1063 }
1064 OI = std::move(MergedOI);
1065 }
1066
1067 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1068 if (ReturnedOffsets.isUnknown())
1069 return ChangeStatus::UNCHANGED;
1070 if (ReachedReturnedOffsets.isUnknown()) {
1071 ReturnedOffsets.setUnknown();
1072 return ChangeStatus::CHANGED;
1073 }
1074 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1075 return ChangeStatus::CHANGED;
1076 return ChangeStatus::UNCHANGED;
1077 }
1078
1079 bool forallInterferingAccesses(
1080 AA::RangeTy Range,
1081 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1082 const override {
1083 return State::forallInterferingAccesses(Range, CB);
1084 }
1085
1086 bool forallInterferingAccesses(
1087 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1088 bool FindInterferingWrites, bool FindInterferingReads,
1089 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1090 AA::RangeTy &Range,
1091 function_ref<bool(const Access &)> SkipCB) const override {
1092 HasBeenWrittenTo = false;
1093
1094 SmallPtrSet<const Access *, 8> DominatingWrites;
1095 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1096
1097 Function &Scope = *I.getFunction();
1098 bool IsKnownNoSync;
1099 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1100 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1101 IsKnownNoSync);
1102 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1103 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1104 bool AllInSameNoSyncFn = IsAssumedNoSync;
1105 bool InstIsExecutedByInitialThreadOnly =
1106 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1107
1108 // If the function is not ending in aligned barriers, we need the stores to
1109 // be in aligned barriers. The load being in one is not sufficient since the
1110 // store might be executed by a thread that disappears after, causing the
1111 // aligned barrier guarding the load to unblock and the load to read a value
1112 // that has no CFG path to the load.
1113 bool InstIsExecutedInAlignedRegion =
1114 FindInterferingReads && ExecDomainAA &&
1115 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1116
1117 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1118 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1119
1120 InformationCache &InfoCache = A.getInfoCache();
1121 bool IsThreadLocalObj =
1122 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1123
1124 // Helper to determine if we need to consider threading, which we cannot
1125 // right now. However, if the function is (assumed) nosync or the thread
1126 // executing all instructions is the main thread only we can ignore
1127 // threading. Also, thread-local objects do not require threading reasoning.
1128 // Finally, we can ignore threading if either access is executed in an
1129 // aligned region.
1130 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1131 if (IsThreadLocalObj || AllInSameNoSyncFn)
1132 return true;
1133 const auto *FnExecDomainAA =
1134 I.getFunction() == &Scope
1135 ? ExecDomainAA
1136 : A.lookupAAFor<AAExecutionDomain>(
1137 IRPosition::function(*I.getFunction()), &QueryingAA,
1138 DepClassTy::NONE);
1139 if (!FnExecDomainAA)
1140 return false;
1141 if (InstIsExecutedInAlignedRegion ||
1142 (FindInterferingWrites &&
1143 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1144 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1145 return true;
1146 }
1147 if (InstIsExecutedByInitialThreadOnly &&
1148 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1149 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1150 return true;
1151 }
1152 return false;
1153 };
1154
1155 // Helper to determine if the access is executed by the same thread as the
1156 // given instruction, for now it is sufficient to avoid any potential
1157 // threading effects as we cannot deal with them anyway.
1158 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1159 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1160 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1161 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1162 };
1163
1164 // TODO: Use inter-procedural reachability and dominance.
1165 bool IsKnownNoRecurse;
1167 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1168 IsKnownNoRecurse);
1169
1170 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1171 // AAExecutionDomain) such that we allow scopes other than kernels as long
1172 // as the reaching kernels are disjoint.
1173 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1174 bool ObjHasKernelLifetime = false;
1175 const bool UseDominanceReasoning =
1176 FindInterferingWrites && IsKnownNoRecurse;
1177 const DominatorTree *DT =
1178 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1179
1180 // Helper to check if a value has "kernel lifetime", that is it will not
1181 // outlive a GPU kernel. This is true for shared, constant, and local
1182 // globals on AMD and NVIDIA GPUs.
1183 auto HasKernelLifetime = [&](Value *V, Module &M) {
1184 if (!AA::isGPU(M))
1185 return false;
1186 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1187 case AA::GPUAddressSpace::Shared:
1188 case AA::GPUAddressSpace::Constant:
1189 case AA::GPUAddressSpace::Local:
1190 return true;
1191 default:
1192 return false;
1193 };
1194 };
1195
1196 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1197 // to determine if we should look at reachability from the callee. For
1198 // certain pointers we know the lifetime and we do not have to step into the
1199 // callee to determine reachability as the pointer would be dead in the
1200 // callee. See the conditional initialization below.
1201 std::function<bool(const Function &)> IsLiveInCalleeCB;
1202
1203 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1204 // If the alloca containing function is not recursive the alloca
1205 // must be dead in the callee.
1206 const Function *AIFn = AI->getFunction();
1207 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1208 bool IsKnownNoRecurse;
1210 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1211 IsKnownNoRecurse)) {
1212 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1213 }
1214 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1215 // If the global has kernel lifetime we can stop if we reach a kernel
1216 // as it is "dead" in the (unknown) callees.
1217 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1218 if (ObjHasKernelLifetime)
1219 IsLiveInCalleeCB = [&A](const Function &Fn) {
1220 return !A.getInfoCache().isKernel(Fn);
1221 };
1222 }
1223
1224 // Set of accesses/instructions that will overwrite the result and are
1225 // therefore blockers in the reachability traversal.
1226 AA::InstExclusionSetTy ExclusionSet;
1227
1228 auto AccessCB = [&](const Access &Acc, bool Exact) {
1229 Function *AccScope = Acc.getRemoteInst()->getFunction();
1230 bool AccInSameScope = AccScope == &Scope;
1231
1232 // If the object has kernel lifetime we can ignore accesses only reachable
1233 // by other kernels. For now we only skip accesses *in* other kernels.
1234 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1235 A.getInfoCache().isKernel(*AccScope))
1236 return true;
1237
1238 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1239 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1240 ExclusionSet.insert(Acc.getRemoteInst());
1241 }
1242
1243 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1244 (!FindInterferingReads || !Acc.isRead()))
1245 return true;
1246
1247 bool Dominates = FindInterferingWrites && DT && Exact &&
1248 Acc.isMustAccess() && AccInSameScope &&
1249 DT->dominates(Acc.getRemoteInst(), &I);
1250 if (Dominates)
1251 DominatingWrites.insert(&Acc);
1252
1253 // Track if all interesting accesses are in the same `nosync` function as
1254 // the given instruction.
1255 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1256
1257 InterferingAccesses.push_back({&Acc, Exact});
1258 return true;
1259 };
1260 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1261 return false;
1262
1263 HasBeenWrittenTo = !DominatingWrites.empty();
1264
1265 // Dominating writes form a chain, find the least/lowest member.
1266 Instruction *LeastDominatingWriteInst = nullptr;
1267 for (const Access *Acc : DominatingWrites) {
1268 if (!LeastDominatingWriteInst) {
1269 LeastDominatingWriteInst = Acc->getRemoteInst();
1270 } else if (DT->dominates(LeastDominatingWriteInst,
1271 Acc->getRemoteInst())) {
1272 LeastDominatingWriteInst = Acc->getRemoteInst();
1273 }
1274 }
1275
1276 // Helper to determine if we can skip a specific write access.
1277 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1278 if (SkipCB && SkipCB(Acc))
1279 return true;
1280 if (!CanIgnoreThreading(Acc))
1281 return false;
1282
1283 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1284 // If we successfully excluded all effects we are interested in, the
1285 // access can be skipped.
1286 bool ReadChecked = !FindInterferingReads;
1287 bool WriteChecked = !FindInterferingWrites;
1288
1289 // If the instruction cannot reach the access, the former does not
1290 // interfere with what the access reads.
1291 if (!ReadChecked) {
1292 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1293 &ExclusionSet, IsLiveInCalleeCB))
1294 ReadChecked = true;
1295 }
1296 // If the instruction cannot be reach from the access, the latter does not
1297 // interfere with what the instruction reads.
1298 if (!WriteChecked) {
1299 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1300 &ExclusionSet, IsLiveInCalleeCB))
1301 WriteChecked = true;
1302 }
1303
1304 // If we still might be affected by the write of the access but there are
1305 // dominating writes in the function of the instruction
1306 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1307 // by them. This would have happend above if they are all in the same
1308 // function, so we only check the inter-procedural case. Effectively, we
1309 // want to show that there is no call after the dominting write that might
1310 // reach the access, and when it returns reach the instruction with the
1311 // updated value. To this end, we iterate all call sites, check if they
1312 // might reach the instruction without going through another access
1313 // (ExclusionSet) and at the same time might reach the access. However,
1314 // that is all part of AAInterFnReachability.
1315 if (!WriteChecked && HasBeenWrittenTo &&
1316 Acc.getRemoteInst()->getFunction() != &Scope) {
1317
1318 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1319 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1320 if (FnReachabilityAA) {
1321 // Without going backwards in the call tree, can we reach the access
1322 // from the least dominating write. Do not allow to pass the
1323 // instruction itself either.
1324 bool Inserted = ExclusionSet.insert(&I).second;
1325
1326 if (!FnReachabilityAA->instructionCanReach(
1327 A, *LeastDominatingWriteInst,
1328 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1329 WriteChecked = true;
1330
1331 if (Inserted)
1332 ExclusionSet.erase(&I);
1333 }
1334 }
1335
1336 if (ReadChecked && WriteChecked)
1337 return true;
1338
1339 if (!DT || !UseDominanceReasoning)
1340 return false;
1341 if (!DominatingWrites.count(&Acc))
1342 return false;
1343 return LeastDominatingWriteInst != Acc.getRemoteInst();
1344 };
1345
1346 // Run the user callback on all accesses we cannot skip and return if
1347 // that succeeded for all or not.
1348 for (auto &It : InterferingAccesses) {
1349 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1350 !CanSkipAccess(*It.first, It.second)) {
1351 if (!UserCB(*It.first, It.second))
1352 return false;
1353 }
1354 }
1355 return true;
1356 }
1357
1358 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1359 const AAPointerInfo &OtherAA,
1360 CallBase &CB) {
1361 using namespace AA::PointerInfo;
1362 if (!OtherAA.getState().isValidState() || !isValidState())
1363 return indicatePessimisticFixpoint();
1364
1365 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1366 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1367 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1368 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1369
1370 // Combine the accesses bin by bin.
1371 const auto &State = OtherAAImpl.getState();
1372 for (const auto &It : State) {
1373 for (auto Index : It.getSecond()) {
1374 const auto &RAcc = State.getAccess(Index);
1375 if (IsByval && !RAcc.isRead())
1376 continue;
1377 bool UsedAssumedInformation = false;
1378 AccessKind AK = RAcc.getKind();
1379 auto Content = A.translateArgumentToCallSiteContent(
1380 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1381 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1382 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1383
1384 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1385 RAcc.getType(), RAcc.getRemoteInst());
1386 }
1387 }
1388 return Changed;
1389 }
1390
1391 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1392 const OffsetInfo &Offsets, CallBase &CB,
1393 bool IsMustAcc) {
1394 using namespace AA::PointerInfo;
1395 if (!OtherAA.getState().isValidState() || !isValidState())
1396 return indicatePessimisticFixpoint();
1397
1398 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1399
1400 // Combine the accesses bin by bin.
1401 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1402 const auto &State = OtherAAImpl.getState();
1403 for (const auto &It : State) {
1404 for (auto Index : It.getSecond()) {
1405 const auto &RAcc = State.getAccess(Index);
1406 if (!IsMustAcc && RAcc.isAssumption())
1407 continue;
1408 for (auto Offset : Offsets) {
1409 auto NewRanges = Offset == AA::RangeTy::Unknown
1411 : RAcc.getRanges();
1412 if (!NewRanges.isUnknown()) {
1413 NewRanges.addToAllOffsets(Offset);
1414 }
1415 AccessKind AK = RAcc.getKind();
1416 if (!IsMustAcc)
1417 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1418 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1419 RAcc.getType(), RAcc.getRemoteInst());
1420 }
1421 }
1422 }
1423 return Changed;
1424 }
1425
1426 /// Statistic tracking for all AAPointerInfo implementations.
1427 /// See AbstractAttribute::trackStatistics().
1428 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1429
1430 /// Dump the state into \p O.
1431 void dumpState(raw_ostream &O) {
1432 for (auto &It : OffsetBins) {
1433 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1434 << "] : " << It.getSecond().size() << "\n";
1435 for (auto AccIndex : It.getSecond()) {
1436 auto &Acc = AccessList[AccIndex];
1437 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1438 if (Acc.getLocalInst() != Acc.getRemoteInst())
1439 O << " --> " << *Acc.getRemoteInst()
1440 << "\n";
1441 if (!Acc.isWrittenValueYetUndetermined()) {
1442 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1443 O << " - c: func " << Acc.getWrittenValue()->getName()
1444 << "\n";
1445 else if (Acc.getWrittenValue())
1446 O << " - c: " << *Acc.getWrittenValue() << "\n";
1447 else
1448 O << " - c: <unknown>\n";
1449 }
1450 }
1451 }
1452 }
1453};
1454
1455struct AAPointerInfoFloating : public AAPointerInfoImpl {
1457 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1458 : AAPointerInfoImpl(IRP, A) {}
1459
1460 /// Deal with an access and signal if it was handled successfully.
1461 bool handleAccess(Attributor &A, Instruction &I,
1462 std::optional<Value *> Content, AccessKind Kind,
1463 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1464 Type &Ty) {
1465 using namespace AA::PointerInfo;
1467 const DataLayout &DL = A.getDataLayout();
1468 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1469 if (!AccessSize.isScalable())
1470 Size = AccessSize.getFixedValue();
1471
1472 // Make a strictly ascending list of offsets as required by addAccess()
1473 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1474 llvm::sort(OffsetsSorted);
1475
1477 if (!VT || VT->getElementCount().isScalable() ||
1478 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1479 (*Content)->getType() != VT ||
1480 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1481 Changed =
1482 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1483 } else {
1484 // Handle vector stores with constant content element-wise.
1485 // TODO: We could look for the elements or create instructions
1486 // representing them.
1487 // TODO: We need to push the Content into the range abstraction
1488 // (AA::RangeTy) to allow different content values for different
1489 // ranges. ranges. Hence, support vectors storing different values.
1490 Type *ElementType = VT->getElementType();
1491 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1492 auto *ConstContent = cast<Constant>(*Content);
1493 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1494 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1495
1496 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1497 Value *ElementContent = ConstantExpr::getExtractElement(
1498 ConstContent, ConstantInt::get(Int32Ty, i));
1499
1500 // Add the element access.
1501 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1502 ElementContent, Kind, ElementType);
1503
1504 // Advance the offsets for the next element.
1505 for (auto &ElementOffset : ElementOffsets)
1506 ElementOffset += ElementSize;
1507 }
1508 }
1509 return true;
1510 };
1511
1512 /// See AbstractAttribute::updateImpl(...).
1513 ChangeStatus updateImpl(Attributor &A) override;
1514
1515 /// If the indices to \p GEP can be traced to constants, incorporate all
1516 /// of these into \p UsrOI.
1517 ///
1518 /// \return true iff \p UsrOI is updated.
1519 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1520 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1521 const GEPOperator *GEP);
1522
1523 /// See AbstractAttribute::trackStatistics()
1524 void trackStatistics() const override {
1525 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1526 }
1527};
1528
1529bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1530 const DataLayout &DL,
1531 OffsetInfo &UsrOI,
1532 const OffsetInfo &PtrOI,
1533 const GEPOperator *GEP) {
1534 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1535 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1536 APInt ConstantOffset(BitWidth, 0);
1537
1538 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1539 "Don't look for constant values if the offset has already been "
1540 "determined to be unknown.");
1541
1542 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1543 UsrOI.setUnknown();
1544 return true;
1545 }
1546
1547 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1548 << (VariableOffsets.empty() ? "" : "not") << " constant "
1549 << *GEP << "\n");
1550
1551 auto Union = PtrOI;
1552 Union.addToAll(ConstantOffset.getSExtValue());
1553
1554 // Each VI in VariableOffsets has a set of potential constant values. Every
1555 // combination of elements, picked one each from these sets, is separately
1556 // added to the original set of offsets, thus resulting in more offsets.
1557 for (const auto &VI : VariableOffsets) {
1558 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1559 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1560 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1561 UsrOI.setUnknown();
1562 return true;
1563 }
1564
1565 // UndefValue is treated as a zero, which leaves Union as is.
1566 if (PotentialConstantsAA->undefIsContained())
1567 continue;
1568
1569 // We need at least one constant in every set to compute an actual offset.
1570 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1571 // don't actually exist. In other words, the absence of constant values
1572 // implies that the operation can be assumed dead for now.
1573 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1574 if (AssumedSet.empty())
1575 return false;
1576
1577 OffsetInfo Product;
1578 for (const auto &ConstOffset : AssumedSet) {
1579 auto CopyPerOffset = Union;
1580 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1581 VI.second.getZExtValue());
1582 Product.merge(CopyPerOffset);
1583 }
1584 Union = Product;
1585 }
1586
1587 UsrOI = std::move(Union);
1588 return true;
1589}
1590
1591ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1592 using namespace AA::PointerInfo;
1594 const DataLayout &DL = A.getDataLayout();
1595 Value &AssociatedValue = getAssociatedValue();
1596
1597 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1598 OffsetInfoMap[&AssociatedValue].insert(0);
1599
1600 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1601 // One does not simply walk into a map and assign a reference to a possibly
1602 // new location. That can cause an invalidation before the assignment
1603 // happens, like so:
1604 //
1605 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1606 //
1607 // The RHS is a reference that may be invalidated by an insertion caused by
1608 // the LHS. So we ensure that the side-effect of the LHS happens first.
1609
1610 assert(OffsetInfoMap.contains(CurPtr) &&
1611 "CurPtr does not exist in the map!");
1612
1613 auto &UsrOI = OffsetInfoMap[Usr];
1614 auto &PtrOI = OffsetInfoMap[CurPtr];
1615 assert(!PtrOI.isUnassigned() &&
1616 "Cannot pass through if the input Ptr was not visited!");
1617 UsrOI.merge(PtrOI);
1618 Follow = true;
1619 return true;
1620 };
1621
1622 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1623 Value *CurPtr = U.get();
1624 User *Usr = U.getUser();
1625 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1626 << "\n");
1627 assert(OffsetInfoMap.count(CurPtr) &&
1628 "The current pointer offset should have been seeded!");
1629 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1630 "Current pointer should be assigned");
1631
1632 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1633 if (CE->isCast())
1634 return HandlePassthroughUser(Usr, CurPtr, Follow);
1635 if (!isa<GEPOperator>(CE)) {
1636 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1637 << "\n");
1638 return false;
1639 }
1640 }
1641 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1642 // Note the order here, the Usr access might change the map, CurPtr is
1643 // already in it though.
1644 auto &UsrOI = OffsetInfoMap[Usr];
1645 auto &PtrOI = OffsetInfoMap[CurPtr];
1646
1647 if (UsrOI.isUnknown())
1648 return true;
1649
1650 if (PtrOI.isUnknown()) {
1651 Follow = true;
1652 UsrOI.setUnknown();
1653 return true;
1654 }
1655
1656 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1657 return true;
1658 }
1659 if (isa<PtrToIntInst>(Usr))
1660 return false;
1661 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1662 return HandlePassthroughUser(Usr, CurPtr, Follow);
1663 // Returns are allowed if they are in the associated functions. Users can
1664 // then check the call site return. Returns from other functions can't be
1665 // tracked and are cause for invalidation.
1666 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1667 if (RI->getFunction() == getAssociatedFunction()) {
1668 auto &PtrOI = OffsetInfoMap[CurPtr];
1669 Changed |= setReachesReturn(PtrOI);
1670 return true;
1671 }
1672 return false;
1673 }
1674
1675 // For PHIs we need to take care of the recurrence explicitly as the value
1676 // might change while we iterate through a loop. For now, we give up if
1677 // the PHI is not invariant.
1678 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1679 // Note the order here, the Usr access might change the map, CurPtr is
1680 // already in it though.
1681 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1682 auto &UsrOI = PhiIt->second;
1683 auto &PtrOI = OffsetInfoMap[CurPtr];
1684
1685 // Check if the PHI operand has already an unknown offset as we can't
1686 // improve on that anymore.
1687 if (PtrOI.isUnknown()) {
1688 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1689 << *CurPtr << " in " << *PHI << "\n");
1690 Follow = !UsrOI.isUnknown();
1691 UsrOI.setUnknown();
1692 return true;
1693 }
1694
1695 // Check if the PHI is invariant (so far).
1696 if (UsrOI == PtrOI) {
1697 assert(!PtrOI.isUnassigned() &&
1698 "Cannot assign if the current Ptr was not visited!");
1699 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1700 return true;
1701 }
1702
1703 // Check if the PHI operand can be traced back to AssociatedValue.
1704 APInt Offset(
1705 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1706 0);
1707 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1708 DL, Offset, /* AllowNonInbounds */ true);
1709 auto It = OffsetInfoMap.find(CurPtrBase);
1710 if (It == OffsetInfoMap.end()) {
1711 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1712 << *CurPtr << " in " << *PHI
1713 << " (base: " << *CurPtrBase << ")\n");
1714 UsrOI.setUnknown();
1715 Follow = true;
1716 return true;
1717 }
1718
1719 // Check if the PHI operand is not dependent on the PHI itself. Every
1720 // recurrence is a cyclic net of PHIs in the data flow, and has an
1721 // equivalent Cycle in the control flow. One of those PHIs must be in the
1722 // header of that control flow Cycle. This is independent of the choice of
1723 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1724 // every Cycle header; if such a node is marked unknown, this will
1725 // eventually propagate through the whole net of PHIs in the recurrence.
1726 const auto *CI =
1727 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1728 *PHI->getFunction());
1729 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1730 auto BaseOI = It->getSecond();
1731 BaseOI.addToAll(Offset.getZExtValue());
1732 if (IsFirstPHIUser || BaseOI == UsrOI) {
1733 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1734 << " in " << *Usr << "\n");
1735 return HandlePassthroughUser(Usr, CurPtr, Follow);
1736 }
1737
1738 LLVM_DEBUG(
1739 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1740 << *CurPtr << " in " << *PHI << "\n");
1741 UsrOI.setUnknown();
1742 Follow = true;
1743 return true;
1744 }
1745
1746 UsrOI.merge(PtrOI);
1747 Follow = true;
1748 return true;
1749 }
1750
1751 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1752 // If the access is to a pointer that may or may not be the associated
1753 // value, e.g. due to a PHI, we cannot assume it will be read.
1754 AccessKind AK = AccessKind::AK_R;
1755 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1756 AK = AccessKind(AK | AccessKind::AK_MUST);
1757 else
1758 AK = AccessKind(AK | AccessKind::AK_MAY);
1759 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1760 OffsetInfoMap[CurPtr].Offsets, Changed,
1761 *LoadI->getType()))
1762 return false;
1763
1764 auto IsAssumption = [](Instruction &I) {
1765 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1766 return II->isAssumeLikeIntrinsic();
1767 return false;
1768 };
1769
1770 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1771 // Check if the assumption and the load are executed together without
1772 // memory modification.
1773 do {
1774 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1775 return true;
1776 FromI = FromI->getNextNode();
1777 } while (FromI && FromI != ToI);
1778 return false;
1779 };
1780
1781 BasicBlock *BB = LoadI->getParent();
1782 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1783 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1784 return false;
1785 BasicBlock *IntrBB = IntrI.getParent();
1786 if (IntrI.getParent() == BB) {
1787 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1788 return false;
1789 } else {
1790 auto PredIt = pred_begin(IntrBB);
1791 if (PredIt == pred_end(IntrBB))
1792 return false;
1793 if ((*PredIt) != BB)
1794 return false;
1795 if (++PredIt != pred_end(IntrBB))
1796 return false;
1797 for (auto *SuccBB : successors(BB)) {
1798 if (SuccBB == IntrBB)
1799 continue;
1800 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1801 continue;
1802 return false;
1803 }
1804 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1805 return false;
1806 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1807 return false;
1808 }
1809 return true;
1810 };
1811
1812 std::pair<Value *, IntrinsicInst *> Assumption;
1813 for (const Use &LoadU : LoadI->uses()) {
1814 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1815 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1816 continue;
1817 for (const Use &CmpU : CmpI->uses()) {
1818 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1819 if (!IsValidAssume(*IntrI))
1820 continue;
1821 int Idx = CmpI->getOperandUse(0) == LoadU;
1822 Assumption = {CmpI->getOperand(Idx), IntrI};
1823 break;
1824 }
1825 }
1826 }
1827 if (Assumption.first)
1828 break;
1829 }
1830
1831 // Check if we found an assumption associated with this load.
1832 if (!Assumption.first || !Assumption.second)
1833 return true;
1834
1835 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1836 << *Assumption.second << ": " << *LoadI
1837 << " == " << *Assumption.first << "\n");
1838 bool UsedAssumedInformation = false;
1839 std::optional<Value *> Content = nullptr;
1840 if (Assumption.first)
1841 Content =
1842 A.getAssumedSimplified(*Assumption.first, *this,
1843 UsedAssumedInformation, AA::Interprocedural);
1844 return handleAccess(
1845 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1846 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1847 }
1848
1849 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1850 ArrayRef<Value *> OtherOps, AccessKind AK) {
1851 for (auto *OtherOp : OtherOps) {
1852 if (OtherOp == CurPtr) {
1853 LLVM_DEBUG(
1854 dbgs()
1855 << "[AAPointerInfo] Escaping use in store like instruction " << I
1856 << "\n");
1857 return false;
1858 }
1859 }
1860
1861 // If the access is to a pointer that may or may not be the associated
1862 // value, e.g. due to a PHI, we cannot assume it will be written.
1863 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1864 AK = AccessKind(AK | AccessKind::AK_MUST);
1865 else
1866 AK = AccessKind(AK | AccessKind::AK_MAY);
1867 bool UsedAssumedInformation = false;
1868 std::optional<Value *> Content = nullptr;
1869 if (ValueOp)
1870 Content = A.getAssumedSimplified(
1871 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1872 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1873 Changed, ValueTy);
1874 };
1875
1876 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1877 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1878 *StoreI->getValueOperand()->getType(),
1879 {StoreI->getValueOperand()}, AccessKind::AK_W);
1880 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1881 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1882 {RMWI->getValOperand()}, AccessKind::AK_RW);
1883 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1884 return HandleStoreLike(
1885 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1886 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1887 AccessKind::AK_RW);
1888
1889 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1890 if (CB->isLifetimeStartOrEnd())
1891 return true;
1892 const auto *TLI =
1893 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1894 if (getFreedOperand(CB, TLI) == U)
1895 return true;
1896 if (CB->isArgOperand(&U)) {
1897 unsigned ArgNo = CB->getArgOperandNo(&U);
1898 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1899 *this, IRPosition::callsite_argument(*CB, ArgNo),
1901 if (!CSArgPI)
1902 return false;
1903 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1904 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1905 IsArgMustAcc) |
1906 Changed;
1907 if (!CSArgPI->reachesReturn())
1908 return isValidState();
1909
1911 if (!Callee || Callee->arg_size() <= ArgNo)
1912 return false;
1913 bool UsedAssumedInformation = false;
1914 auto ReturnedValue = A.getAssumedSimplified(
1915 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1917 auto *ReturnedArg =
1918 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1919 auto *Arg = Callee->getArg(ArgNo);
1920 if (ReturnedArg && Arg != ReturnedArg)
1921 return true;
1922 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1923 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1925 if (!CSRetPI)
1926 return false;
1927 OffsetInfo OI = OffsetInfoMap[CurPtr];
1928 CSArgPI->addReturnedOffsetsTo(OI);
1929 Changed =
1930 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1931 return isValidState();
1932 }
1933 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1934 << "\n");
1935 return false;
1936 }
1937
1938 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1939 return false;
1940 };
1941 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1942 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1943 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1944 if (OffsetInfoMap.count(NewU)) {
1945 LLVM_DEBUG({
1946 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1947 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1948 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1949 << "\n";
1950 }
1951 });
1952 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1953 }
1954 bool Unused;
1955 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1956 };
1957 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1958 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1959 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1960 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1961 return indicatePessimisticFixpoint();
1962 }
1963
1964 LLVM_DEBUG({
1965 dbgs() << "Accesses by bin after update:\n";
1966 dumpState(dbgs());
1967 });
1968
1969 return Changed;
1970}
1971
1972struct AAPointerInfoReturned final : AAPointerInfoImpl {
1973 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1974 : AAPointerInfoImpl(IRP, A) {}
1975
1976 /// See AbstractAttribute::updateImpl(...).
1977 ChangeStatus updateImpl(Attributor &A) override {
1978 return indicatePessimisticFixpoint();
1979 }
1980
1981 /// See AbstractAttribute::trackStatistics()
1982 void trackStatistics() const override {
1983 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1984 }
1985};
1986
1987struct AAPointerInfoArgument final : AAPointerInfoFloating {
1988 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1989 : AAPointerInfoFloating(IRP, A) {}
1990
1991 /// See AbstractAttribute::trackStatistics()
1992 void trackStatistics() const override {
1993 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1994 }
1995};
1996
1997struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1998 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1999 : AAPointerInfoFloating(IRP, A) {}
2000
2001 /// See AbstractAttribute::updateImpl(...).
2002 ChangeStatus updateImpl(Attributor &A) override {
2003 using namespace AA::PointerInfo;
2004 // We handle memory intrinsics explicitly, at least the first (=
2005 // destination) and second (=source) arguments as we know how they are
2006 // accessed.
2007 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2008 int64_t LengthVal = AA::RangeTy::Unknown;
2009 if (auto Length = MI->getLengthInBytes())
2010 LengthVal = Length->getSExtValue();
2011 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2012 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2013 if (ArgNo > 1) {
2014 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2015 << *MI << "\n");
2016 return indicatePessimisticFixpoint();
2017 } else {
2018 auto Kind =
2019 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2020 Changed =
2021 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2022 }
2023 LLVM_DEBUG({
2024 dbgs() << "Accesses by bin after update:\n";
2025 dumpState(dbgs());
2026 });
2027
2028 return Changed;
2029 }
2030
2031 // TODO: Once we have call site specific value information we can provide
2032 // call site specific liveness information and then it makes
2033 // sense to specialize attributes for call sites arguments instead of
2034 // redirecting requests to the callee argument.
2035 Argument *Arg = getAssociatedArgument();
2036 if (Arg) {
2037 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2038 auto *ArgAA =
2039 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2040 if (ArgAA && ArgAA->getState().isValidState())
2041 return translateAndAddStateFromCallee(A, *ArgAA,
2042 *cast<CallBase>(getCtxI()));
2043 if (!Arg->getParent()->isDeclaration())
2044 return indicatePessimisticFixpoint();
2045 }
2046
2047 bool IsKnownNoCapture;
2049 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2050 return indicatePessimisticFixpoint();
2051
2052 bool IsKnown = false;
2053 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2054 return ChangeStatus::UNCHANGED;
2055 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2056 auto Kind =
2057 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2058 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2059 nullptr);
2060 }
2061
2062 /// See AbstractAttribute::trackStatistics()
2063 void trackStatistics() const override {
2064 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2065 }
2066};
2067
2068struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2069 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2070 : AAPointerInfoFloating(IRP, A) {}
2071
2072 /// See AbstractAttribute::trackStatistics()
2073 void trackStatistics() const override {
2074 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2075 }
2076};
2077} // namespace
2078
2079/// -----------------------NoUnwind Function Attribute--------------------------
2080
2081namespace {
2082struct AANoUnwindImpl : AANoUnwind {
2083 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2084
2085 /// See AbstractAttribute::initialize(...).
2086 void initialize(Attributor &A) override {
2087 bool IsKnown;
2089 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2090 (void)IsKnown;
2091 }
2092
2093 const std::string getAsStr(Attributor *A) const override {
2094 return getAssumed() ? "nounwind" : "may-unwind";
2095 }
2096
2097 /// See AbstractAttribute::updateImpl(...).
2098 ChangeStatus updateImpl(Attributor &A) override {
2099 auto Opcodes = {
2100 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2101 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2102 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2103
2104 auto CheckForNoUnwind = [&](Instruction &I) {
2105 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2106 return true;
2107
2108 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2109 bool IsKnownNoUnwind;
2111 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2112 IsKnownNoUnwind);
2113 }
2114 return false;
2115 };
2116
2117 bool UsedAssumedInformation = false;
2118 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2119 UsedAssumedInformation))
2120 return indicatePessimisticFixpoint();
2121
2122 return ChangeStatus::UNCHANGED;
2123 }
2124};
2125
2126struct AANoUnwindFunction final : public AANoUnwindImpl {
2127 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2128 : AANoUnwindImpl(IRP, A) {}
2129
2130 /// See AbstractAttribute::trackStatistics()
2131 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2132};
2133
2134/// NoUnwind attribute deduction for a call sites.
2135struct AANoUnwindCallSite final
2136 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2137 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2138 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2139
2140 /// See AbstractAttribute::trackStatistics()
2141 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2142};
2143} // namespace
2144
2145/// ------------------------ NoSync Function Attribute -------------------------
2146
2147bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2148 switch (CB.getIntrinsicID()) {
2149 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2150 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2151 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2152 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2153 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2154 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2155 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2156 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
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<CondBrInst>(&I);
3014
3015 // Either we stopped and the appropriate action was taken,
3016 // or we got back a simplified value to continue.
3017 std::optional<Value *> SimplifiedCond =
3018 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3019 if (!SimplifiedCond || !*SimplifiedCond)
3020 return true;
3021 AssumedNoUBInsts.insert(&I);
3022 return true;
3023 };
3024
3025 auto InspectCallSiteForUB = [&](Instruction &I) {
3026 // Check whether a callsite always cause UB or not
3027
3028 // Skip instructions that are already saved.
3029 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3030 return true;
3031
3032 // Check nonnull and noundef argument attribute violation for each
3033 // callsite.
3034 CallBase &CB = cast<CallBase>(I);
3036 if (!Callee)
3037 return true;
3038 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3039 // If current argument is known to be simplified to null pointer and the
3040 // corresponding argument position is known to have nonnull attribute,
3041 // the argument is poison. Furthermore, if the argument is poison and
3042 // the position is known to have noundef attriubte, this callsite is
3043 // considered UB.
3044 if (idx >= Callee->arg_size())
3045 break;
3046 Value *ArgVal = CB.getArgOperand(idx);
3047 if (!ArgVal)
3048 continue;
3049 // Here, we handle three cases.
3050 // (1) Not having a value means it is dead. (we can replace the value
3051 // with undef)
3052 // (2) Simplified to undef. The argument violate noundef attriubte.
3053 // (3) Simplified to null pointer where known to be nonnull.
3054 // The argument is a poison value and violate noundef attribute.
3055 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3056 bool IsKnownNoUndef;
3058 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3059 if (!IsKnownNoUndef)
3060 continue;
3061 bool UsedAssumedInformation = false;
3062 std::optional<Value *> SimplifiedVal =
3063 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3064 UsedAssumedInformation, AA::Interprocedural);
3065 if (UsedAssumedInformation)
3066 continue;
3067 if (SimplifiedVal && !*SimplifiedVal)
3068 return true;
3069 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3070 KnownUBInsts.insert(&I);
3071 continue;
3072 }
3073 if (!ArgVal->getType()->isPointerTy() ||
3074 !isa<ConstantPointerNull>(**SimplifiedVal))
3075 continue;
3076 bool IsKnownNonNull;
3078 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3079 if (IsKnownNonNull)
3080 KnownUBInsts.insert(&I);
3081 }
3082 return true;
3083 };
3084
3085 auto InspectReturnInstForUB = [&](Instruction &I) {
3086 auto &RI = cast<ReturnInst>(I);
3087 // Either we stopped and the appropriate action was taken,
3088 // or we got back a simplified return value to continue.
3089 std::optional<Value *> SimplifiedRetValue =
3090 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3091 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3092 return true;
3093
3094 // Check if a return instruction always cause UB or not
3095 // Note: It is guaranteed that the returned position of the anchor
3096 // scope has noundef attribute when this is called.
3097 // We also ensure the return position is not "assumed dead"
3098 // because the returned value was then potentially simplified to
3099 // `undef` in AAReturnedValues without removing the `noundef`
3100 // attribute yet.
3101
3102 // When the returned position has noundef attriubte, UB occurs in the
3103 // following cases.
3104 // (1) Returned value is known to be undef.
3105 // (2) The value is known to be a null pointer and the returned
3106 // position has nonnull attribute (because the returned value is
3107 // poison).
3108 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3109 bool IsKnownNonNull;
3111 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3112 IsKnownNonNull);
3113 if (IsKnownNonNull)
3114 KnownUBInsts.insert(&I);
3115 }
3116
3117 return true;
3118 };
3119
3120 bool UsedAssumedInformation = false;
3121 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3122 {Instruction::Load, Instruction::Store,
3123 Instruction::AtomicCmpXchg,
3124 Instruction::AtomicRMW},
3125 UsedAssumedInformation,
3126 /* CheckBBLivenessOnly */ true);
3127 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3128 UsedAssumedInformation,
3129 /* CheckBBLivenessOnly */ true);
3130 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3131 UsedAssumedInformation);
3132
3133 // If the returned position of the anchor scope has noundef attriubte, check
3134 // all returned instructions.
3135 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3136 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3137 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3138 bool IsKnownNoUndef;
3140 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3141 if (IsKnownNoUndef)
3142 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3143 {Instruction::Ret}, UsedAssumedInformation,
3144 /* CheckBBLivenessOnly */ true);
3145 }
3146 }
3147
3148 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3149 UBPrevSize != KnownUBInsts.size())
3150 return ChangeStatus::CHANGED;
3151 return ChangeStatus::UNCHANGED;
3152 }
3153
3154 bool isKnownToCauseUB(Instruction *I) const override {
3155 return KnownUBInsts.count(I);
3156 }
3157
3158 bool isAssumedToCauseUB(Instruction *I) const override {
3159 // In simple words, if an instruction is not in the assumed to _not_
3160 // cause UB, then it is assumed UB (that includes those
3161 // in the KnownUBInsts set). The rest is boilerplate
3162 // is to ensure that it is one of the instructions we test
3163 // for UB.
3164
3165 switch (I->getOpcode()) {
3166 case Instruction::Load:
3167 case Instruction::Store:
3168 case Instruction::AtomicCmpXchg:
3169 case Instruction::AtomicRMW:
3170 case Instruction::CondBr:
3171 return !AssumedNoUBInsts.count(I);
3172 default:
3173 return false;
3174 }
3175 return false;
3176 }
3177
3178 ChangeStatus manifest(Attributor &A) override {
3179 if (KnownUBInsts.empty())
3180 return ChangeStatus::UNCHANGED;
3181 for (Instruction *I : KnownUBInsts)
3182 A.changeToUnreachableAfterManifest(I);
3183 return ChangeStatus::CHANGED;
3184 }
3185
3186 /// See AbstractAttribute::getAsStr()
3187 const std::string getAsStr(Attributor *A) const override {
3188 return getAssumed() ? "undefined-behavior" : "no-ub";
3189 }
3190
3191 /// Note: The correctness of this analysis depends on the fact that the
3192 /// following 2 sets will stop changing after some point.
3193 /// "Change" here means that their size changes.
3194 /// The size of each set is monotonically increasing
3195 /// (we only add items to them) and it is upper bounded by the number of
3196 /// instructions in the processed function (we can never save more
3197 /// elements in either set than this number). Hence, at some point,
3198 /// they will stop increasing.
3199 /// Consequently, at some point, both sets will have stopped
3200 /// changing, effectively making the analysis reach a fixpoint.
3201
3202 /// Note: These 2 sets are disjoint and an instruction can be considered
3203 /// one of 3 things:
3204 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3205 /// the KnownUBInsts set.
3206 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3207 /// has a reason to assume it).
3208 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3209 /// could not find a reason to assume or prove that it can cause UB,
3210 /// hence it assumes it doesn't. We have a set for these instructions
3211 /// so that we don't reprocess them in every update.
3212 /// Note however that instructions in this set may cause UB.
3213
3214protected:
3215 /// A set of all live instructions _known_ to cause UB.
3216 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3217
3218private:
3219 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3220 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3221
3222 // Should be called on updates in which if we're processing an instruction
3223 // \p I that depends on a value \p V, one of the following has to happen:
3224 // - If the value is assumed, then stop.
3225 // - If the value is known but undef, then consider it UB.
3226 // - Otherwise, do specific processing with the simplified value.
3227 // We return std::nullopt in the first 2 cases to signify that an appropriate
3228 // action was taken and the caller should stop.
3229 // Otherwise, we return the simplified value that the caller should
3230 // use for specific processing.
3231 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3232 Instruction *I) {
3233 bool UsedAssumedInformation = false;
3234 std::optional<Value *> SimplifiedV =
3235 A.getAssumedSimplified(IRPosition::value(*V), *this,
3236 UsedAssumedInformation, AA::Interprocedural);
3237 if (!UsedAssumedInformation) {
3238 // Don't depend on assumed values.
3239 if (!SimplifiedV) {
3240 // If it is known (which we tested above) but it doesn't have a value,
3241 // then we can assume `undef` and hence the instruction is UB.
3242 KnownUBInsts.insert(I);
3243 return std::nullopt;
3244 }
3245 if (!*SimplifiedV)
3246 return nullptr;
3247 V = *SimplifiedV;
3248 }
3249 if (isa<UndefValue>(V)) {
3250 KnownUBInsts.insert(I);
3251 return std::nullopt;
3252 }
3253 return V;
3254 }
3255};
3256
3257struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3258 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3259 : AAUndefinedBehaviorImpl(IRP, A) {}
3260
3261 /// See AbstractAttribute::trackStatistics()
3262 void trackStatistics() const override {
3263 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3264 "Number of instructions known to have UB");
3265 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3266 KnownUBInsts.size();
3267 }
3268};
3269} // namespace
3270
3271/// ------------------------ Will-Return Attributes ----------------------------
3272
3273namespace {
3274// Helper function that checks whether a function has any cycle which we don't
3275// know if it is bounded or not.
3276// Loops with maximum trip count are considered bounded, any other cycle not.
3277static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3278 ScalarEvolution *SE =
3279 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3280 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3281 // If either SCEV or LoopInfo is not available for the function then we assume
3282 // any cycle to be unbounded cycle.
3283 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3284 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3285 if (!SE || !LI) {
3286 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3287 if (SCCI.hasCycle())
3288 return true;
3289 return false;
3290 }
3291
3292 // If there's irreducible control, the function may contain non-loop cycles.
3294 return true;
3295
3296 // Any loop that does not have a max trip count is considered unbounded cycle.
3297 for (auto *L : LI->getLoopsInPreorder()) {
3298 if (!SE->getSmallConstantMaxTripCount(L))
3299 return true;
3300 }
3301 return false;
3302}
3303
3304struct AAWillReturnImpl : public AAWillReturn {
3305 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3306 : AAWillReturn(IRP, A) {}
3307
3308 /// See AbstractAttribute::initialize(...).
3309 void initialize(Attributor &A) override {
3310 bool IsKnown;
3312 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3313 (void)IsKnown;
3314 }
3315
3316 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3317 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3318 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3319 return false;
3320
3321 bool IsKnown;
3322 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3323 return IsKnown || !KnownOnly;
3324 return false;
3325 }
3326
3327 /// See AbstractAttribute::updateImpl(...).
3328 ChangeStatus updateImpl(Attributor &A) override {
3329 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3330 return ChangeStatus::UNCHANGED;
3331
3332 auto CheckForWillReturn = [&](Instruction &I) {
3334 bool IsKnown;
3336 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3337 if (IsKnown)
3338 return true;
3339 } else {
3340 return false;
3341 }
3342 bool IsKnownNoRecurse;
3344 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3345 };
3346
3347 bool UsedAssumedInformation = false;
3348 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3349 UsedAssumedInformation))
3350 return indicatePessimisticFixpoint();
3351
3352 return ChangeStatus::UNCHANGED;
3353 }
3354
3355 /// See AbstractAttribute::getAsStr()
3356 const std::string getAsStr(Attributor *A) const override {
3357 return getAssumed() ? "willreturn" : "may-noreturn";
3358 }
3359};
3360
3361struct AAWillReturnFunction final : AAWillReturnImpl {
3362 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3363 : AAWillReturnImpl(IRP, A) {}
3364
3365 /// See AbstractAttribute::initialize(...).
3366 void initialize(Attributor &A) override {
3367 AAWillReturnImpl::initialize(A);
3368
3369 Function *F = getAnchorScope();
3370 assert(F && "Did expect an anchor function");
3371 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3372 indicatePessimisticFixpoint();
3373 }
3374
3375 /// See AbstractAttribute::trackStatistics()
3376 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3377};
3378
3379/// WillReturn attribute deduction for a call sites.
3380struct AAWillReturnCallSite final
3381 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3382 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3383 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3384
3385 /// See AbstractAttribute::updateImpl(...).
3386 ChangeStatus updateImpl(Attributor &A) override {
3387 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3388 return ChangeStatus::UNCHANGED;
3389
3390 return AACalleeToCallSite::updateImpl(A);
3391 }
3392
3393 /// See AbstractAttribute::trackStatistics()
3394 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3395};
3396} // namespace
3397
3398/// -------------------AAIntraFnReachability Attribute--------------------------
3399
3400/// All information associated with a reachability query. This boilerplate code
3401/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3402/// different \p ToTy values.
3403template <typename ToTy> struct ReachabilityQueryInfo {
3404 enum class Reachable {
3407 };
3408
3409 /// Start here,
3410 const Instruction *From = nullptr;
3411 /// reach this place,
3412 const ToTy *To = nullptr;
3413 /// without going through any of these instructions,
3415 /// and remember if it worked:
3417
3418 /// Precomputed hash for this RQI.
3419 unsigned Hash = 0;
3420
3421 unsigned computeHashValue() const {
3422 assert(Hash == 0 && "Computed hash twice!");
3425 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3426 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3427 InstSetDMI::getHashValue(ExclusionSet));
3428 }
3429
3431 : From(From), To(To) {}
3432
3433 /// Constructor replacement to ensure unique and stable sets are used for the
3434 /// cache.
3436 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3437 : From(&From), To(&To), ExclusionSet(ES) {
3438
3439 if (!ES || ES->empty()) {
3440 ExclusionSet = nullptr;
3441 } else if (MakeUnique) {
3442 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3443 }
3444 }
3445
3448};
3449
3450namespace llvm {
3451template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3454
3457
3460 return &TombstoneKey;
3461 }
3462 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3463 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3464 }
3465 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3466 const ReachabilityQueryInfo<ToTy> *RHS) {
3467 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3468 return false;
3469 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3470 }
3471};
3472
3473#define DefineKeys(ToTy) \
3474 template <> \
3475 ReachabilityQueryInfo<ToTy> \
3476 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3477 ReachabilityQueryInfo<ToTy>( \
3478 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3479 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3480 template <> \
3481 ReachabilityQueryInfo<ToTy> \
3482 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3483 ReachabilityQueryInfo<ToTy>( \
3484 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3485 DenseMapInfo<const ToTy *>::getTombstoneKey());
3486
3488#undef DefineKeys
3489
3490} // namespace llvm
3491
3492namespace {
3493
3494template <typename BaseTy, typename ToTy>
3495struct CachedReachabilityAA : public BaseTy {
3496 using RQITy = ReachabilityQueryInfo<ToTy>;
3497
3498 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3499
3500 /// See AbstractAttribute::isQueryAA.
3501 bool isQueryAA() const override { return true; }
3502
3503 /// See AbstractAttribute::updateImpl(...).
3504 ChangeStatus updateImpl(Attributor &A) override {
3505 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3506 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3507 RQITy *RQI = QueryVector[u];
3508 if (RQI->Result == RQITy::Reachable::No &&
3509 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3510 Changed = ChangeStatus::CHANGED;
3511 }
3512 return Changed;
3513 }
3514
3515 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3516 bool IsTemporaryRQI) = 0;
3517
3518 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3519 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3520 RQI.Result = Result;
3521
3522 // Remove the temporary RQI from the cache.
3523 if (IsTemporaryRQI)
3524 QueryCache.erase(&RQI);
3525
3526 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3527 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3528 // this query. 2) We did not use the exclusion set, potentially because
3529 // there is none.
3530 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3531 RQITy PlainRQI(RQI.From, RQI.To);
3532 if (!QueryCache.count(&PlainRQI)) {
3533 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3534 RQIPtr->Result = Result;
3535 QueryVector.push_back(RQIPtr);
3536 QueryCache.insert(RQIPtr);
3537 }
3538 }
3539
3540 // Check if we need to insert a new permanent RQI with the exclusion set.
3541 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3542 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3543 "Did not expect empty set!");
3544 RQITy *RQIPtr = new (A.Allocator)
3545 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3546 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3547 RQIPtr->Result = Result;
3548 assert(!QueryCache.count(RQIPtr));
3549 QueryVector.push_back(RQIPtr);
3550 QueryCache.insert(RQIPtr);
3551 }
3552
3553 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3554 A.registerForUpdate(*this);
3555 return Result == RQITy::Reachable::Yes;
3556 }
3557
3558 const std::string getAsStr(Attributor *A) const override {
3559 // TODO: Return the number of reachable queries.
3560 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3561 }
3562
3563 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3564 typename RQITy::Reachable &Result) {
3565 if (!this->getState().isValidState()) {
3566 Result = RQITy::Reachable::Yes;
3567 return true;
3568 }
3569
3570 // If we have an exclusion set we might be able to find our answer by
3571 // ignoring it first.
3572 if (StackRQI.ExclusionSet) {
3573 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3574 auto It = QueryCache.find(&PlainRQI);
3575 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3576 Result = RQITy::Reachable::No;
3577 return true;
3578 }
3579 }
3580
3581 auto It = QueryCache.find(&StackRQI);
3582 if (It != QueryCache.end()) {
3583 Result = (*It)->Result;
3584 return true;
3585 }
3586
3587 // Insert a temporary for recursive queries. We will replace it with a
3588 // permanent entry later.
3589 QueryCache.insert(&StackRQI);
3590 return false;
3591 }
3592
3593private:
3594 SmallVector<RQITy *> QueryVector;
3595 DenseSet<RQITy *> QueryCache;
3596};
3597
3598struct AAIntraFnReachabilityFunction final
3599 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3600 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3601 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3602 : Base(IRP, A) {
3603 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3604 *IRP.getAssociatedFunction());
3605 }
3606
3607 bool isAssumedReachable(
3608 Attributor &A, const Instruction &From, const Instruction &To,
3609 const AA::InstExclusionSetTy *ExclusionSet) const override {
3610 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3611 if (&From == &To)
3612 return true;
3613
3614 RQITy StackRQI(A, From, To, ExclusionSet, false);
3615 RQITy::Reachable Result;
3616 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3617 return NonConstThis->isReachableImpl(A, StackRQI,
3618 /*IsTemporaryRQI=*/true);
3619 return Result == RQITy::Reachable::Yes;
3620 }
3621
3622 ChangeStatus updateImpl(Attributor &A) override {
3623 // We only depend on liveness. DeadEdges is all we care about, check if any
3624 // of them changed.
3625 auto *LivenessAA =
3626 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3627 if (LivenessAA &&
3628 llvm::all_of(DeadEdges,
3629 [&](const auto &DeadEdge) {
3630 return LivenessAA->isEdgeDead(DeadEdge.first,
3631 DeadEdge.second);
3632 }) &&
3633 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3634 return LivenessAA->isAssumedDead(BB);
3635 })) {
3636 return ChangeStatus::UNCHANGED;
3637 }
3638 DeadEdges.clear();
3639 DeadBlocks.clear();
3640 return Base::updateImpl(A);
3641 }
3642
3643 bool isReachableImpl(Attributor &A, RQITy &RQI,
3644 bool IsTemporaryRQI) override {
3645 const Instruction *Origin = RQI.From;
3646 bool UsedExclusionSet = false;
3647
3648 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3649 const AA::InstExclusionSetTy *ExclusionSet) {
3650 const Instruction *IP = &From;
3651 while (IP && IP != &To) {
3652 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3653 UsedExclusionSet = true;
3654 break;
3655 }
3656 IP = IP->getNextNode();
3657 }
3658 return IP == &To;
3659 };
3660
3661 const BasicBlock *FromBB = RQI.From->getParent();
3662 const BasicBlock *ToBB = RQI.To->getParent();
3663 assert(FromBB->getParent() == ToBB->getParent() &&
3664 "Not an intra-procedural query!");
3665
3666 // Check intra-block reachability, however, other reaching paths are still
3667 // possible.
3668 if (FromBB == ToBB &&
3669 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3670 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3671 IsTemporaryRQI);
3672
3673 // Check if reaching the ToBB block is sufficient or if even that would not
3674 // ensure reaching the target. In the latter case we are done.
3675 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3676 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3677 IsTemporaryRQI);
3678
3679 const Function *Fn = FromBB->getParent();
3680 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3681 if (RQI.ExclusionSet)
3682 for (auto *I : *RQI.ExclusionSet)
3683 if (I->getFunction() == Fn)
3684 ExclusionBlocks.insert(I->getParent());
3685
3686 // Check if we make it out of the FromBB block at all.
3687 if (ExclusionBlocks.count(FromBB) &&
3688 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3689 RQI.ExclusionSet))
3690 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3691
3692 auto *LivenessAA =
3693 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3694 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3695 DeadBlocks.insert(ToBB);
3696 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3697 IsTemporaryRQI);
3698 }
3699
3700 SmallPtrSet<const BasicBlock *, 16> Visited;
3702 Worklist.push_back(FromBB);
3703
3704 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3705 while (!Worklist.empty()) {
3706 const BasicBlock *BB = Worklist.pop_back_val();
3707 if (!Visited.insert(BB).second)
3708 continue;
3709 for (const BasicBlock *SuccBB : successors(BB)) {
3710 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3711 LocalDeadEdges.insert({BB, SuccBB});
3712 continue;
3713 }
3714 // We checked before if we just need to reach the ToBB block.
3715 if (SuccBB == ToBB)
3716 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3717 IsTemporaryRQI);
3718 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3719 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3720 IsTemporaryRQI);
3721
3722 if (ExclusionBlocks.count(SuccBB)) {
3723 UsedExclusionSet = true;
3724 continue;
3725 }
3726 Worklist.push_back(SuccBB);
3727 }
3728 }
3729
3730 DeadEdges.insert_range(LocalDeadEdges);
3731 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3732 IsTemporaryRQI);
3733 }
3734
3735 /// See AbstractAttribute::trackStatistics()
3736 void trackStatistics() const override {}
3737
3738private:
3739 // Set of assumed dead blocks we used in the last query. If any changes we
3740 // update the state.
3741 DenseSet<const BasicBlock *> DeadBlocks;
3742
3743 // Set of assumed dead edges we used in the last query. If any changes we
3744 // update the state.
3745 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3746
3747 /// The dominator tree of the function to short-circuit reasoning.
3748 const DominatorTree *DT = nullptr;
3749};
3750} // namespace
3751
3752/// ------------------------ NoAlias Argument Attribute ------------------------
3753
3755 Attribute::AttrKind ImpliedAttributeKind,
3756 bool IgnoreSubsumingPositions) {
3757 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3758 "Unexpected attribute kind");
3759 Value *Val = &IRP.getAssociatedValue();
3761 if (isa<AllocaInst>(Val))
3762 return true;
3763 } else {
3764 IgnoreSubsumingPositions = true;
3765 }
3766
3767 if (isa<UndefValue>(Val))
3768 return true;
3769
3770 if (isa<ConstantPointerNull>(Val) &&
3773 return true;
3774
3775 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3776 IgnoreSubsumingPositions, Attribute::NoAlias))
3777 return true;
3778
3779 return false;
3780}
3781
3782namespace {
3783struct AANoAliasImpl : AANoAlias {
3784 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3785 assert(getAssociatedType()->isPointerTy() &&
3786 "Noalias is a pointer attribute");
3787 }
3788
3789 const std::string getAsStr(Attributor *A) const override {
3790 return getAssumed() ? "noalias" : "may-alias";
3791 }
3792};
3793
3794/// NoAlias attribute for a floating value.
3795struct AANoAliasFloating final : AANoAliasImpl {
3796 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3797 : AANoAliasImpl(IRP, A) {}
3798
3799 /// See AbstractAttribute::updateImpl(...).
3800 ChangeStatus updateImpl(Attributor &A) override {
3801 // TODO: Implement this.
3802 return indicatePessimisticFixpoint();
3803 }
3804
3805 /// See AbstractAttribute::trackStatistics()
3806 void trackStatistics() const override {
3808 }
3809};
3810
3811/// NoAlias attribute for an argument.
3812struct AANoAliasArgument final
3813 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3814 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3815 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3816
3817 /// See AbstractAttribute::update(...).
3818 ChangeStatus updateImpl(Attributor &A) override {
3819 // We have to make sure no-alias on the argument does not break
3820 // synchronization when this is a callback argument, see also [1] below.
3821 // If synchronization cannot be affected, we delegate to the base updateImpl
3822 // function, otherwise we give up for now.
3823
3824 // If the function is no-sync, no-alias cannot break synchronization.
3825 bool IsKnownNoSycn;
3827 A, this, IRPosition::function_scope(getIRPosition()),
3828 DepClassTy::OPTIONAL, IsKnownNoSycn))
3829 return Base::updateImpl(A);
3830
3831 // If the argument is read-only, no-alias cannot break synchronization.
3832 bool IsKnown;
3833 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3834 return Base::updateImpl(A);
3835
3836 // If the argument is never passed through callbacks, no-alias cannot break
3837 // synchronization.
3838 bool UsedAssumedInformation = false;
3839 if (A.checkForAllCallSites(
3840 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3841 true, UsedAssumedInformation))
3842 return Base::updateImpl(A);
3843
3844 // TODO: add no-alias but make sure it doesn't break synchronization by
3845 // introducing fake uses. See:
3846 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3847 // International Workshop on OpenMP 2018,
3848 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3849
3850 return indicatePessimisticFixpoint();
3851 }
3852
3853 /// See AbstractAttribute::trackStatistics()
3854 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3855};
3856
3857struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3858 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3859 : AANoAliasImpl(IRP, A) {}
3860
3861 /// Determine if the underlying value may alias with the call site argument
3862 /// \p OtherArgNo of \p ICS (= the underlying call site).
3863 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3864 const AAMemoryBehavior &MemBehaviorAA,
3865 const CallBase &CB, unsigned OtherArgNo) {
3866 // We do not need to worry about aliasing with the underlying IRP.
3867 if (this->getCalleeArgNo() == (int)OtherArgNo)
3868 return false;
3869
3870 // If it is not a pointer or pointer vector we do not alias.
3871 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3872 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3873 return false;
3874
3875 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3876 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3877
3878 // If the argument is readnone, there is no read-write aliasing.
3879 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3880 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3881 return false;
3882 }
3883
3884 // If the argument is readonly and the underlying value is readonly, there
3885 // is no read-write aliasing.
3886 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3887 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3888 IsReadOnly) {
3889 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3890 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3891 return false;
3892 }
3893
3894 // We have to utilize actual alias analysis queries so we need the object.
3895 if (!AAR)
3896 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3897 *getAnchorScope());
3898
3899 // Try to rule it out at the call site.
3900 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3901 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3902 "callsite arguments: "
3903 << getAssociatedValue() << " " << *ArgOp << " => "
3904 << (IsAliasing ? "" : "no-") << "alias \n");
3905
3906 return IsAliasing;
3907 }
3908
3909 bool isKnownNoAliasDueToNoAliasPreservation(
3910 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3911 // We can deduce "noalias" if the following conditions hold.
3912 // (i) Associated value is assumed to be noalias in the definition.
3913 // (ii) Associated value is assumed to be no-capture in all the uses
3914 // possibly executed before this callsite.
3915 // (iii) There is no other pointer argument which could alias with the
3916 // value.
3917
3918 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3919 const Function *ScopeFn = VIRP.getAnchorScope();
3920 // Check whether the value is captured in the scope using AANoCapture.
3921 // Look at CFG and check only uses possibly executed before this
3922 // callsite.
3923 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3924 Instruction *UserI = cast<Instruction>(U.getUser());
3925
3926 // If UserI is the curr instruction and there is a single potential use of
3927 // the value in UserI we allow the use.
3928 // TODO: We should inspect the operands and allow those that cannot alias
3929 // with the value.
3930 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3931 return true;
3932
3933 if (ScopeFn) {
3934 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3935 if (CB->isArgOperand(&U)) {
3936
3937 unsigned ArgNo = CB->getArgOperandNo(&U);
3938
3939 bool IsKnownNoCapture;
3941 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3942 DepClassTy::OPTIONAL, IsKnownNoCapture))
3943 return true;
3944 }
3945 }
3946
3948 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3949 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3950 return true;
3951 }
3952
3953 // TODO: We should track the capturing uses in AANoCapture but the problem
3954 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3955 // a value in the module slice.
3956 // TODO(captures): Make this more precise.
3957 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3958 if (capturesNothing(CI))
3959 return true;
3960 if (CI.isPassthrough()) {
3961 Follow = true;
3962 return true;
3963 }
3964 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3965 return false;
3966 };
3967
3968 bool IsKnownNoCapture;
3969 const AANoCapture *NoCaptureAA = nullptr;
3970 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3971 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3972 if (!IsAssumedNoCapture &&
3973 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3974 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3975 LLVM_DEBUG(
3976 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3977 << " cannot be noalias as it is potentially captured\n");
3978 return false;
3979 }
3980 }
3981 if (NoCaptureAA)
3982 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3983
3984 // Check there is no other pointer argument which could alias with the
3985 // value passed at this call site.
3986 // TODO: AbstractCallSite
3987 const auto &CB = cast<CallBase>(getAnchorValue());
3988 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3989 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3990 return false;
3991
3992 return true;
3993 }
3994
3995 /// See AbstractAttribute::updateImpl(...).
3996 ChangeStatus updateImpl(Attributor &A) override {
3997 // If the argument is readnone we are done as there are no accesses via the
3998 // argument.
3999 auto *MemBehaviorAA =
4000 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4001 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4002 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4003 return ChangeStatus::UNCHANGED;
4004 }
4005
4006 bool IsKnownNoAlias;
4007 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4009 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4010 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4011 << " is not no-alias at the definition\n");
4012 return indicatePessimisticFixpoint();
4013 }
4014
4015 AAResults *AAR = nullptr;
4016 if (MemBehaviorAA &&
4017 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4018 LLVM_DEBUG(
4019 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4020 return ChangeStatus::UNCHANGED;
4021 }
4022
4023 return indicatePessimisticFixpoint();
4024 }
4025
4026 /// See AbstractAttribute::trackStatistics()
4027 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4028};
4029
4030/// NoAlias attribute for function return value.
4031struct AANoAliasReturned final : AANoAliasImpl {
4032 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4033 : AANoAliasImpl(IRP, A) {}
4034
4035 /// See AbstractAttribute::updateImpl(...).
4036 ChangeStatus updateImpl(Attributor &A) override {
4037
4038 auto CheckReturnValue = [&](Value &RV) -> bool {
4039 if (Constant *C = dyn_cast<Constant>(&RV))
4040 if (C->isNullValue() || isa<UndefValue>(C))
4041 return true;
4042
4043 /// For now, we can only deduce noalias if we have call sites.
4044 /// FIXME: add more support.
4045 if (!isa<CallBase>(&RV))
4046 return false;
4047
4048 const IRPosition &RVPos = IRPosition::value(RV);
4049 bool IsKnownNoAlias;
4051 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4052 return false;
4053
4054 bool IsKnownNoCapture;
4055 const AANoCapture *NoCaptureAA = nullptr;
4056 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4057 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4058 &NoCaptureAA);
4059 return IsAssumedNoCapture ||
4060 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4061 };
4062
4063 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4064 return indicatePessimisticFixpoint();
4065
4066 return ChangeStatus::UNCHANGED;
4067 }
4068
4069 /// See AbstractAttribute::trackStatistics()
4070 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4071};
4072
4073/// NoAlias attribute deduction for a call site return value.
4074struct AANoAliasCallSiteReturned final
4075 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4076 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4077 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4078
4079 /// See AbstractAttribute::trackStatistics()
4080 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4081};
4082} // namespace
4083
4084/// -------------------AAIsDead Function Attribute-----------------------
4085
4086namespace {
4087struct AAIsDeadValueImpl : public AAIsDead {
4088 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4089
4090 /// See AAIsDead::isAssumedDead().
4091 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4092
4093 /// See AAIsDead::isKnownDead().
4094 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4095
4096 /// See AAIsDead::isAssumedDead(BasicBlock *).
4097 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4098
4099 /// See AAIsDead::isKnownDead(BasicBlock *).
4100 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4101
4102 /// See AAIsDead::isAssumedDead(Instruction *I).
4103 bool isAssumedDead(const Instruction *I) const override {
4104 return I == getCtxI() && isAssumedDead();
4105 }
4106
4107 /// See AAIsDead::isKnownDead(Instruction *I).
4108 bool isKnownDead(const Instruction *I) const override {
4109 return isAssumedDead(I) && isKnownDead();
4110 }
4111
4112 /// See AbstractAttribute::getAsStr().
4113 const std::string getAsStr(Attributor *A) const override {
4114 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4115 }
4116
4117 /// Check if all uses are assumed dead.
4118 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4119 // Callers might not check the type, void has no uses.
4120 if (V.getType()->isVoidTy() || V.use_empty())
4121 return true;
4122
4123 // If we replace a value with a constant there are no uses left afterwards.
4124 if (!isa<Constant>(V)) {
4125 if (auto *I = dyn_cast<Instruction>(&V))
4126 if (!A.isRunOn(*I->getFunction()))
4127 return false;
4128 bool UsedAssumedInformation = false;
4129 std::optional<Constant *> C =
4130 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4131 if (!C || *C)
4132 return true;
4133 }
4134
4135 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4136 // Explicitly set the dependence class to required because we want a long
4137 // chain of N dependent instructions to be considered live as soon as one is
4138 // without going through N update cycles. This is not required for
4139 // correctness.
4140 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4141 DepClassTy::REQUIRED,
4142 /* IgnoreDroppableUses */ false);
4143 }
4144
4145 /// Determine if \p I is assumed to be side-effect free.
4146 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4148 return true;
4149
4150 auto *CB = dyn_cast<CallBase>(I);
4151 if (!CB || isa<IntrinsicInst>(CB))
4152 return false;
4153
4154 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4155
4156 bool IsKnownNoUnwind;
4158 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4159 return false;
4160
4161 bool IsKnown;
4162 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4163 }
4164};
4165
4166struct AAIsDeadFloating : public AAIsDeadValueImpl {
4167 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4168 : AAIsDeadValueImpl(IRP, A) {}
4169
4170 /// See AbstractAttribute::initialize(...).
4171 void initialize(Attributor &A) override {
4172 AAIsDeadValueImpl::initialize(A);
4173
4174 if (isa<UndefValue>(getAssociatedValue())) {
4175 indicatePessimisticFixpoint();
4176 return;
4177 }
4178
4179 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4180 if (!isAssumedSideEffectFree(A, I)) {
4182 indicatePessimisticFixpoint();
4183 else
4184 removeAssumedBits(HAS_NO_EFFECT);
4185 }
4186 }
4187
4188 bool isDeadFence(Attributor &A, FenceInst &FI) {
4189 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4190 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4191 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4192 return false;
4193 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4194 return true;
4195 }
4196
4197 bool isDeadStore(Attributor &A, StoreInst &SI,
4198 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4199 // Lang ref now states volatile store is not UB/dead, let's skip them.
4200 if (SI.isVolatile())
4201 return false;
4202
4203 // If we are collecting assumes to be deleted we are in the manifest stage.
4204 // It's problematic to collect the potential copies again now so we use the
4205 // cached ones.
4206 bool UsedAssumedInformation = false;
4207 if (!AssumeOnlyInst) {
4208 PotentialCopies.clear();
4209 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4210 UsedAssumedInformation)) {
4211 LLVM_DEBUG(
4212 dbgs()
4213 << "[AAIsDead] Could not determine potential copies of store!\n");
4214 return false;
4215 }
4216 }
4217 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4218 << " potential copies.\n");
4219
4220 InformationCache &InfoCache = A.getInfoCache();
4221 return llvm::all_of(PotentialCopies, [&](Value *V) {
4222 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4223 UsedAssumedInformation))
4224 return true;
4225 if (auto *LI = dyn_cast<LoadInst>(V)) {
4226 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4227 auto &UserI = cast<Instruction>(*U.getUser());
4228 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4229 if (AssumeOnlyInst)
4230 AssumeOnlyInst->insert(&UserI);
4231 return true;
4232 }
4233 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4234 })) {
4235 return true;
4236 }
4237 }
4238 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4239 << " is assumed live!\n");
4240 return false;
4241 });
4242 }
4243
4244 /// See AbstractAttribute::getAsStr().
4245 const std::string getAsStr(Attributor *A) const override {
4246 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4248 if (isValidState())
4249 return "assumed-dead-store";
4251 if (isValidState())
4252 return "assumed-dead-fence";
4253 return AAIsDeadValueImpl::getAsStr(A);
4254 }
4255
4256 /// See AbstractAttribute::updateImpl(...).
4257 ChangeStatus updateImpl(Attributor &A) override {
4258 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4259 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4260 if (!isDeadStore(A, *SI))
4261 return indicatePessimisticFixpoint();
4262 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4263 if (!isDeadFence(A, *FI))
4264 return indicatePessimisticFixpoint();
4265 } else {
4266 if (!isAssumedSideEffectFree(A, I))
4267 return indicatePessimisticFixpoint();
4268 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4269 return indicatePessimisticFixpoint();
4270 }
4272 }
4273
4274 bool isRemovableStore() const override {
4275 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4276 }
4277
4278 /// See AbstractAttribute::manifest(...).
4279 ChangeStatus manifest(Attributor &A) override {
4280 Value &V = getAssociatedValue();
4281 if (auto *I = dyn_cast<Instruction>(&V)) {
4282 // If we get here we basically know the users are all dead. We check if
4283 // isAssumedSideEffectFree returns true here again because it might not be
4284 // the case and only the users are dead but the instruction (=call) is
4285 // still needed.
4286 if (auto *SI = dyn_cast<StoreInst>(I)) {
4287 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4288 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4289 (void)IsDead;
4290 assert(IsDead && "Store was assumed to be dead!");
4291 A.deleteAfterManifest(*I);
4292 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4293 Instruction *AOI = AssumeOnlyInst[i];
4294 for (auto *Usr : AOI->users())
4295 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4296 A.deleteAfterManifest(*AOI);
4297 }
4298 return ChangeStatus::CHANGED;
4299 }
4300 if (auto *FI = dyn_cast<FenceInst>(I)) {
4301 assert(isDeadFence(A, *FI));
4302 A.deleteAfterManifest(*FI);
4303 return ChangeStatus::CHANGED;
4304 }
4305 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4306 A.deleteAfterManifest(*I);
4307 return ChangeStatus::CHANGED;
4308 }
4309 }
4311 }
4312
4313 /// See AbstractAttribute::trackStatistics()
4314 void trackStatistics() const override {
4316 }
4317
4318private:
4319 // The potential copies of a dead store, used for deletion during manifest.
4320 SmallSetVector<Value *, 4> PotentialCopies;
4321};
4322
4323struct AAIsDeadArgument : public AAIsDeadFloating {
4324 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4325 : AAIsDeadFloating(IRP, A) {}
4326
4327 /// See AbstractAttribute::manifest(...).
4328 ChangeStatus manifest(Attributor &A) override {
4329 Argument &Arg = *getAssociatedArgument();
4330 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4331 if (A.registerFunctionSignatureRewrite(
4332 Arg, /* ReplacementTypes */ {},
4335 return ChangeStatus::CHANGED;
4336 }
4337 return ChangeStatus::UNCHANGED;
4338 }
4339
4340 /// See AbstractAttribute::trackStatistics()
4341 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4342};
4343
4344struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4345 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4346 : AAIsDeadValueImpl(IRP, A) {}
4347
4348 /// See AbstractAttribute::initialize(...).
4349 void initialize(Attributor &A) override {
4350 AAIsDeadValueImpl::initialize(A);
4351 if (isa<UndefValue>(getAssociatedValue()))
4352 indicatePessimisticFixpoint();
4353 }
4354
4355 /// See AbstractAttribute::updateImpl(...).
4356 ChangeStatus updateImpl(Attributor &A) override {
4357 // TODO: Once we have call site specific value information we can provide
4358 // call site specific liveness information and then it makes
4359 // sense to specialize attributes for call sites arguments instead of
4360 // redirecting requests to the callee argument.
4361 Argument *Arg = getAssociatedArgument();
4362 if (!Arg)
4363 return indicatePessimisticFixpoint();
4364 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4365 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4366 if (!ArgAA)
4367 return indicatePessimisticFixpoint();
4368 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4369 }
4370
4371 /// See AbstractAttribute::manifest(...).
4372 ChangeStatus manifest(Attributor &A) override {
4373 CallBase &CB = cast<CallBase>(getAnchorValue());
4374 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4375 assert(!isa<UndefValue>(U.get()) &&
4376 "Expected undef values to be filtered out!");
4377 UndefValue &UV = *UndefValue::get(U->getType());
4378 if (A.changeUseAfterManifest(U, UV))
4379 return ChangeStatus::CHANGED;
4380 return ChangeStatus::UNCHANGED;
4381 }
4382
4383 /// See AbstractAttribute::trackStatistics()
4384 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4385};
4386
4387struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4388 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4389 : AAIsDeadFloating(IRP, A) {}
4390
4391 /// See AAIsDead::isAssumedDead().
4392 bool isAssumedDead() const override {
4393 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4394 }
4395
4396 /// See AbstractAttribute::initialize(...).
4397 void initialize(Attributor &A) override {
4398 AAIsDeadFloating::initialize(A);
4399 if (isa<UndefValue>(getAssociatedValue())) {
4400 indicatePessimisticFixpoint();
4401 return;
4402 }
4403
4404 // We track this separately as a secondary state.
4405 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4406 }
4407
4408 /// See AbstractAttribute::updateImpl(...).
4409 ChangeStatus updateImpl(Attributor &A) override {
4410 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4411 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4412 IsAssumedSideEffectFree = false;
4413 Changed = ChangeStatus::CHANGED;
4414 }
4415 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4416 return indicatePessimisticFixpoint();
4417 return Changed;
4418 }
4419
4420 /// See AbstractAttribute::trackStatistics()
4421 void trackStatistics() const override {
4422 if (IsAssumedSideEffectFree)
4424 else
4425 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4426 }
4427
4428 /// See AbstractAttribute::getAsStr().
4429 const std::string getAsStr(Attributor *A) const override {
4430 return isAssumedDead()
4431 ? "assumed-dead"
4432 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4433 }
4434
4435private:
4436 bool IsAssumedSideEffectFree = true;
4437};
4438
4439struct AAIsDeadReturned : public AAIsDeadValueImpl {
4440 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4441 : AAIsDeadValueImpl(IRP, A) {}
4442
4443 /// See AbstractAttribute::updateImpl(...).
4444 ChangeStatus updateImpl(Attributor &A) override {
4445
4446 bool UsedAssumedInformation = false;
4447 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4448 {Instruction::Ret}, UsedAssumedInformation);
4449
4450 auto PredForCallSite = [&](AbstractCallSite ACS) {
4451 if (ACS.isCallbackCall() || !ACS.getInstruction())
4452 return false;
4453 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4454 };
4455
4456 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4457 UsedAssumedInformation))
4458 return indicatePessimisticFixpoint();
4459
4460 return ChangeStatus::UNCHANGED;
4461 }
4462
4463 /// See AbstractAttribute::manifest(...).
4464 ChangeStatus manifest(Attributor &A) override {
4465 // TODO: Rewrite the signature to return void?
4466 bool AnyChange = false;
4467 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4468 auto RetInstPred = [&](Instruction &I) {
4469 ReturnInst &RI = cast<ReturnInst>(I);
4471 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4472 return true;
4473 };
4474 bool UsedAssumedInformation = false;
4475 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4476 UsedAssumedInformation);
4477 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4478 }
4479
4480 /// See AbstractAttribute::trackStatistics()
4481 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4482};
4483
4484struct AAIsDeadFunction : public AAIsDead {
4485 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4486
4487 /// See AbstractAttribute::initialize(...).
4488 void initialize(Attributor &A) override {
4489 Function *F = getAnchorScope();
4490 assert(F && "Did expect an anchor function");
4491 if (!isAssumedDeadInternalFunction(A)) {
4492 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4493 assumeLive(A, F->getEntryBlock());
4494 }
4495 }
4496
4497 bool isAssumedDeadInternalFunction(Attributor &A) {
4498 if (!getAnchorScope()->hasLocalLinkage())
4499 return false;
4500 bool UsedAssumedInformation = false;
4501 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4502 true, UsedAssumedInformation);
4503 }
4504
4505 /// See AbstractAttribute::getAsStr().
4506 const std::string getAsStr(Attributor *A) const override {
4507 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4508 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4509 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4510 std::to_string(KnownDeadEnds.size()) + "]";
4511 }
4512
4513 /// See AbstractAttribute::manifest(...).
4514 ChangeStatus manifest(Attributor &A) override {
4515 assert(getState().isValidState() &&
4516 "Attempted to manifest an invalid state!");
4517
4518 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4519 Function &F = *getAnchorScope();
4520
4521 if (AssumedLiveBlocks.empty()) {
4522 A.deleteAfterManifest(F);
4523 return ChangeStatus::CHANGED;
4524 }
4525
4526 // Flag to determine if we can change an invoke to a call assuming the
4527 // callee is nounwind. This is not possible if the personality of the
4528 // function allows to catch asynchronous exceptions.
4529 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4530
4531 KnownDeadEnds.set_union(ToBeExploredFrom);
4532 for (const Instruction *DeadEndI : KnownDeadEnds) {
4533 auto *CB = dyn_cast<CallBase>(DeadEndI);
4534 if (!CB)
4535 continue;
4536 bool IsKnownNoReturn;
4538 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4539 IsKnownNoReturn);
4540 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4541 continue;
4542
4543 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4544 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4545 else
4546 A.changeToUnreachableAfterManifest(
4547 const_cast<Instruction *>(DeadEndI->getNextNode()));
4548 HasChanged = ChangeStatus::CHANGED;
4549 }
4550
4551 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4552 for (BasicBlock &BB : F)
4553 if (!AssumedLiveBlocks.count(&BB)) {
4554 A.deleteAfterManifest(BB);
4555 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4556 HasChanged = ChangeStatus::CHANGED;
4557 }
4558
4559 return HasChanged;
4560 }
4561
4562 /// See AbstractAttribute::updateImpl(...).
4563 ChangeStatus updateImpl(Attributor &A) override;
4564
4565 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4566 assert(From->getParent() == getAnchorScope() &&
4567 To->getParent() == getAnchorScope() &&
4568 "Used AAIsDead of the wrong function");
4569 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4570 }
4571
4572 /// See AbstractAttribute::trackStatistics()
4573 void trackStatistics() const override {}
4574
4575 /// Returns true if the function is assumed dead.
4576 bool isAssumedDead() const override { return false; }
4577
4578 /// See AAIsDead::isKnownDead().
4579 bool isKnownDead() const override { return false; }
4580
4581 /// See AAIsDead::isAssumedDead(BasicBlock *).
4582 bool isAssumedDead(const BasicBlock *BB) const override {
4583 assert(BB->getParent() == getAnchorScope() &&
4584 "BB must be in the same anchor scope function.");
4585
4586 if (!getAssumed())
4587 return false;
4588 return !AssumedLiveBlocks.count(BB);
4589 }
4590
4591 /// See AAIsDead::isKnownDead(BasicBlock *).
4592 bool isKnownDead(const BasicBlock *BB) const override {
4593 return getKnown() && isAssumedDead(BB);
4594 }
4595
4596 /// See AAIsDead::isAssumed(Instruction *I).
4597 bool isAssumedDead(const Instruction *I) const override {
4598 assert(I->getParent()->getParent() == getAnchorScope() &&
4599 "Instruction must be in the same anchor scope function.");
4600
4601 if (!getAssumed())
4602 return false;
4603
4604 // If it is not in AssumedLiveBlocks then it for sure dead.
4605 // Otherwise, it can still be after noreturn call in a live block.
4606 if (!AssumedLiveBlocks.count(I->getParent()))
4607 return true;
4608
4609 // If it is not after a liveness barrier it is live.
4610 const Instruction *PrevI = I->getPrevNode();
4611 while (PrevI) {
4612 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4613 return true;
4614 PrevI = PrevI->getPrevNode();
4615 }
4616 return false;
4617 }
4618
4619 /// See AAIsDead::isKnownDead(Instruction *I).
4620 bool isKnownDead(const Instruction *I) const override {
4621 return getKnown() && isAssumedDead(I);
4622 }
4623
4624 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4625 /// that internal function called from \p BB should now be looked at.
4626 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4627 if (!AssumedLiveBlocks.insert(&BB).second)
4628 return false;
4629
4630 // We assume that all of BB is (probably) live now and if there are calls to
4631 // internal functions we will assume that those are now live as well. This
4632 // is a performance optimization for blocks with calls to a lot of internal
4633 // functions. It can however cause dead functions to be treated as live.
4634 for (const Instruction &I : BB)
4635 if (const auto *CB = dyn_cast<CallBase>(&I))
4637 if (F->hasLocalLinkage())
4638 A.markLiveInternalFunction(*F);
4639 return true;
4640 }
4641
4642 /// Collection of instructions that need to be explored again, e.g., we
4643 /// did assume they do not transfer control to (one of their) successors.
4644 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4645
4646 /// Collection of instructions that are known to not transfer control.
4647 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4648
4649 /// Collection of all assumed live edges
4650 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4651
4652 /// Collection of all assumed live BasicBlocks.
4653 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4654};
4655
4656static bool
4657identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4658 AbstractAttribute &AA,
4659 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4660 const IRPosition &IPos = IRPosition::callsite_function(CB);
4661
4662 bool IsKnownNoReturn;
4664 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4665 return !IsKnownNoReturn;
4666 if (CB.isTerminator())
4667 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4668 else
4669 AliveSuccessors.push_back(CB.getNextNode());
4670 return false;
4671}
4672
4673static bool
4674identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4675 AbstractAttribute &AA,
4676 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4677 bool UsedAssumedInformation =
4678 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4679
4680 // First, determine if we can change an invoke to a call assuming the
4681 // callee is nounwind. This is not possible if the personality of the
4682 // function allows to catch asynchronous exceptions.
4683 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4684 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4685 } else {
4686 const IRPosition &IPos = IRPosition::callsite_function(II);
4687
4688 bool IsKnownNoUnwind;
4690 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4691 UsedAssumedInformation |= !IsKnownNoUnwind;
4692 } else {
4693 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4694 }
4695 }
4696 return UsedAssumedInformation;
4697}
4698
4699static bool
4700identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4701 AbstractAttribute &,
4702 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4703 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4704 return false;
4705}
4706
4707static bool
4708identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4709 AbstractAttribute &AA,
4710 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4711 bool UsedAssumedInformation = false;
4712 std::optional<Constant *> C =
4713 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4714 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4715 // No value yet, assume both edges are dead.
4716 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4717 const BasicBlock *SuccBB =
4718 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4719 AliveSuccessors.push_back(&SuccBB->front());
4720 } else {
4721 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4722 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4723 UsedAssumedInformation = false;
4724 }
4725 return UsedAssumedInformation;
4726}
4727
4728static bool
4729identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4730 AbstractAttribute &AA,
4731 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4732 bool UsedAssumedInformation = false;
4734 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4735 Values, AA::AnyScope,
4736 UsedAssumedInformation)) {
4737 // Something went wrong, assume all successors are live.
4738 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4739 AliveSuccessors.push_back(&SuccBB->front());
4740 return false;
4741 }
4742
4743 if (Values.empty() ||
4744 (Values.size() == 1 &&
4745 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4746 // No valid value yet, assume all edges are dead.
4747 return UsedAssumedInformation;
4748 }
4749
4750 Type &Ty = *SI.getCondition()->getType();
4751 SmallPtrSet<ConstantInt *, 8> Constants;
4752 auto CheckForConstantInt = [&](Value *V) {
4753 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4754 Constants.insert(CI);
4755 return true;
4756 }
4757 return false;
4758 };
4759
4760 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4761 return CheckForConstantInt(VAC.getValue());
4762 })) {
4763 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4764 AliveSuccessors.push_back(&SuccBB->front());
4765 return UsedAssumedInformation;
4766 }
4767
4768 unsigned MatchedCases = 0;
4769 for (const auto &CaseIt : SI.cases()) {
4770 if (Constants.count(CaseIt.getCaseValue())) {
4771 ++MatchedCases;
4772 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4773 }
4774 }
4775
4776 // If all potential values have been matched, we will not visit the default
4777 // case.
4778 if (MatchedCases < Constants.size())
4779 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4780 return UsedAssumedInformation;
4781}
4782
4783ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4785
4786 if (AssumedLiveBlocks.empty()) {
4787 if (isAssumedDeadInternalFunction(A))
4789
4790 Function *F = getAnchorScope();
4791 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4792 assumeLive(A, F->getEntryBlock());
4793 Change = ChangeStatus::CHANGED;
4794 }
4795
4796 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4797 << getAnchorScope()->size() << "] BBs and "
4798 << ToBeExploredFrom.size() << " exploration points and "
4799 << KnownDeadEnds.size() << " known dead ends\n");
4800
4801 // Copy and clear the list of instructions we need to explore from. It is
4802 // refilled with instructions the next update has to look at.
4803 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4804 ToBeExploredFrom.end());
4805 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4806
4808 while (!Worklist.empty()) {
4809 const Instruction *I = Worklist.pop_back_val();
4810 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4811
4812 // Fast forward for uninteresting instructions. We could look for UB here
4813 // though.
4814 while (!I->isTerminator() && !isa<CallBase>(I))
4815 I = I->getNextNode();
4816
4817 AliveSuccessors.clear();
4818
4819 bool UsedAssumedInformation = false;
4820 switch (I->getOpcode()) {
4821 // TODO: look for (assumed) UB to backwards propagate "deadness".
4822 default:
4823 assert(I->isTerminator() &&
4824 "Expected non-terminators to be handled already!");
4825 for (const BasicBlock *SuccBB : successors(I->getParent()))
4826 AliveSuccessors.push_back(&SuccBB->front());
4827 break;
4828 case Instruction::Call:
4829 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4830 *this, AliveSuccessors);
4831 break;
4832 case Instruction::Invoke:
4833 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4834 *this, AliveSuccessors);
4835 break;
4836 case Instruction::UncondBr:
4837 UsedAssumedInformation = identifyAliveSuccessors(
4838 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4839 break;
4840 case Instruction::CondBr:
4841 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4842 *this, AliveSuccessors);
4843 break;
4844 case Instruction::Switch:
4845 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4846 *this, AliveSuccessors);
4847 break;
4848 }
4849
4850 if (UsedAssumedInformation) {
4851 NewToBeExploredFrom.insert(I);
4852 } else if (AliveSuccessors.empty() ||
4853 (I->isTerminator() &&
4854 AliveSuccessors.size() < I->getNumSuccessors())) {
4855 if (KnownDeadEnds.insert(I))
4856 Change = ChangeStatus::CHANGED;
4857 }
4858
4859 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4860 << AliveSuccessors.size() << " UsedAssumedInformation: "
4861 << UsedAssumedInformation << "\n");
4862
4863 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4864 if (!I->isTerminator()) {
4865 assert(AliveSuccessors.size() == 1 &&
4866 "Non-terminator expected to have a single successor!");
4867 Worklist.push_back(AliveSuccessor);
4868 } else {
4869 // record the assumed live edge
4870 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4871 if (AssumedLiveEdges.insert(Edge).second)
4872 Change = ChangeStatus::CHANGED;
4873 if (assumeLive(A, *AliveSuccessor->getParent()))
4874 Worklist.push_back(AliveSuccessor);
4875 }
4876 }
4877 }
4878
4879 // Check if the content of ToBeExploredFrom changed, ignore the order.
4880 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4881 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4882 return !ToBeExploredFrom.count(I);
4883 })) {
4884 Change = ChangeStatus::CHANGED;
4885 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4886 }
4887
4888 // If we know everything is live there is no need to query for liveness.
4889 // Instead, indicating a pessimistic fixpoint will cause the state to be
4890 // "invalid" and all queries to be answered conservatively without lookups.
4891 // To be in this state we have to (1) finished the exploration and (3) not
4892 // discovered any non-trivial dead end and (2) not ruled unreachable code
4893 // dead.
4894 if (ToBeExploredFrom.empty() &&
4895 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4896 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4897 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4898 }))
4899 return indicatePessimisticFixpoint();
4900 return Change;
4901}
4902
4903/// Liveness information for a call sites.
4904struct AAIsDeadCallSite final : AAIsDeadFunction {
4905 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4906 : AAIsDeadFunction(IRP, A) {}
4907
4908 /// See AbstractAttribute::initialize(...).
4909 void initialize(Attributor &A) override {
4910 // TODO: Once we have call site specific value information we can provide
4911 // call site specific liveness information and then it makes
4912 // sense to specialize attributes for call sites instead of
4913 // redirecting requests to the callee.
4914 llvm_unreachable("Abstract attributes for liveness are not "
4915 "supported for call sites yet!");
4916 }
4917
4918 /// See AbstractAttribute::updateImpl(...).
4919 ChangeStatus updateImpl(Attributor &A) override {
4920 return indicatePessimisticFixpoint();
4921 }
4922
4923 /// See AbstractAttribute::trackStatistics()
4924 void trackStatistics() const override {}
4925};
4926} // namespace
4927
4928/// -------------------- Dereferenceable Argument Attribute --------------------
4929
4930namespace {
4931struct AADereferenceableImpl : AADereferenceable {
4932 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4933 : AADereferenceable(IRP, A) {}
4934 using StateType = DerefState;
4935
4936 /// See AbstractAttribute::initialize(...).
4937 void initialize(Attributor &A) override {
4938 Value &V = *getAssociatedValue().stripPointerCasts();
4940 A.getAttrs(getIRPosition(),
4941 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4942 Attrs, /* IgnoreSubsumingPositions */ false);
4943 for (const Attribute &Attr : Attrs)
4944 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4945
4946 // Ensure we initialize the non-null AA (if necessary).
4947 bool IsKnownNonNull;
4949 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4950
4951 bool CanBeNull, CanBeFreed;
4952 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4953 A.getDataLayout(), CanBeNull, CanBeFreed));
4954
4955 if (Instruction *CtxI = getCtxI())
4956 followUsesInMBEC(*this, A, getState(), *CtxI);
4957 }
4958
4959 /// See AbstractAttribute::getState()
4960 /// {
4961 StateType &getState() override { return *this; }
4962 const StateType &getState() const override { return *this; }
4963 /// }
4964
4965 /// Helper function for collecting accessed bytes in must-be-executed-context
4966 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4967 DerefState &State) {
4968 const Value *UseV = U->get();
4969 if (!UseV->getType()->isPointerTy())
4970 return;
4971
4972 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4973 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4974 return;
4975
4976 int64_t Offset;
4978 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4979 if (Base && Base == &getAssociatedValue())
4980 State.addAccessedBytes(Offset, Loc->Size.getValue());
4981 }
4982
4983 /// See followUsesInMBEC
4984 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4985 AADereferenceable::StateType &State) {
4986 bool IsNonNull = false;
4987 bool TrackUse = false;
4988 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4989 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4990 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4991 << " for instruction " << *I << "\n");
4992
4993 addAccessedBytesForUse(A, U, I, State);
4994 State.takeKnownDerefBytesMaximum(DerefBytes);
4995 return TrackUse;
4996 }
4997
4998 /// See AbstractAttribute::manifest(...).
4999 ChangeStatus manifest(Attributor &A) override {
5000 ChangeStatus Change = AADereferenceable::manifest(A);
5001 bool IsKnownNonNull;
5002 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5003 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5004 if (IsAssumedNonNull &&
5005 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5006 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5007 return ChangeStatus::CHANGED;
5008 }
5009 return Change;
5010 }
5011
5012 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5013 SmallVectorImpl<Attribute> &Attrs) const override {
5014 // TODO: Add *_globally support
5015 bool IsKnownNonNull;
5016 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5017 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5018 if (IsAssumedNonNull)
5019 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5020 Ctx, getAssumedDereferenceableBytes()));
5021 else
5022 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5023 Ctx, getAssumedDereferenceableBytes()));
5024 }
5025
5026 /// See AbstractAttribute::getAsStr().
5027 const std::string getAsStr(Attributor *A) const override {
5028 if (!getAssumedDereferenceableBytes())
5029 return "unknown-dereferenceable";
5030 bool IsKnownNonNull;
5031 bool IsAssumedNonNull = false;
5032 if (A)
5034 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5035 return std::string("dereferenceable") +
5036 (IsAssumedNonNull ? "" : "_or_null") +
5037 (isAssumedGlobal() ? "_globally" : "") + "<" +
5038 std::to_string(getKnownDereferenceableBytes()) + "-" +
5039 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5040 (!A ? " [non-null is unknown]" : "");
5041 }
5042};
5043
5044/// Dereferenceable attribute for a floating value.
5045struct AADereferenceableFloating : AADereferenceableImpl {
5046 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5047 : AADereferenceableImpl(IRP, A) {}
5048
5049 /// See AbstractAttribute::updateImpl(...).
5050 ChangeStatus updateImpl(Attributor &A) override {
5051 bool Stripped;
5052 bool UsedAssumedInformation = false;
5054 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5055 AA::AnyScope, UsedAssumedInformation)) {
5056 Values.push_back({getAssociatedValue(), getCtxI()});
5057 Stripped = false;
5058 } else {
5059 Stripped = Values.size() != 1 ||
5060 Values.front().getValue() != &getAssociatedValue();
5061 }
5062
5063 const DataLayout &DL = A.getDataLayout();
5064 DerefState T;
5065
5066 auto VisitValueCB = [&](const Value &V) -> bool {
5067 unsigned IdxWidth =
5068 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5069 APInt Offset(IdxWidth, 0);
5071 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5072 /* AllowNonInbounds */ true);
5073
5074 const auto *AA = A.getAAFor<AADereferenceable>(
5075 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5076 int64_t DerefBytes = 0;
5077 if (!AA || (!Stripped && this == AA)) {
5078 // Use IR information if we did not strip anything.
5079 // TODO: track globally.
5080 bool CanBeNull, CanBeFreed;
5081 DerefBytes =
5082 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5083 T.GlobalState.indicatePessimisticFixpoint();
5084 } else {
5085 const DerefState &DS = AA->getState();
5086 DerefBytes = DS.DerefBytesState.getAssumed();
5087 T.GlobalState &= DS.GlobalState;
5088 }
5089
5090 // For now we do not try to "increase" dereferenceability due to negative
5091 // indices as we first have to come up with code to deal with loops and
5092 // for overflows of the dereferenceable bytes.
5093 int64_t OffsetSExt = Offset.getSExtValue();
5094 if (OffsetSExt < 0)
5095 OffsetSExt = 0;
5096
5097 T.takeAssumedDerefBytesMinimum(
5098 std::max(int64_t(0), DerefBytes - OffsetSExt));
5099
5100 if (this == AA) {
5101 if (!Stripped) {
5102 // If nothing was stripped IR information is all we got.
5103 T.takeKnownDerefBytesMaximum(
5104 std::max(int64_t(0), DerefBytes - OffsetSExt));
5105 T.indicatePessimisticFixpoint();
5106 } else if (OffsetSExt > 0) {
5107 // If something was stripped but there is circular reasoning we look
5108 // for the offset. If it is positive we basically decrease the
5109 // dereferenceable bytes in a circular loop now, which will simply
5110 // drive them down to the known value in a very slow way which we
5111 // can accelerate.
5112 T.indicatePessimisticFixpoint();
5113 }
5114 }
5115
5116 return T.isValidState();
5117 };
5118
5119 for (const auto &VAC : Values)
5120 if (!VisitValueCB(*VAC.getValue()))
5121 return indicatePessimisticFixpoint();
5122
5123 return clampStateAndIndicateChange(getState(), T);
5124 }
5125
5126 /// See AbstractAttribute::trackStatistics()
5127 void trackStatistics() const override {
5128 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5129 }
5130};
5131
5132/// Dereferenceable attribute for a return value.
5133struct AADereferenceableReturned final
5134 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5135 using Base =
5136 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5137 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5138 : Base(IRP, A) {}
5139
5140 /// See AbstractAttribute::trackStatistics()
5141 void trackStatistics() const override {
5142 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5143 }
5144};
5145
5146/// Dereferenceable attribute for an argument
5147struct AADereferenceableArgument final
5148 : AAArgumentFromCallSiteArguments<AADereferenceable,
5149 AADereferenceableImpl> {
5150 using Base =
5151 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5152 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5153 : Base(IRP, A) {}
5154
5155 /// See AbstractAttribute::trackStatistics()
5156 void trackStatistics() const override {
5157 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5158 }
5159};
5160
5161/// Dereferenceable attribute for a call site argument.
5162struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5163 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5164 : AADereferenceableFloating(IRP, A) {}
5165
5166 /// See AbstractAttribute::trackStatistics()
5167 void trackStatistics() const override {
5168 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5169 }
5170};
5171
5172/// Dereferenceable attribute deduction for a call site return value.
5173struct AADereferenceableCallSiteReturned final
5174 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5175 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5176 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5177 : Base(IRP, A) {}
5178
5179 /// See AbstractAttribute::trackStatistics()
5180 void trackStatistics() const override {
5181 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5182 }
5183};
5184} // namespace
5185
5186// ------------------------ Align Argument Attribute ------------------------
5187
5188namespace {
5189
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 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5206 switch (II->getIntrinsicID()) {
5207 case Intrinsic::ptrmask: {
5208 // Is it appropriate to pull attribute in initialization?
5209 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5210 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5211 const auto *AlignAA = A.getAAFor<AAAlign>(
5212 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5213 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5214 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5216 Align ConstAlign(UINT64_C(1) << ShiftValue);
5217 if (ConstAlign >= AlignAA->getKnownAlign())
5218 return Align(1).value();
5219 }
5220 if (AlignAA)
5221 return AlignAA->getKnownAlign().value();
5222 break;
5223 }
5224 case Intrinsic::amdgcn_make_buffer_rsrc: {
5225 const auto *AlignAA = A.getAAFor<AAAlign>(
5226 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5227 if (AlignAA)
5228 return AlignAA->getKnownAlign().value();
5229 break;
5230 }
5231 default:
5232 break;
5233 }
5234
5235 MaybeAlign MA;
5236 if (const auto *CB = dyn_cast<CallBase>(I)) {
5237 if (CB->isBundleOperand(U) || CB->isCallee(U))
5238 return 0;
5239
5240 unsigned ArgNo = CB->getArgOperandNo(U);
5241 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5242 // As long as we only use known information there is no need to track
5243 // dependences here.
5244 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5245 if (AlignAA)
5246 MA = MaybeAlign(AlignAA->getKnownAlign());
5247 }
5248
5249 const DataLayout &DL = A.getDataLayout();
5250 const Value *UseV = U->get();
5251 if (auto *SI = dyn_cast<StoreInst>(I)) {
5252 if (SI->getPointerOperand() == UseV)
5253 MA = SI->getAlign();
5254 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5255 if (LI->getPointerOperand() == UseV)
5256 MA = LI->getAlign();
5257 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5258 if (AI->getPointerOperand() == UseV)
5259 MA = AI->getAlign();
5260 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5261 if (AI->getPointerOperand() == UseV)
5262 MA = AI->getAlign();
5263 }
5264
5265 if (!MA || *MA <= QueryingAA.getKnownAlign())
5266 return 0;
5267
5268 unsigned Alignment = MA->value();
5269 int64_t Offset;
5270
5271 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5272 if (Base == &AssociatedValue) {
5273 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5274 // So we can say that the maximum power of two which is a divisor of
5275 // gcd(Offset, Alignment) is an alignment.
5276
5277 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5278 Alignment = llvm::bit_floor(gcd);
5279 }
5280 }
5281
5282 return Alignment;
5283}
5284
5285struct AAAlignImpl : AAAlign {
5286 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5287
5288 /// See AbstractAttribute::initialize(...).
5289 void initialize(Attributor &A) override {
5291 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5292 for (const Attribute &Attr : Attrs)
5293 takeKnownMaximum(Attr.getValueAsInt());
5294
5295 Value &V = *getAssociatedValue().stripPointerCasts();
5296 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5297
5298 if (Instruction *CtxI = getCtxI())
5299 followUsesInMBEC(*this, A, getState(), *CtxI);
5300 }
5301
5302 /// See AbstractAttribute::manifest(...).
5303 ChangeStatus manifest(Attributor &A) override {
5304 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5305
5306 // Check for users that allow alignment annotations.
5307 Value &AssociatedValue = getAssociatedValue();
5308 if (isa<ConstantData>(AssociatedValue))
5309 return ChangeStatus::UNCHANGED;
5310
5311 for (const Use &U : AssociatedValue.uses()) {
5312 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5313 if (SI->getPointerOperand() == &AssociatedValue)
5314 if (SI->getAlign() < getAssumedAlign()) {
5315 STATS_DECLTRACK(AAAlign, Store,
5316 "Number of times alignment added to a store");
5317 SI->setAlignment(getAssumedAlign());
5318 InstrChanged = ChangeStatus::CHANGED;
5319 }
5320 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5321 if (LI->getPointerOperand() == &AssociatedValue)
5322 if (LI->getAlign() < getAssumedAlign()) {
5323 LI->setAlignment(getAssumedAlign());
5324 STATS_DECLTRACK(AAAlign, Load,
5325 "Number of times alignment added to a load");
5326 InstrChanged = ChangeStatus::CHANGED;
5327 }
5328 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5329 if (RMW->getPointerOperand() == &AssociatedValue) {
5330 if (RMW->getAlign() < getAssumedAlign()) {
5331 STATS_DECLTRACK(AAAlign, AtomicRMW,
5332 "Number of times alignment added to atomicrmw");
5333
5334 RMW->setAlignment(getAssumedAlign());
5335 InstrChanged = ChangeStatus::CHANGED;
5336 }
5337 }
5338 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5339 if (CAS->getPointerOperand() == &AssociatedValue) {
5340 if (CAS->getAlign() < getAssumedAlign()) {
5341 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5342 "Number of times alignment added to cmpxchg");
5343 CAS->setAlignment(getAssumedAlign());
5344 InstrChanged = ChangeStatus::CHANGED;
5345 }
5346 }
5347 }
5348 }
5349
5350 ChangeStatus Changed = AAAlign::manifest(A);
5351
5352 Align InheritAlign =
5353 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5354 if (InheritAlign >= getAssumedAlign())
5355 return InstrChanged;
5356 return Changed | InstrChanged;
5357 }
5358
5359 // TODO: Provide a helper to determine the implied ABI alignment and check in
5360 // the existing manifest method and a new one for AAAlignImpl that value
5361 // to avoid making the alignment explicit if it did not improve.
5362
5363 /// See AbstractAttribute::getDeducedAttributes
5364 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5365 SmallVectorImpl<Attribute> &Attrs) const override {
5366 if (getAssumedAlign() > 1)
5367 Attrs.emplace_back(
5368 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5369 }
5370
5371 /// See followUsesInMBEC
5372 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5373 AAAlign::StateType &State) {
5374 bool TrackUse = false;
5375
5376 unsigned int KnownAlign =
5377 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5378 State.takeKnownMaximum(KnownAlign);
5379
5380 return TrackUse;
5381 }
5382
5383 /// See AbstractAttribute::getAsStr().
5384 const std::string getAsStr(Attributor *A) const override {
5385 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5386 std::to_string(getAssumedAlign().value()) + ">";
5387 }
5388};
5389
5390/// Align attribute for a floating value.
5391struct AAAlignFloating : AAAlignImpl {
5392 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5393
5394 /// See AbstractAttribute::updateImpl(...).
5395 ChangeStatus updateImpl(Attributor &A) override {
5396 const DataLayout &DL = A.getDataLayout();
5397
5398 bool Stripped;
5399 bool UsedAssumedInformation = false;
5401 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5402 AA::AnyScope, UsedAssumedInformation)) {
5403 Values.push_back({getAssociatedValue(), getCtxI()});
5404 Stripped = false;
5405 } else {
5406 Stripped = Values.size() != 1 ||
5407 Values.front().getValue() != &getAssociatedValue();
5408 }
5409
5410 StateType T;
5411 auto VisitValueCB = [&](Value &V) -> bool {
5413 return true;
5414 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5415 DepClassTy::REQUIRED);
5416 if (!AA || (!Stripped && this == AA)) {
5417 int64_t Offset;
5418 unsigned Alignment = 1;
5419 if (const Value *Base =
5421 // TODO: Use AAAlign for the base too.
5422 Align PA = Base->getPointerAlignment(DL);
5423 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5424 // So we can say that the maximum power of two which is a divisor of
5425 // gcd(Offset, Alignment) is an alignment.
5426
5427 uint32_t gcd =
5428 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5429 Alignment = llvm::bit_floor(gcd);
5430 } else {
5431 Alignment = V.getPointerAlignment(DL).value();
5432 }
5433 // Use only IR information if we did not strip anything.
5434 T.takeKnownMaximum(Alignment);
5435 T.indicatePessimisticFixpoint();
5436 } else {
5437 // Use abstract attribute information.
5438 const AAAlign::StateType &DS = AA->getState();
5439 T ^= DS;
5440 }
5441 return T.isValidState();
5442 };
5443
5444 for (const auto &VAC : Values) {
5445 if (!VisitValueCB(*VAC.getValue()))
5446 return indicatePessimisticFixpoint();
5447 }
5448
5449 // TODO: If we know we visited all incoming values, thus no are assumed
5450 // dead, we can take the known information from the state T.
5451 return clampStateAndIndicateChange(getState(), T);
5452 }
5453
5454 /// See AbstractAttribute::trackStatistics()
5455 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5456};
5457
5458/// Align attribute for function return value.
5459struct AAAlignReturned final
5460 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5461 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5462 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5463
5464 /// See AbstractAttribute::trackStatistics()
5465 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5466};
5467
5468/// Align attribute for function argument.
5469struct AAAlignArgument final
5470 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5471 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5472 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5473
5474 /// See AbstractAttribute::manifest(...).
5475 ChangeStatus manifest(Attributor &A) override {
5476 // If the associated argument is involved in a must-tail call we give up
5477 // because we would need to keep the argument alignments of caller and
5478 // callee in-sync. Just does not seem worth the trouble right now.
5479 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5480 return ChangeStatus::UNCHANGED;
5481 return Base::manifest(A);
5482 }
5483
5484 /// See AbstractAttribute::trackStatistics()
5485 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5486};
5487
5488struct AAAlignCallSiteArgument final : AAAlignFloating {
5489 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5490 : AAAlignFloating(IRP, A) {}
5491
5492 /// See AbstractAttribute::manifest(...).
5493 ChangeStatus manifest(Attributor &A) override {
5494 // If the associated argument is involved in a must-tail call we give up
5495 // because we would need to keep the argument alignments of caller and
5496 // callee in-sync. Just does not seem worth the trouble right now.
5497 if (Argument *Arg = getAssociatedArgument())
5498 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5499 return ChangeStatus::UNCHANGED;
5500 ChangeStatus Changed = AAAlignImpl::manifest(A);
5501 Align InheritAlign =
5502 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5503 if (InheritAlign >= getAssumedAlign())
5504 Changed = ChangeStatus::UNCHANGED;
5505 return Changed;
5506 }
5507
5508 /// See AbstractAttribute::updateImpl(Attributor &A).
5509 ChangeStatus updateImpl(Attributor &A) override {
5510 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5511 if (Argument *Arg = getAssociatedArgument()) {
5512 // We only take known information from the argument
5513 // so we do not need to track a dependence.
5514 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5515 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5516 if (ArgAlignAA)
5517 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5518 }
5519 return Changed;
5520 }
5521
5522 /// See AbstractAttribute::trackStatistics()
5523 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5524};
5525
5526/// Align attribute deduction for a call site return value.
5527struct AAAlignCallSiteReturned final
5528 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5529 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5530 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5531 : Base(IRP, A) {}
5532
5533 ChangeStatus updateImpl(Attributor &A) override {
5534 Instruction *I = getIRPosition().getCtxI();
5535 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5536 switch (II->getIntrinsicID()) {
5537 case Intrinsic::ptrmask: {
5538 Align Alignment;
5539 bool Valid = false;
5540
5541 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5542 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5543 if (ConstVals && ConstVals->isValidState()) {
5544 unsigned ShiftValue =
5545 std::min(ConstVals->getAssumedMinTrailingZeros(),
5546 Value::MaxAlignmentExponent);
5547 Alignment = Align(UINT64_C(1) << ShiftValue);
5548 Valid = true;
5549 }
5550
5551 const auto *AlignAA =
5552 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5553 DepClassTy::REQUIRED);
5554 if (AlignAA) {
5555 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5556 Valid = true;
5557 }
5558
5559 if (Valid)
5561 this->getState(),
5562 std::min(this->getAssumedAlign(), Alignment).value());
5563 break;
5564 }
5565 // FIXME: Should introduce target specific sub-attributes and letting
5566 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5567 // specific intrinsics.
5568 case Intrinsic::amdgcn_make_buffer_rsrc: {
5569 const auto *AlignAA =
5570 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5571 DepClassTy::REQUIRED);
5572 if (AlignAA)
5574 this->getState(), AlignAA->getAssumedAlign().value());
5575 break;
5576 }
5577 default:
5578 break;
5579 }
5580 }
5581 return Base::updateImpl(A);
5582 };
5583 /// See AbstractAttribute::trackStatistics()
5584 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5585};
5586} // namespace
5587
5588/// ------------------ Function No-Return Attribute ----------------------------
5589namespace {
5590struct AANoReturnImpl : public AANoReturn {
5591 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5592
5593 /// See AbstractAttribute::initialize(...).
5594 void initialize(Attributor &A) override {
5595 bool IsKnown;
5597 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5598 (void)IsKnown;
5599 }
5600
5601 /// See AbstractAttribute::getAsStr().
5602 const std::string getAsStr(Attributor *A) const override {
5603 return getAssumed() ? "noreturn" : "may-return";
5604 }
5605
5606 /// See AbstractAttribute::updateImpl(Attributor &A).
5607 ChangeStatus updateImpl(Attributor &A) override {
5608 auto CheckForNoReturn = [](Instruction &) { return false; };
5609 bool UsedAssumedInformation = false;
5610 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5611 {(unsigned)Instruction::Ret},
5612 UsedAssumedInformation))
5613 return indicatePessimisticFixpoint();
5614 return ChangeStatus::UNCHANGED;
5615 }
5616};
5617
5618struct AANoReturnFunction final : AANoReturnImpl {
5619 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5620 : AANoReturnImpl(IRP, A) {}
5621
5622 /// See AbstractAttribute::trackStatistics()
5623 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5624};
5625
5626/// NoReturn attribute deduction for a call sites.
5627struct AANoReturnCallSite final
5628 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5629 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5630 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5631
5632 /// See AbstractAttribute::trackStatistics()
5633 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5634};
5635} // namespace
5636
5637/// ----------------------- Instance Info ---------------------------------
5638
5639namespace {
5640/// A class to hold the state of for no-capture attributes.
5641struct AAInstanceInfoImpl : public AAInstanceInfo {
5642 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5643 : AAInstanceInfo(IRP, A) {}
5644
5645 /// See AbstractAttribute::initialize(...).
5646 void initialize(Attributor &A) override {
5647 Value &V = getAssociatedValue();
5648 if (auto *C = dyn_cast<Constant>(&V)) {
5649 if (C->isThreadDependent())
5650 indicatePessimisticFixpoint();
5651 else
5652 indicateOptimisticFixpoint();
5653 return;
5654 }
5655 if (auto *CB = dyn_cast<CallBase>(&V))
5656 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5657 !CB->mayReadFromMemory()) {
5658 indicateOptimisticFixpoint();
5659 return;
5660 }
5661 if (auto *I = dyn_cast<Instruction>(&V)) {
5662 const auto *CI =
5663 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5664 *I->getFunction());
5665 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5666 indicatePessimisticFixpoint();
5667 return;
5668 }
5669 }
5670 }
5671
5672 /// See AbstractAttribute::updateImpl(...).
5673 ChangeStatus updateImpl(Attributor &A) override {
5674 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5675
5676 Value &V = getAssociatedValue();
5677 const Function *Scope = nullptr;
5678 if (auto *I = dyn_cast<Instruction>(&V))
5679 Scope = I->getFunction();
5680 if (auto *A = dyn_cast<Argument>(&V)) {
5681 Scope = A->getParent();
5682 if (!Scope->hasLocalLinkage())
5683 return Changed;
5684 }
5685 if (!Scope)
5686 return indicateOptimisticFixpoint();
5687
5688 bool IsKnownNoRecurse;
5690 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5691 IsKnownNoRecurse))
5692 return Changed;
5693
5694 auto UsePred = [&](const Use &U, bool &Follow) {
5695 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5696 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5697 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5698 Follow = true;
5699 return true;
5700 }
5701 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5702 (isa<StoreInst>(UserI) &&
5703 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5704 return true;
5705 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5706 // This check is not guaranteeing uniqueness but for now that we cannot
5707 // end up with two versions of \p U thinking it was one.
5709 if (!Callee || !Callee->hasLocalLinkage())
5710 return true;
5711 if (!CB->isArgOperand(&U))
5712 return false;
5713 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5715 DepClassTy::OPTIONAL);
5716 if (!ArgInstanceInfoAA ||
5717 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5718 return false;
5719 // If this call base might reach the scope again we might forward the
5720 // argument back here. This is very conservative.
5722 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5723 [Scope](const Function &Fn) { return &Fn != Scope; }))
5724 return false;
5725 return true;
5726 }
5727 return false;
5728 };
5729
5730 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5731 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5732 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5733 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5734 AA::isDynamicallyUnique(A, *this, *Ptr))
5735 return true;
5736 }
5737 return false;
5738 };
5739
5740 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5741 DepClassTy::OPTIONAL,
5742 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5743 return indicatePessimisticFixpoint();
5744
5745 return Changed;
5746 }
5747
5748 /// See AbstractState::getAsStr().
5749 const std::string getAsStr(Attributor *A) const override {
5750 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5751 }
5752
5753 /// See AbstractAttribute::trackStatistics()
5754 void trackStatistics() const override {}
5755};
5756
5757/// InstanceInfo attribute for floating values.
5758struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5759 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5760 : AAInstanceInfoImpl(IRP, A) {}
5761};
5762
5763/// NoCapture attribute for function arguments.
5764struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5765 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5766 : AAInstanceInfoFloating(IRP, A) {}
5767};
5768
5769/// InstanceInfo attribute for call site arguments.
5770struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5771 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5772 : AAInstanceInfoImpl(IRP, A) {}
5773
5774 /// See AbstractAttribute::updateImpl(...).
5775 ChangeStatus updateImpl(Attributor &A) override {
5776 // TODO: Once we have call site specific value information we can provide
5777 // call site specific liveness information and then it makes
5778 // sense to specialize attributes for call sites arguments instead of
5779 // redirecting requests to the callee argument.
5780 Argument *Arg = getAssociatedArgument();
5781 if (!Arg)
5782 return indicatePessimisticFixpoint();
5783 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5784 auto *ArgAA =
5785 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5786 if (!ArgAA)
5787 return indicatePessimisticFixpoint();
5788 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5789 }
5790};
5791
5792/// InstanceInfo attribute for function return value.
5793struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5794 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5795 : AAInstanceInfoImpl(IRP, A) {
5796 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5797 }
5798
5799 /// See AbstractAttribute::initialize(...).
5800 void initialize(Attributor &A) override {
5801 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5802 }
5803
5804 /// See AbstractAttribute::updateImpl(...).
5805 ChangeStatus updateImpl(Attributor &A) override {
5806 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5807 }
5808};
5809
5810/// InstanceInfo attribute deduction for a call site return value.
5811struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5812 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5813 : AAInstanceInfoFloating(IRP, A) {}
5814};
5815} // namespace
5816
5817/// ----------------------- Variable Capturing ---------------------------------
5819 Attribute::AttrKind ImpliedAttributeKind,
5820 bool IgnoreSubsumingPositions) {
5821 assert(ImpliedAttributeKind == Attribute::Captures &&
5822 "Unexpected attribute kind");
5823 Value &V = IRP.getAssociatedValue();
5824 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5825 return V.use_empty();
5826
5827 // You cannot "capture" null in the default address space.
5828 //
5829 // FIXME: This should use NullPointerIsDefined to account for the function
5830 // attribute.
5832 V.getType()->getPointerAddressSpace() == 0)) {
5833 return true;
5834 }
5835
5837 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5838 /* IgnoreSubsumingPositions */ true);
5839 for (const Attribute &Attr : Attrs)
5840 if (capturesNothing(Attr.getCaptureInfo()))
5841 return true;
5842
5844 if (Argument *Arg = IRP.getAssociatedArgument()) {
5846 A.getAttrs(IRPosition::argument(*Arg),
5847 {Attribute::Captures, Attribute::ByVal}, Attrs,
5848 /* IgnoreSubsumingPositions */ true);
5849 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5850 return Attr.getKindAsEnum() == Attribute::ByVal ||
5852 });
5853 if (ArgNoCapture) {
5854 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5855 V.getContext(), CaptureInfo::none()));
5856 return true;
5857 }
5858 }
5859
5860 if (const Function *F = IRP.getAssociatedFunction()) {
5861 // Check what state the associated function can actually capture.
5864 if (State.isKnown(NO_CAPTURE)) {
5865 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5867 return true;
5868 }
5869 }
5870
5871 return false;
5872}
5873
5874/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5875/// depending on the ability of the function associated with \p IRP to capture
5876/// state in memory and through "returning/throwing", respectively.
5878 const Function &F,
5879 BitIntegerState &State) {
5880 // TODO: Once we have memory behavior attributes we should use them here.
5881
5882 // If we know we cannot communicate or write to memory, we do not care about
5883 // ptr2int anymore.
5884 bool ReadOnly = F.onlyReadsMemory();
5885 bool NoThrow = F.doesNotThrow();
5886 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5887 if (ReadOnly && NoThrow && IsVoidReturn) {
5888 State.addKnownBits(NO_CAPTURE);
5889 return;
5890 }
5891
5892 // A function cannot capture state in memory if it only reads memory, it can
5893 // however return/throw state and the state might be influenced by the
5894 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5895 if (ReadOnly)
5896 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5897
5898 // A function cannot communicate state back if it does not through
5899 // exceptions and doesn not return values.
5900 if (NoThrow && IsVoidReturn)
5901 State.addKnownBits(NOT_CAPTURED_IN_RET);
5902
5903 // Check existing "returned" attributes.
5904 int ArgNo = IRP.getCalleeArgNo();
5905 if (!NoThrow || ArgNo < 0 ||
5906 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5907 return;
5908
5909 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5910 if (F.hasParamAttribute(U, Attribute::Returned)) {
5911 if (U == unsigned(ArgNo))
5912 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5913 else if (ReadOnly)
5914 State.addKnownBits(NO_CAPTURE);
5915 else
5916 State.addKnownBits(NOT_CAPTURED_IN_RET);
5917 break;
5918 }
5919}
5920
5921namespace {
5922/// A class to hold the state of for no-capture attributes.
5923struct AANoCaptureImpl : public AANoCapture {
5924 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5925
5926 /// See AbstractAttribute::initialize(...).
5927 void initialize(Attributor &A) override {
5928 bool IsKnown;
5930 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5931 (void)IsKnown;
5932 }
5933
5934 /// See AbstractAttribute::updateImpl(...).
5935 ChangeStatus updateImpl(Attributor &A) override;
5936
5937 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5938 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5939 SmallVectorImpl<Attribute> &Attrs) const override {
5940 if (!isAssumedNoCaptureMaybeReturned())
5941 return;
5942
5943 if (isArgumentPosition()) {
5944 if (isAssumedNoCapture())
5945 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5946 else if (ManifestInternal)
5947 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5948 }
5949 }
5950
5951 /// See AbstractState::getAsStr().
5952 const std::string getAsStr(Attributor *A) const override {
5953 if (isKnownNoCapture())
5954 return "known not-captured";
5955 if (isAssumedNoCapture())
5956 return "assumed not-captured";
5957 if (isKnownNoCaptureMaybeReturned())
5958 return "known not-captured-maybe-returned";
5959 if (isAssumedNoCaptureMaybeReturned())
5960 return "assumed not-captured-maybe-returned";
5961 return "assumed-captured";
5962 }
5963
5964 /// Check the use \p U and update \p State accordingly. Return true if we
5965 /// should continue to update the state.
5966 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5967 bool &Follow) {
5968 Instruction *UInst = cast<Instruction>(U.getUser());
5969 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5970 << *UInst << "\n");
5971
5972 // Deal with ptr2int by following uses.
5973 if (isa<PtrToIntInst>(UInst)) {
5974 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5975 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5976 /* Return */ true);
5977 }
5978
5979 // For stores we already checked if we can follow them, if they make it
5980 // here we give up.
5981 if (isa<StoreInst>(UInst))
5982 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5983 /* Return */ true);
5984
5985 // Explicitly catch return instructions.
5986 if (isa<ReturnInst>(UInst)) {
5987 if (UInst->getFunction() == getAnchorScope())
5988 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5989 /* Return */ true);
5990 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5991 /* Return */ true);
5992 }
5993
5994 // For now we only use special logic for call sites. However, the tracker
5995 // itself knows about a lot of other non-capturing cases already.
5996 auto *CB = dyn_cast<CallBase>(UInst);
5997 if (!CB || !CB->isArgOperand(&U))
5998 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5999 /* Return */ true);
6000
6001 unsigned ArgNo = CB->getArgOperandNo(&U);
6002 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6003 // If we have a abstract no-capture attribute for the argument we can use
6004 // it to justify a non-capture attribute here. This allows recursion!
6005 bool IsKnownNoCapture;
6006 const AANoCapture *ArgNoCaptureAA = nullptr;
6007 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6008 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6009 &ArgNoCaptureAA);
6010 if (IsAssumedNoCapture)
6011 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6012 /* Return */ false);
6013 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6014 Follow = true;
6015 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6016 /* Return */ false);
6017 }
6018
6019 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6020 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6021 /* Return */ true);
6022 }
6023
6024 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6025 /// \p CapturedInRet, then return true if we should continue updating the
6026 /// state.
6027 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6028 bool CapturedInInt, bool CapturedInRet) {
6029 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6030 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6031 if (CapturedInMem)
6032 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6033 if (CapturedInInt)
6034 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6035 if (CapturedInRet)
6036 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6037 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6038 }
6039};
6040
6041ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6042 const IRPosition &IRP = getIRPosition();
6043 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6044 : &IRP.getAssociatedValue();
6045 if (!V)
6046 return indicatePessimisticFixpoint();
6047
6048 const Function *F =
6049 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6050
6051 // TODO: Is the checkForAllUses below useful for constants?
6052 if (!F)
6053 return indicatePessimisticFixpoint();
6054
6056 const IRPosition &FnPos = IRPosition::function(*F);
6057
6058 // Readonly means we cannot capture through memory.
6059 bool IsKnown;
6060 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6061 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6062 if (IsKnown)
6063 addKnownBits(NOT_CAPTURED_IN_MEM);
6064 }
6065
6066 // Make sure all returned values are different than the underlying value.
6067 // TODO: we could do this in a more sophisticated way inside
6068 // AAReturnedValues, e.g., track all values that escape through returns
6069 // directly somehow.
6070 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6072 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6074 UsedAssumedInformation))
6075 return false;
6076 bool SeenConstant = false;
6077 for (const AA::ValueAndContext &VAC : Values) {
6078 if (isa<Constant>(VAC.getValue())) {
6079 if (SeenConstant)
6080 return false;
6081 SeenConstant = true;
6082 } else if (!isa<Argument>(VAC.getValue()) ||
6083 VAC.getValue() == getAssociatedArgument())
6084 return false;
6085 }
6086 return true;
6087 };
6088
6089 bool IsKnownNoUnwind;
6091 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6092 bool IsVoidTy = F->getReturnType()->isVoidTy();
6093 bool UsedAssumedInformation = false;
6094 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6095 T.addKnownBits(NOT_CAPTURED_IN_RET);
6096 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6098 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6099 addKnownBits(NOT_CAPTURED_IN_RET);
6100 if (isKnown(NOT_CAPTURED_IN_MEM))
6101 return indicateOptimisticFixpoint();
6102 }
6103 }
6104 }
6105
6106 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6107 // TODO(captures): Make this more precise.
6108 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6109 if (capturesNothing(CI))
6110 return true;
6111 if (CI.isPassthrough()) {
6112 Follow = true;
6113 return true;
6114 }
6115 return checkUse(A, T, U, Follow);
6116 };
6117
6118 if (!A.checkForAllUses(UseCheck, *this, *V))
6119 return indicatePessimisticFixpoint();
6120
6121 AANoCapture::StateType &S = getState();
6122 auto Assumed = S.getAssumed();
6123 S.intersectAssumedBits(T.getAssumed());
6124 if (!isAssumedNoCaptureMaybeReturned())
6125 return indicatePessimisticFixpoint();
6126 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6128}
6129
6130/// NoCapture attribute for function arguments.
6131struct AANoCaptureArgument final : AANoCaptureImpl {
6132 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6133 : AANoCaptureImpl(IRP, A) {}
6134
6135 /// See AbstractAttribute::trackStatistics()
6136 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6137};
6138
6139/// NoCapture attribute for call site arguments.
6140struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6141 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6142 : AANoCaptureImpl(IRP, A) {}
6143
6144 /// See AbstractAttribute::updateImpl(...).
6145 ChangeStatus updateImpl(Attributor &A) override {
6146 // TODO: Once we have call site specific value information we can provide
6147 // call site specific liveness information and then it makes
6148 // sense to specialize attributes for call sites arguments instead of
6149 // redirecting requests to the callee argument.
6150 Argument *Arg = getAssociatedArgument();
6151 if (!Arg)
6152 return indicatePessimisticFixpoint();
6153 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6154 bool IsKnownNoCapture;
6155 const AANoCapture *ArgAA = nullptr;
6157 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6158 &ArgAA))
6159 return ChangeStatus::UNCHANGED;
6160 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6161 return indicatePessimisticFixpoint();
6162 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6163 }
6164
6165 /// See AbstractAttribute::trackStatistics()
6166 void trackStatistics() const override {
6168 };
6169};
6170
6171/// NoCapture attribute for floating values.
6172struct AANoCaptureFloating final : AANoCaptureImpl {
6173 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6174 : AANoCaptureImpl(IRP, A) {}
6175
6176 /// See AbstractAttribute::trackStatistics()
6177 void trackStatistics() const override {
6179 }
6180};
6181
6182/// NoCapture attribute for function return value.
6183struct AANoCaptureReturned final : AANoCaptureImpl {
6184 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6185 : AANoCaptureImpl(IRP, A) {
6186 llvm_unreachable("NoCapture is not applicable to function returns!");
6187 }
6188
6189 /// See AbstractAttribute::initialize(...).
6190 void initialize(Attributor &A) override {
6191 llvm_unreachable("NoCapture is not applicable to function returns!");
6192 }
6193
6194 /// See AbstractAttribute::updateImpl(...).
6195 ChangeStatus updateImpl(Attributor &A) override {
6196 llvm_unreachable("NoCapture is not applicable to function returns!");
6197 }
6198
6199 /// See AbstractAttribute::trackStatistics()
6200 void trackStatistics() const override {}
6201};
6202
6203/// NoCapture attribute deduction for a call site return value.
6204struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6205 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6206 : AANoCaptureImpl(IRP, A) {}
6207
6208 /// See AbstractAttribute::initialize(...).
6209 void initialize(Attributor &A) override {
6210 const Function *F = getAnchorScope();
6211 // Check what state the associated function can actually capture.
6212 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6213 }
6214
6215 /// See AbstractAttribute::trackStatistics()
6216 void trackStatistics() const override {
6218 }
6219};
6220} // namespace
6221
6222/// ------------------ Value Simplify Attribute ----------------------------
6223
6224bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6225 // FIXME: Add a typecast support.
6228 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6229 return false;
6230
6231 LLVM_DEBUG({
6233 dbgs() << "[ValueSimplify] is assumed to be "
6234 << **SimplifiedAssociatedValue << "\n";
6235 else
6236 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6237 });
6238 return true;
6239}
6240
6241namespace {
6242struct AAValueSimplifyImpl : AAValueSimplify {
6243 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6244 : AAValueSimplify(IRP, A) {}
6245
6246 /// See AbstractAttribute::initialize(...).
6247 void initialize(Attributor &A) override {
6248 if (getAssociatedValue().getType()->isVoidTy())
6249 indicatePessimisticFixpoint();
6250 if (A.hasSimplificationCallback(getIRPosition()))
6251 indicatePessimisticFixpoint();
6252 }
6253
6254 /// See AbstractAttribute::getAsStr().
6255 const std::string getAsStr(Attributor *A) const override {
6256 LLVM_DEBUG({
6257 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6258 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6259 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6260 });
6261 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6262 : "not-simple";
6263 }
6264
6265 /// See AbstractAttribute::trackStatistics()
6266 void trackStatistics() const override {}
6267
6268 /// See AAValueSimplify::getAssumedSimplifiedValue()
6269 std::optional<Value *>
6270 getAssumedSimplifiedValue(Attributor &A) const override {
6271 return SimplifiedAssociatedValue;
6272 }
6273
6274 /// Ensure the return value is \p V with type \p Ty, if not possible return
6275 /// nullptr. If \p Check is true we will only verify such an operation would
6276 /// suceed and return a non-nullptr value if that is the case. No IR is
6277 /// generated or modified.
6278 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6279 bool Check) {
6280 if (auto *TypedV = AA::getWithType(V, Ty))
6281 return TypedV;
6282 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6283 return Check ? &V
6284 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6285 &V, &Ty, "", CtxI->getIterator());
6286 return nullptr;
6287 }
6288
6289 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6290 /// If \p Check is true we will only verify such an operation would suceed and
6291 /// return a non-nullptr value if that is the case. No IR is generated or
6292 /// modified.
6293 static Value *reproduceInst(Attributor &A,
6294 const AbstractAttribute &QueryingAA,
6295 Instruction &I, Type &Ty, Instruction *CtxI,
6296 bool Check, ValueToValueMapTy &VMap) {
6297 assert(CtxI && "Cannot reproduce an instruction without context!");
6298 if (Check && (I.mayReadFromMemory() ||
6299 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6300 /* TLI */ nullptr)))
6301 return nullptr;
6302 for (Value *Op : I.operands()) {
6303 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6304 if (!NewOp) {
6305 assert(Check && "Manifest of new value unexpectedly failed!");
6306 return nullptr;
6307 }
6308 if (!Check)
6309 VMap[Op] = NewOp;
6310 }
6311 if (Check)
6312 return &I;
6313
6314 Instruction *CloneI = I.clone();
6315 // TODO: Try to salvage debug information here.
6316 CloneI->setDebugLoc(DebugLoc());
6317 VMap[&I] = CloneI;
6318 CloneI->insertBefore(CtxI->getIterator());
6319 RemapInstruction(CloneI, VMap);
6320 return CloneI;
6321 }
6322
6323 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6324 /// If \p Check is true we will only verify such an operation would suceed and
6325 /// return a non-nullptr value if that is the case. No IR is generated or
6326 /// modified.
6327 static Value *reproduceValue(Attributor &A,
6328 const AbstractAttribute &QueryingAA, Value &V,
6329 Type &Ty, Instruction *CtxI, bool Check,
6330 ValueToValueMapTy &VMap) {
6331 if (const auto &NewV = VMap.lookup(&V))
6332 return NewV;
6333 bool UsedAssumedInformation = false;
6334 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6335 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6336 if (!SimpleV.has_value())
6337 return PoisonValue::get(&Ty);
6338 Value *EffectiveV = &V;
6339 if (*SimpleV)
6340 EffectiveV = *SimpleV;
6341 if (auto *C = dyn_cast<Constant>(EffectiveV))
6342 return C;
6343 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6344 A.getInfoCache()))
6345 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6346 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6347 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6348 return ensureType(A, *NewV, Ty, CtxI, Check);
6349 return nullptr;
6350 }
6351
6352 /// Return a value we can use as replacement for the associated one, or
6353 /// nullptr if we don't have one that makes sense.
6354 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6355 Value *NewV = SimplifiedAssociatedValue
6356 ? *SimplifiedAssociatedValue
6357 : UndefValue::get(getAssociatedType());
6358 if (NewV && NewV != &getAssociatedValue()) {
6359 ValueToValueMapTy VMap;
6360 // First verify we can reprduce the value with the required type at the
6361 // context location before we actually start modifying the IR.
6362 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6363 /* CheckOnly */ true, VMap))
6364 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6365 /* CheckOnly */ false, VMap);
6366 }
6367 return nullptr;
6368 }
6369
6370 /// Helper function for querying AAValueSimplify and updating candidate.
6371 /// \param IRP The value position we are trying to unify with SimplifiedValue
6372 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6373 const IRPosition &IRP, bool Simplify = true) {
6374 bool UsedAssumedInformation = false;
6375 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6376 if (Simplify)
6377 QueryingValueSimplified = A.getAssumedSimplified(
6378 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6379 return unionAssumed(QueryingValueSimplified);
6380 }
6381
6382 /// Returns a candidate is found or not
6383 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6384 if (!getAssociatedValue().getType()->isIntegerTy())
6385 return false;
6386
6387 // This will also pass the call base context.
6388 const auto *AA =
6389 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6390 if (!AA)
6391 return false;
6392
6393 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6394
6395 if (!COpt) {
6396 SimplifiedAssociatedValue = std::nullopt;
6397 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6398 return true;
6399 }
6400 if (auto *C = *COpt) {
6401 SimplifiedAssociatedValue = C;
6402 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6403 return true;
6404 }
6405 return false;
6406 }
6407
6408 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6409 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6410 return true;
6411 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6412 return true;
6413 return false;
6414 }
6415
6416 /// See AbstractAttribute::manifest(...).
6417 ChangeStatus manifest(Attributor &A) override {
6418 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6419 for (auto &U : getAssociatedValue().uses()) {
6420 // Check if we need to adjust the insertion point to make sure the IR is
6421 // valid.
6422 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6423 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6424 IP = PHI->getIncomingBlock(U)->getTerminator();
6425 if (auto *NewV = manifestReplacementValue(A, IP)) {
6426 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6427 << " -> " << *NewV << " :: " << *this << "\n");
6428 if (A.changeUseAfterManifest(U, *NewV))
6429 Changed = ChangeStatus::CHANGED;
6430 }
6431 }
6432
6433 return Changed | AAValueSimplify::manifest(A);
6434 }
6435
6436 /// See AbstractState::indicatePessimisticFixpoint(...).
6437 ChangeStatus indicatePessimisticFixpoint() override {
6438 SimplifiedAssociatedValue = &getAssociatedValue();
6439 return AAValueSimplify::indicatePessimisticFixpoint();
6440 }
6441};
6442
6443struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6444 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6445 : AAValueSimplifyImpl(IRP, A) {}
6446
6447 void initialize(Attributor &A) override {
6448 AAValueSimplifyImpl::initialize(A);
6449 if (A.hasAttr(getIRPosition(),
6450 {Attribute::InAlloca, Attribute::Preallocated,
6451 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6452 /* IgnoreSubsumingPositions */ true))
6453 indicatePessimisticFixpoint();
6454 }
6455
6456 /// See AbstractAttribute::updateImpl(...).
6457 ChangeStatus updateImpl(Attributor &A) override {
6458 // Byval is only replacable if it is readonly otherwise we would write into
6459 // the replaced value and not the copy that byval creates implicitly.
6460 Argument *Arg = getAssociatedArgument();
6461 if (Arg->hasByValAttr()) {
6462 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6463 // there is no race by not copying a constant byval.
6464 bool IsKnown;
6465 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6466 return indicatePessimisticFixpoint();
6467 }
6468
6469 auto Before = SimplifiedAssociatedValue;
6470
6471 auto PredForCallSite = [&](AbstractCallSite ACS) {
6472 const IRPosition &ACSArgPos =
6473 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6474 // Check if a coresponding argument was found or if it is on not
6475 // associated (which can happen for callback calls).
6476 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6477 return false;
6478
6479 // Simplify the argument operand explicitly and check if the result is
6480 // valid in the current scope. This avoids refering to simplified values
6481 // in other functions, e.g., we don't want to say a an argument in a
6482 // static function is actually an argument in a different function.
6483 bool UsedAssumedInformation = false;
6484 std::optional<Constant *> SimpleArgOp =
6485 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6486 if (!SimpleArgOp)
6487 return true;
6488 if (!*SimpleArgOp)
6489 return false;
6490 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6491 return false;
6492 return unionAssumed(*SimpleArgOp);
6493 };
6494
6495 // Generate a answer specific to a call site context.
6496 bool Success;
6497 bool UsedAssumedInformation = false;
6498 if (hasCallBaseContext() &&
6499 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6500 Success = PredForCallSite(
6501 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6502 else
6503 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6504 UsedAssumedInformation);
6505
6506 if (!Success)
6507 if (!askSimplifiedValueForOtherAAs(A))
6508 return indicatePessimisticFixpoint();
6509
6510 // If a candidate was found in this update, return CHANGED.
6511 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6512 : ChangeStatus ::CHANGED;
6513 }
6514
6515 /// See AbstractAttribute::trackStatistics()
6516 void trackStatistics() const override {
6517 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6518 }
6519};
6520
6521struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6522 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6523 : AAValueSimplifyImpl(IRP, A) {}
6524
6525 /// See AAValueSimplify::getAssumedSimplifiedValue()
6526 std::optional<Value *>
6527 getAssumedSimplifiedValue(Attributor &A) const override {
6528 if (!isValidState())
6529 return nullptr;
6530 return SimplifiedAssociatedValue;
6531 }
6532
6533 /// See AbstractAttribute::updateImpl(...).
6534 ChangeStatus updateImpl(Attributor &A) override {
6535 auto Before = SimplifiedAssociatedValue;
6536
6537 auto ReturnInstCB = [&](Instruction &I) {
6538 auto &RI = cast<ReturnInst>(I);
6539 return checkAndUpdate(
6540 A, *this,
6541 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6542 };
6543
6544 bool UsedAssumedInformation = false;
6545 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6546 UsedAssumedInformation))
6547 if (!askSimplifiedValueForOtherAAs(A))
6548 return indicatePessimisticFixpoint();
6549
6550 // If a candidate was found in this update, return CHANGED.
6551 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6552 : ChangeStatus ::CHANGED;
6553 }
6554
6555 ChangeStatus manifest(Attributor &A) override {
6556 // We queried AAValueSimplify for the returned values so they will be
6557 // replaced if a simplified form was found. Nothing to do here.
6558 return ChangeStatus::UNCHANGED;
6559 }
6560
6561 /// See AbstractAttribute::trackStatistics()
6562 void trackStatistics() const override {
6563 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6564 }
6565};
6566
6567struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6568 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6569 : AAValueSimplifyImpl(IRP, A) {}
6570
6571 /// See AbstractAttribute::initialize(...).
6572 void initialize(Attributor &A) override {
6573 AAValueSimplifyImpl::initialize(A);
6574 Value &V = getAnchorValue();
6575
6576 // TODO: add other stuffs
6577 if (isa<Constant>(V))
6578 indicatePessimisticFixpoint();
6579 }
6580
6581 /// See AbstractAttribute::updateImpl(...).
6582 ChangeStatus updateImpl(Attributor &A) override {
6583 auto Before = SimplifiedAssociatedValue;
6584 if (!askSimplifiedValueForOtherAAs(A))
6585 return indicatePessimisticFixpoint();
6586
6587 // If a candidate was found in this update, return CHANGED.
6588 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6589 : ChangeStatus ::CHANGED;
6590 }
6591
6592 /// See AbstractAttribute::trackStatistics()
6593 void trackStatistics() const override {
6594 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6595 }
6596};
6597
6598struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6599 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6600 : AAValueSimplifyImpl(IRP, A) {}
6601
6602 /// See AbstractAttribute::initialize(...).
6603 void initialize(Attributor &A) override {
6604 SimplifiedAssociatedValue = nullptr;
6605 indicateOptimisticFixpoint();
6606 }
6607 /// See AbstractAttribute::initialize(...).
6608 ChangeStatus updateImpl(Attributor &A) override {
6610 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6611 }
6612 /// See AbstractAttribute::trackStatistics()
6613 void trackStatistics() const override {
6614 STATS_DECLTRACK_FN_ATTR(value_simplify)
6615 }
6616};
6617
6618struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6619 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6620 : AAValueSimplifyFunction(IRP, A) {}
6621 /// See AbstractAttribute::trackStatistics()
6622 void trackStatistics() const override {
6623 STATS_DECLTRACK_CS_ATTR(value_simplify)
6624 }
6625};
6626
6627struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6628 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6629 : AAValueSimplifyImpl(IRP, A) {}
6630
6631 void initialize(Attributor &A) override {
6632 AAValueSimplifyImpl::initialize(A);
6633 Function *Fn = getAssociatedFunction();
6634 assert(Fn && "Did expect an associted function");
6635 for (Argument &Arg : Fn->args()) {
6636 if (Arg.hasReturnedAttr()) {
6637 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6638 Arg.getArgNo());
6640 checkAndUpdate(A, *this, IRP))
6641 indicateOptimisticFixpoint();
6642 else
6643 indicatePessimisticFixpoint();
6644 return;
6645 }
6646 }
6647 }
6648
6649 /// See AbstractAttribute::updateImpl(...).
6650 ChangeStatus updateImpl(Attributor &A) override {
6651 return indicatePessimisticFixpoint();
6652 }
6653
6654 void trackStatistics() const override {
6655 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6656 }
6657};
6658
6659struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6660 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6661 : AAValueSimplifyFloating(IRP, A) {}
6662
6663 /// See AbstractAttribute::manifest(...).
6664 ChangeStatus manifest(Attributor &A) override {
6665 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6666 // TODO: We should avoid simplification duplication to begin with.
6667 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6668 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6669 if (FloatAA && FloatAA->getState().isValidState())
6670 return Changed;
6671
6672 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6673 Use &U = cast<CallBase>(&getAnchorValue())
6674 ->getArgOperandUse(getCallSiteArgNo());
6675 if (A.changeUseAfterManifest(U, *NewV))
6676 Changed = ChangeStatus::CHANGED;
6677 }
6678
6679 return Changed | AAValueSimplify::manifest(A);
6680 }
6681
6682 void trackStatistics() const override {
6683 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6684 }
6685};
6686} // namespace
6687
6688/// ----------------------- Heap-To-Stack Conversion ---------------------------
6689namespace {
6690struct AAHeapToStackFunction final : public AAHeapToStack {
6691
6692 static bool isGlobalizedLocal(const CallBase &CB) {
6693 Attribute A = CB.getFnAttr("alloc-family");
6694 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6695 }
6696
6697 struct AllocationInfo {
6698 /// The call that allocates the memory.
6699 CallBase *const CB;
6700
6701 /// Whether this allocation is an OpenMP globalized local variable.
6702 bool IsGlobalizedLocal = false;
6703
6704 /// The status wrt. a rewrite.
6705 enum {
6706 STACK_DUE_TO_USE,
6707 STACK_DUE_TO_FREE,
6708 INVALID,
6709 } Status = STACK_DUE_TO_USE;
6710
6711 /// Flag to indicate if we encountered a use that might free this allocation
6712 /// but which is not in the deallocation infos.
6713 bool HasPotentiallyFreeingUnknownUses = false;
6714
6715 /// Flag to indicate that we should place the new alloca in the function
6716 /// entry block rather than where the call site (CB) is.
6717 bool MoveAllocaIntoEntry = true;
6718
6719 /// The set of free calls that use this allocation.
6720 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6721 };
6722
6723 struct DeallocationInfo {
6724 /// The call that deallocates the memory.
6725 CallBase *const CB;
6726 /// The value freed by the call.
6727 Value *FreedOp;
6728
6729 /// Flag to indicate if we don't know all objects this deallocation might
6730 /// free.
6731 bool MightFreeUnknownObjects = false;
6732
6733 /// The set of allocation calls that are potentially freed.
6734 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6735 };
6736
6737 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6738 : AAHeapToStack(IRP, A) {}
6739
6740 ~AAHeapToStackFunction() override {
6741 // Ensure we call the destructor so we release any memory allocated in the
6742 // sets.
6743 for (auto &It : AllocationInfos)
6744 It.second->~AllocationInfo();
6745 for (auto &It : DeallocationInfos)
6746 It.second->~DeallocationInfo();
6747 }
6748
6749 void initialize(Attributor &A) override {
6750 AAHeapToStack::initialize(A);
6751
6752 const Function *F = getAnchorScope();
6753 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6754
6755 auto AllocationIdentifierCB = [&](Instruction &I) {
6756 CallBase *CB = dyn_cast<CallBase>(&I);
6757 if (!CB)
6758 return true;
6759 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6760 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6761 return true;
6762 }
6763 // To do heap to stack, we need to know that the allocation itself is
6764 // removable once uses are rewritten, and that we can initialize the
6765 // alloca to the same pattern as the original allocation result.
6766 if (isRemovableAlloc(CB, TLI)) {
6767 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6768 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6769 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6770 AllocationInfos[CB] = AI;
6771 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6772 }
6773 }
6774 return true;
6775 };
6776
6777 bool UsedAssumedInformation = false;
6778 bool Success = A.checkForAllCallLikeInstructions(
6779 AllocationIdentifierCB, *this, UsedAssumedInformation,
6780 /* CheckBBLivenessOnly */ false,
6781 /* CheckPotentiallyDead */ true);
6782 (void)Success;
6783 assert(Success && "Did not expect the call base visit callback to fail!");
6784
6786 [](const IRPosition &, const AbstractAttribute *,
6787 bool &) -> std::optional<Value *> { return nullptr; };
6788 for (const auto &It : AllocationInfos)
6789 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6790 SCB);
6791 for (const auto &It : DeallocationInfos)
6792 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6793 SCB);
6794 }
6795
6796 const std::string getAsStr(Attributor *A) const override {
6797 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6798 for (const auto &It : AllocationInfos) {
6799 if (It.second->Status == AllocationInfo::INVALID)
6800 ++NumInvalidMallocs;
6801 else
6802 ++NumH2SMallocs;
6803 }
6804 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6805 std::to_string(NumInvalidMallocs);
6806 }
6807
6808 /// See AbstractAttribute::trackStatistics().
6809 void trackStatistics() const override {
6810 STATS_DECL(
6811 MallocCalls, Function,
6812 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6813 for (const auto &It : AllocationInfos)
6814 if (It.second->Status != AllocationInfo::INVALID)
6815 ++BUILD_STAT_NAME(MallocCalls, Function);
6816 }
6817
6818 bool isAssumedHeapToStack(const CallBase &CB) const override {
6819 if (isValidState())
6820 if (AllocationInfo *AI =
6821 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6822 return AI->Status != AllocationInfo::INVALID;
6823 return false;
6824 }
6825
6826 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6827 if (!isValidState())
6828 return false;
6829
6830 for (const auto &It : AllocationInfos) {
6831 AllocationInfo &AI = *It.second;
6832 if (AI.Status == AllocationInfo::INVALID)
6833 continue;
6834
6835 if (AI.PotentialFreeCalls.count(&CB))
6836 return true;
6837 }
6838
6839 return false;
6840 }
6841
6842 ChangeStatus manifest(Attributor &A) override {
6843 assert(getState().isValidState() &&
6844 "Attempted to manifest an invalid state!");
6845
6846 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6847 Function *F = getAnchorScope();
6848 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6849
6850 for (auto &It : AllocationInfos) {
6851 AllocationInfo &AI = *It.second;
6852 if (AI.Status == AllocationInfo::INVALID)
6853 continue;
6854
6855 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6856 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6857 A.deleteAfterManifest(*FreeCall);
6858 HasChanged = ChangeStatus::CHANGED;
6859 }
6860
6861 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6862 << "\n");
6863
6864 auto Remark = [&](OptimizationRemark OR) {
6865 if (AI.IsGlobalizedLocal)
6866 return OR << "Moving globalized variable to the stack.";
6867 return OR << "Moving memory allocation from the heap to the stack.";
6868 };
6869 if (AI.IsGlobalizedLocal)
6870 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6871 else
6872 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6873
6874 const DataLayout &DL = A.getInfoCache().getDL();
6875 Value *Size;
6876 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6877 if (SizeAPI) {
6878 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6879 } else {
6880 LLVMContext &Ctx = AI.CB->getContext();
6881 ObjectSizeOpts Opts;
6882 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6883 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6884 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6885 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6886 Size = SizeOffsetPair.Size;
6887 }
6888
6889 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6890 ? F->getEntryBlock().begin()
6891 : AI.CB->getIterator();
6892
6893 Align Alignment(1);
6894 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6895 Alignment = std::max(Alignment, *RetAlign);
6896 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6897 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6898 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6899 "Expected an alignment during manifest!");
6900 Alignment =
6901 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6902 }
6903
6904 // TODO: Hoist the alloca towards the function entry.
6905 unsigned AS = DL.getAllocaAddrSpace();
6906 Instruction *Alloca =
6907 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6908 AI.CB->getName() + ".h2s", IP);
6909
6910 if (Alloca->getType() != AI.CB->getType())
6911 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6912 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6913
6914 auto *I8Ty = Type::getInt8Ty(F->getContext());
6915 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6916 assert(InitVal &&
6917 "Must be able to materialize initial memory state of allocation");
6918
6919 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6920
6921 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6922 auto *NBB = II->getNormalDest();
6923 UncondBrInst::Create(NBB, AI.CB->getParent());
6924 A.deleteAfterManifest(*AI.CB);
6925 } else {
6926 A.deleteAfterManifest(*AI.CB);
6927 }
6928
6929 // Initialize the alloca with the same value as used by the allocation
6930 // function. We can skip undef as the initial value of an alloc is
6931 // undef, and the memset would simply end up being DSEd.
6932 if (!isa<UndefValue>(InitVal)) {
6933 IRBuilder<> Builder(Alloca->getNextNode());
6934 // TODO: Use alignment above if align!=1
6935 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6936 }
6937 HasChanged = ChangeStatus::CHANGED;
6938 }
6939
6940 return HasChanged;
6941 }
6942
6943 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6944 Value &V) {
6945 bool UsedAssumedInformation = false;
6946 std::optional<Constant *> SimpleV =
6947 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6948 if (!SimpleV)
6949 return APInt(64, 0);
6950 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6951 return CI->getValue();
6952 return std::nullopt;
6953 }
6954
6955 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6956 AllocationInfo &AI) {
6957 auto Mapper = [&](const Value *V) -> const Value * {
6958 bool UsedAssumedInformation = false;
6959 if (std::optional<Constant *> SimpleV =
6960 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6961 if (*SimpleV)
6962 return *SimpleV;
6963 return V;
6964 };
6965
6966 const Function *F = getAnchorScope();
6967 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6968 return getAllocSize(AI.CB, TLI, Mapper);
6969 }
6970
6971 /// Collection of all malloc-like calls in a function with associated
6972 /// information.
6973 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6974
6975 /// Collection of all free-like calls in a function with associated
6976 /// information.
6977 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6978
6979 ChangeStatus updateImpl(Attributor &A) override;
6980};
6981
6982ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6984 const Function *F = getAnchorScope();
6985 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6986
6987 const auto *LivenessAA =
6988 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6989
6990 MustBeExecutedContextExplorer *Explorer =
6991 A.getInfoCache().getMustBeExecutedContextExplorer();
6992
6993 bool StackIsAccessibleByOtherThreads =
6994 A.getInfoCache().stackIsAccessibleByOtherThreads();
6995
6996 LoopInfo *LI =
6997 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6998 std::optional<bool> MayContainIrreducibleControl;
6999 auto IsInLoop = [&](BasicBlock &BB) {
7000 if (&F->getEntryBlock() == &BB)
7001 return false;
7002 if (!MayContainIrreducibleControl.has_value())
7003 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7004 if (*MayContainIrreducibleControl)
7005 return true;
7006 if (!LI)
7007 return true;
7008 return LI->getLoopFor(&BB) != nullptr;
7009 };
7010
7011 // Flag to ensure we update our deallocation information at most once per
7012 // updateImpl call and only if we use the free check reasoning.
7013 bool HasUpdatedFrees = false;
7014
7015 auto UpdateFrees = [&]() {
7016 HasUpdatedFrees = true;
7017
7018 for (auto &It : DeallocationInfos) {
7019 DeallocationInfo &DI = *It.second;
7020 // For now we cannot use deallocations that have unknown inputs, skip
7021 // them.
7022 if (DI.MightFreeUnknownObjects)
7023 continue;
7024
7025 // No need to analyze dead calls, ignore them instead.
7026 bool UsedAssumedInformation = false;
7027 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7028 /* CheckBBLivenessOnly */ true))
7029 continue;
7030
7031 // Use the non-optimistic version to get the freed object.
7032 Value *Obj = getUnderlyingObject(DI.FreedOp);
7033 if (!Obj) {
7034 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7035 DI.MightFreeUnknownObjects = true;
7036 continue;
7037 }
7038
7039 // Free of null and undef can be ignored as no-ops (or UB in the latter
7040 // case).
7042 continue;
7043
7044 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7045 if (!ObjCB) {
7046 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7047 << "\n");
7048 DI.MightFreeUnknownObjects = true;
7049 continue;
7050 }
7051
7052 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7053 if (!AI) {
7054 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7055 << "\n");
7056 DI.MightFreeUnknownObjects = true;
7057 continue;
7058 }
7059
7060 DI.PotentialAllocationCalls.insert(ObjCB);
7061 }
7062 };
7063
7064 auto FreeCheck = [&](AllocationInfo &AI) {
7065 // If the stack is not accessible by other threads, the "must-free" logic
7066 // doesn't apply as the pointer could be shared and needs to be places in
7067 // "shareable" memory.
7068 if (!StackIsAccessibleByOtherThreads) {
7069 bool IsKnownNoSycn;
7071 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7072 LLVM_DEBUG(
7073 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7074 "other threads and function is not nosync:\n");
7075 return false;
7076 }
7077 }
7078 if (!HasUpdatedFrees)
7079 UpdateFrees();
7080
7081 // TODO: Allow multi exit functions that have different free calls.
7082 if (AI.PotentialFreeCalls.size() != 1) {
7083 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7084 << AI.PotentialFreeCalls.size() << "\n");
7085 return false;
7086 }
7087 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7088 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7089 if (!DI) {
7090 LLVM_DEBUG(
7091 dbgs() << "[H2S] unique free call was not known as deallocation call "
7092 << *UniqueFree << "\n");
7093 return false;
7094 }
7095 if (DI->MightFreeUnknownObjects) {
7096 LLVM_DEBUG(
7097 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7098 return false;
7099 }
7100 if (DI->PotentialAllocationCalls.empty())
7101 return true;
7102 if (DI->PotentialAllocationCalls.size() > 1) {
7103 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7104 << DI->PotentialAllocationCalls.size()
7105 << " different allocations\n");
7106 return false;
7107 }
7108 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7109 LLVM_DEBUG(
7110 dbgs()
7111 << "[H2S] unique free call not known to free this allocation but "
7112 << **DI->PotentialAllocationCalls.begin() << "\n");
7113 return false;
7114 }
7115
7116 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7117 if (!AI.IsGlobalizedLocal) {
7118 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7119 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7120 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7121 "with the allocation "
7122 << *UniqueFree << "\n");
7123 return false;
7124 }
7125 }
7126 return true;
7127 };
7128
7129 auto UsesCheck = [&](AllocationInfo &AI) {
7130 bool ValidUsesOnly = true;
7131
7132 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7133 Instruction *UserI = cast<Instruction>(U.getUser());
7134 if (isa<LoadInst>(UserI))
7135 return true;
7136 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7137 if (SI->getValueOperand() == U.get()) {
7139 << "[H2S] escaping store to memory: " << *UserI << "\n");
7140 ValidUsesOnly = false;
7141 } else {
7142 // A store into the malloc'ed memory is fine.
7143 }
7144 return true;
7145 }
7146 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7147 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7148 return true;
7149 if (DeallocationInfos.count(CB)) {
7150 AI.PotentialFreeCalls.insert(CB);
7151 return true;
7152 }
7153
7154 unsigned ArgNo = CB->getArgOperandNo(&U);
7155 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7156
7157 bool IsKnownNoCapture;
7158 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7159 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7160
7161 // If a call site argument use is nofree, we are fine.
7162 bool IsKnownNoFree;
7163 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7164 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7165
7166 if (!IsAssumedNoCapture ||
7167 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7168 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7169
7170 // Emit a missed remark if this is missed OpenMP globalization.
7171 auto Remark = [&](OptimizationRemarkMissed ORM) {
7172 return ORM
7173 << "Could not move globalized variable to the stack. "
7174 "Variable is potentially captured in call. Mark "
7175 "parameter as `__attribute__((noescape))` to override.";
7176 };
7177
7178 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7179 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7180
7181 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7182 ValidUsesOnly = false;
7183 }
7184 return true;
7185 }
7186
7187 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7188 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7189 Follow = true;
7190 return true;
7191 }
7192 // Unknown user for which we can not track uses further (in a way that
7193 // makes sense).
7194 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7195 ValidUsesOnly = false;
7196 return true;
7197 };
7198 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7199 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7200 [&](const Use &OldU, const Use &NewU) {
7201 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7202 return !SI || StackIsAccessibleByOtherThreads ||
7203 AA::isAssumedThreadLocalObject(
7204 A, *SI->getPointerOperand(), *this);
7205 }))
7206 return false;
7207 return ValidUsesOnly;
7208 };
7209
7210 // The actual update starts here. We look at all allocations and depending on
7211 // their status perform the appropriate check(s).
7212 for (auto &It : AllocationInfos) {
7213 AllocationInfo &AI = *It.second;
7214 if (AI.Status == AllocationInfo::INVALID)
7215 continue;
7216
7217 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7218 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7219 if (!APAlign) {
7220 // Can't generate an alloca which respects the required alignment
7221 // on the allocation.
7222 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7223 << "\n");
7224 AI.Status = AllocationInfo::INVALID;
7226 continue;
7227 }
7228 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7229 !APAlign->isPowerOf2()) {
7230 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7231 << "\n");
7232 AI.Status = AllocationInfo::INVALID;
7234 continue;
7235 }
7236 }
7237
7238 std::optional<APInt> Size = getSize(A, *this, AI);
7239 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7240 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7241 LLVM_DEBUG({
7242 if (!Size)
7243 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7244 else
7245 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7246 << MaxHeapToStackSize << "\n";
7247 });
7248
7249 AI.Status = AllocationInfo::INVALID;
7251 continue;
7252 }
7253 }
7254
7255 switch (AI.Status) {
7256 case AllocationInfo::STACK_DUE_TO_USE:
7257 if (UsesCheck(AI))
7258 break;
7259 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7260 [[fallthrough]];
7261 case AllocationInfo::STACK_DUE_TO_FREE:
7262 if (FreeCheck(AI))
7263 break;
7264 AI.Status = AllocationInfo::INVALID;
7266 break;
7267 case AllocationInfo::INVALID:
7268 llvm_unreachable("Invalid allocations should never reach this point!");
7269 };
7270
7271 // Check if we still think we can move it into the entry block. If the
7272 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7273 // ignore the potential complications associated with loops.
7274 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7275 if (AI.MoveAllocaIntoEntry &&
7276 (!Size.has_value() ||
7277 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7278 AI.MoveAllocaIntoEntry = false;
7279 }
7280
7281 return Changed;
7282}
7283} // namespace
7284
7285/// ----------------------- Privatizable Pointers ------------------------------
7286namespace {
7287struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7288 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7289 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7290
7291 ChangeStatus indicatePessimisticFixpoint() override {
7292 AAPrivatizablePtr::indicatePessimisticFixpoint();
7293 PrivatizableType = nullptr;
7294 return ChangeStatus::CHANGED;
7295 }
7296
7297 /// Identify the type we can chose for a private copy of the underlying
7298 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7299 /// none.
7300 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7301
7302 /// Return a privatizable type that encloses both T0 and T1.
7303 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7304 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7305 std::optional<Type *> T1) {
7306 if (!T0)
7307 return T1;
7308 if (!T1)
7309 return T0;
7310 if (T0 == T1)
7311 return T0;
7312 return nullptr;
7313 }
7314
7315 std::optional<Type *> getPrivatizableType() const override {
7316 return PrivatizableType;
7317 }
7318
7319 const std::string getAsStr(Attributor *A) const override {
7320 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7321 }
7322
7323protected:
7324 std::optional<Type *> PrivatizableType;
7325};
7326
7327// TODO: Do this for call site arguments (probably also other values) as well.
7328
7329struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7330 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7331 : AAPrivatizablePtrImpl(IRP, A) {}
7332
7333 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7334 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7335 // If this is a byval argument and we know all the call sites (so we can
7336 // rewrite them), there is no need to check them explicitly.
7337 bool UsedAssumedInformation = false;
7339 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7340 /* IgnoreSubsumingPositions */ true);
7341 if (!Attrs.empty() &&
7342 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7343 true, UsedAssumedInformation))
7344 return Attrs[0].getValueAsType();
7345
7346 std::optional<Type *> Ty;
7347 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7348
7349 // Make sure the associated call site argument has the same type at all call
7350 // sites and it is an allocation we know is safe to privatize, for now that
7351 // means we only allow alloca instructions.
7352 // TODO: We can additionally analyze the accesses in the callee to create
7353 // the type from that information instead. That is a little more
7354 // involved and will be done in a follow up patch.
7355 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7356 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7357 // Check if a coresponding argument was found or if it is one not
7358 // associated (which can happen for callback calls).
7359 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7360 return false;
7361
7362 // Check that all call sites agree on a type.
7363 auto *PrivCSArgAA =
7364 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7365 if (!PrivCSArgAA)
7366 return false;
7367 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7368
7369 LLVM_DEBUG({
7370 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7371 if (CSTy && *CSTy)
7372 (*CSTy)->print(dbgs());
7373 else if (CSTy)
7374 dbgs() << "<nullptr>";
7375 else
7376 dbgs() << "<none>";
7377 });
7378
7379 Ty = combineTypes(Ty, CSTy);
7380
7381 LLVM_DEBUG({
7382 dbgs() << " : New Type: ";
7383 if (Ty && *Ty)
7384 (*Ty)->print(dbgs());
7385 else if (Ty)
7386 dbgs() << "<nullptr>";
7387 else
7388 dbgs() << "<none>";
7389 dbgs() << "\n";
7390 });
7391
7392 return !Ty || *Ty;
7393 };
7394
7395 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7396 UsedAssumedInformation))
7397 return nullptr;
7398 return Ty;
7399 }
7400
7401 /// See AbstractAttribute::updateImpl(...).
7402 ChangeStatus updateImpl(Attributor &A) override {
7403 PrivatizableType = identifyPrivatizableType(A);
7404 if (!PrivatizableType)
7405 return ChangeStatus::UNCHANGED;
7406 if (!*PrivatizableType)
7407 return indicatePessimisticFixpoint();
7408
7409 // The dependence is optional so we don't give up once we give up on the
7410 // alignment.
7411 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7412 DepClassTy::OPTIONAL);
7413
7414 // Avoid arguments with padding for now.
7415 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7416 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7417 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7418 return indicatePessimisticFixpoint();
7419 }
7420
7421 // Collect the types that will replace the privatizable type in the function
7422 // signature.
7423 SmallVector<Type *, 16> ReplacementTypes;
7424 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7425
7426 // Verify callee and caller agree on how the promoted argument would be
7427 // passed.
7428 Function &Fn = *getIRPosition().getAnchorScope();
7429 const auto *TTI =
7430 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7431 if (!TTI) {
7432 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7433 << Fn.getName() << "\n");
7434 return indicatePessimisticFixpoint();
7435 }
7436
7437 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7438 CallBase *CB = ACS.getInstruction();
7439 return TTI->areTypesABICompatible(
7440 CB->getCaller(),
7442 ReplacementTypes);
7443 };
7444 bool UsedAssumedInformation = false;
7445 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7446 UsedAssumedInformation)) {
7447 LLVM_DEBUG(
7448 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7449 << Fn.getName() << "\n");
7450 return indicatePessimisticFixpoint();
7451 }
7452
7453 // Register a rewrite of the argument.
7454 Argument *Arg = getAssociatedArgument();
7455 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7456 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7457 return indicatePessimisticFixpoint();
7458 }
7459
7460 unsigned ArgNo = Arg->getArgNo();
7461
7462 // Helper to check if for the given call site the associated argument is
7463 // passed to a callback where the privatization would be different.
7464 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7465 SmallVector<const Use *, 4> CallbackUses;
7466 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7467 for (const Use *U : CallbackUses) {
7468 AbstractCallSite CBACS(U);
7469 assert(CBACS && CBACS.isCallbackCall());
7470 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7471 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7472
7473 LLVM_DEBUG({
7474 dbgs()
7475 << "[AAPrivatizablePtr] Argument " << *Arg
7476 << "check if can be privatized in the context of its parent ("
7477 << Arg->getParent()->getName()
7478 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7479 "callback ("
7480 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7481 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7482 << CBACS.getCallArgOperand(CBArg) << " vs "
7483 << CB.getArgOperand(ArgNo) << "\n"
7484 << "[AAPrivatizablePtr] " << CBArg << " : "
7485 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7486 });
7487
7488 if (CBArgNo != int(ArgNo))
7489 continue;
7490 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7491 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7492 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7493 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7494 if (!CBArgPrivTy)
7495 continue;
7496 if (*CBArgPrivTy == PrivatizableType)
7497 continue;
7498 }
7499
7500 LLVM_DEBUG({
7501 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7502 << " cannot be privatized in the context of its parent ("
7503 << Arg->getParent()->getName()
7504 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7505 "callback ("
7506 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7507 << ").\n[AAPrivatizablePtr] for which the argument "
7508 "privatization is not compatible.\n";
7509 });
7510 return false;
7511 }
7512 }
7513 return true;
7514 };
7515
7516 // Helper to check if for the given call site the associated argument is
7517 // passed to a direct call where the privatization would be different.
7518 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7519 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7520 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7521 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7522 "Expected a direct call operand for callback call operand");
7523
7524 Function *DCCallee =
7526 LLVM_DEBUG({
7527 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7528 << " check if be privatized in the context of its parent ("
7529 << Arg->getParent()->getName()
7530 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7531 "direct call of ("
7532 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7533 });
7534
7535 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7536 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7537 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7538 DepClassTy::REQUIRED);
7539 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7540 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7541 if (!DCArgPrivTy)
7542 return true;
7543 if (*DCArgPrivTy == PrivatizableType)
7544 return true;
7545 }
7546 }
7547
7548 LLVM_DEBUG({
7549 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7550 << " cannot be privatized in the context of its parent ("
7551 << Arg->getParent()->getName()
7552 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7553 "direct call of ("
7555 << ").\n[AAPrivatizablePtr] for which the argument "
7556 "privatization is not compatible.\n";
7557 });
7558 return false;
7559 };
7560
7561 // Helper to check if the associated argument is used at the given abstract
7562 // call site in a way that is incompatible with the privatization assumed
7563 // here.
7564 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7565 if (ACS.isDirectCall())
7566 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7567 if (ACS.isCallbackCall())
7568 return IsCompatiblePrivArgOfDirectCS(ACS);
7569 return false;
7570 };
7571
7572 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7573 UsedAssumedInformation))
7574 return indicatePessimisticFixpoint();
7575
7576 return ChangeStatus::UNCHANGED;
7577 }
7578
7579 /// Given a type to private \p PrivType, collect the constituates (which are
7580 /// used) in \p ReplacementTypes.
7581 static void
7582 identifyReplacementTypes(Type *PrivType,
7583 SmallVectorImpl<Type *> &ReplacementTypes) {
7584 // TODO: For now we expand the privatization type to the fullest which can
7585 // lead to dead arguments that need to be removed later.
7586 assert(PrivType && "Expected privatizable type!");
7587
7588 // Traverse the type, extract constituate types on the outermost level.
7589 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7590 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7591 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7592 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7593 ReplacementTypes.append(PrivArrayType->getNumElements(),
7594 PrivArrayType->getElementType());
7595 } else {
7596 ReplacementTypes.push_back(PrivType);
7597 }
7598 }
7599
7600 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7601 /// The values needed are taken from the arguments of \p F starting at
7602 /// position \p ArgNo.
7603 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7604 unsigned ArgNo, BasicBlock::iterator IP) {
7605 assert(PrivType && "Expected privatizable type!");
7606
7607 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7608 const DataLayout &DL = F.getDataLayout();
7609
7610 // Traverse the type, build GEPs and stores.
7611 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7612 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7613 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7614 Value *Ptr =
7615 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7616 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7617 }
7618 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7619 Type *PointeeTy = PrivArrayType->getElementType();
7620 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7621 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7622 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7623 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7624 }
7625 } else {
7626 new StoreInst(F.getArg(ArgNo), &Base, IP);
7627 }
7628 }
7629
7630 /// Extract values from \p Base according to the type \p PrivType at the
7631 /// call position \p ACS. The values are appended to \p ReplacementValues.
7632 void createReplacementValues(Align Alignment, Type *PrivType,
7633 AbstractCallSite ACS, Value *Base,
7634 SmallVectorImpl<Value *> &ReplacementValues) {
7635 assert(Base && "Expected base value!");
7636 assert(PrivType && "Expected privatizable type!");
7637 Instruction *IP = ACS.getInstruction();
7638
7639 IRBuilder<NoFolder> IRB(IP);
7640 const DataLayout &DL = IP->getDataLayout();
7641
7642 // Traverse the type, build GEPs and loads.
7643 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7644 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7645 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7646 Type *PointeeTy = PrivStructType->getElementType(u);
7647 Value *Ptr =
7648 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7649 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7650 L->setAlignment(Alignment);
7651 ReplacementValues.push_back(L);
7652 }
7653 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7654 Type *PointeeTy = PrivArrayType->getElementType();
7655 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7656 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7657 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7658 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7659 L->setAlignment(Alignment);
7660 ReplacementValues.push_back(L);
7661 }
7662 } else {
7663 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7664 L->setAlignment(Alignment);
7665 ReplacementValues.push_back(L);
7666 }
7667 }
7668
7669 /// See AbstractAttribute::manifest(...)
7670 ChangeStatus manifest(Attributor &A) override {
7671 if (!PrivatizableType)
7672 return ChangeStatus::UNCHANGED;
7673 assert(*PrivatizableType && "Expected privatizable type!");
7674
7675 // Collect all tail calls in the function as we cannot allow new allocas to
7676 // escape into tail recursion.
7677 // TODO: Be smarter about new allocas escaping into tail calls.
7679 bool UsedAssumedInformation = false;
7680 if (!A.checkForAllInstructions(
7681 [&](Instruction &I) {
7682 CallInst &CI = cast<CallInst>(I);
7683 if (CI.isTailCall())
7684 TailCalls.push_back(&CI);
7685 return true;
7686 },
7687 *this, {Instruction::Call}, UsedAssumedInformation))
7688 return ChangeStatus::UNCHANGED;
7689
7690 Argument *Arg = getAssociatedArgument();
7691 // Query AAAlign attribute for alignment of associated argument to
7692 // determine the best alignment of loads.
7693 const auto *AlignAA =
7694 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7695
7696 // Callback to repair the associated function. A new alloca is placed at the
7697 // beginning and initialized with the values passed through arguments. The
7698 // new alloca replaces the use of the old pointer argument.
7700 [=](const Attributor::ArgumentReplacementInfo &ARI,
7701 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7702 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7704 const DataLayout &DL = IP->getDataLayout();
7705 unsigned AS = DL.getAllocaAddrSpace();
7706 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7707 Arg->getName() + ".priv", IP);
7708 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7709 ArgIt->getArgNo(), IP);
7710
7711 if (AI->getType() != Arg->getType())
7712 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7713 AI, Arg->getType(), "", IP);
7714 Arg->replaceAllUsesWith(AI);
7715
7716 for (CallInst *CI : TailCalls)
7717 CI->setTailCall(false);
7718 };
7719
7720 // Callback to repair a call site of the associated function. The elements
7721 // of the privatizable type are loaded prior to the call and passed to the
7722 // new function version.
7724 [=](const Attributor::ArgumentReplacementInfo &ARI,
7725 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7726 // When no alignment is specified for the load instruction,
7727 // natural alignment is assumed.
7728 createReplacementValues(
7729 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7730 *PrivatizableType, ACS,
7731 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7732 NewArgOperands);
7733 };
7734
7735 // Collect the types that will replace the privatizable type in the function
7736 // signature.
7737 SmallVector<Type *, 16> ReplacementTypes;
7738 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7739
7740 // Register a rewrite of the argument.
7741 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7742 std::move(FnRepairCB),
7743 std::move(ACSRepairCB)))
7744 return ChangeStatus::CHANGED;
7745 return ChangeStatus::UNCHANGED;
7746 }
7747
7748 /// See AbstractAttribute::trackStatistics()
7749 void trackStatistics() const override {
7750 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7751 }
7752};
7753
7754struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7755 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7756 : AAPrivatizablePtrImpl(IRP, A) {}
7757
7758 /// See AbstractAttribute::initialize(...).
7759 void initialize(Attributor &A) override {
7760 // TODO: We can privatize more than arguments.
7761 indicatePessimisticFixpoint();
7762 }
7763
7764 ChangeStatus updateImpl(Attributor &A) override {
7765 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7766 "updateImpl will not be called");
7767 }
7768
7769 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7770 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7771 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7772 if (!Obj) {
7773 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7774 return nullptr;
7775 }
7776
7777 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7778 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7779 if (CI->isOne())
7780 return AI->getAllocatedType();
7781 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7782 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7783 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7784 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7785 return PrivArgAA->getPrivatizableType();
7786 }
7787
7788 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7789 "alloca nor privatizable argument: "
7790 << *Obj << "!\n");
7791 return nullptr;
7792 }
7793
7794 /// See AbstractAttribute::trackStatistics()
7795 void trackStatistics() const override {
7796 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7797 }
7798};
7799
7800struct AAPrivatizablePtrCallSiteArgument final
7801 : public AAPrivatizablePtrFloating {
7802 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7803 : AAPrivatizablePtrFloating(IRP, A) {}
7804
7805 /// See AbstractAttribute::initialize(...).
7806 void initialize(Attributor &A) override {
7807 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7808 indicateOptimisticFixpoint();
7809 }
7810
7811 /// See AbstractAttribute::updateImpl(...).
7812 ChangeStatus updateImpl(Attributor &A) override {
7813 PrivatizableType = identifyPrivatizableType(A);
7814 if (!PrivatizableType)
7815 return ChangeStatus::UNCHANGED;
7816 if (!*PrivatizableType)
7817 return indicatePessimisticFixpoint();
7818
7819 const IRPosition &IRP = getIRPosition();
7820 bool IsKnownNoCapture;
7821 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7822 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7823 if (!IsAssumedNoCapture) {
7824 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7825 return indicatePessimisticFixpoint();
7826 }
7827
7828 bool IsKnownNoAlias;
7830 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7831 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7832 return indicatePessimisticFixpoint();
7833 }
7834
7835 bool IsKnown;
7836 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7837 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7838 return indicatePessimisticFixpoint();
7839 }
7840
7841 return ChangeStatus::UNCHANGED;
7842 }
7843
7844 /// See AbstractAttribute::trackStatistics()
7845 void trackStatistics() const override {
7846 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7847 }
7848};
7849
7850struct AAPrivatizablePtrCallSiteReturned final
7851 : public AAPrivatizablePtrFloating {
7852 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7853 : AAPrivatizablePtrFloating(IRP, A) {}
7854
7855 /// See AbstractAttribute::initialize(...).
7856 void initialize(Attributor &A) override {
7857 // TODO: We can privatize more than arguments.
7858 indicatePessimisticFixpoint();
7859 }
7860
7861 /// See AbstractAttribute::trackStatistics()
7862 void trackStatistics() const override {
7863 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7864 }
7865};
7866
7867struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7868 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7869 : AAPrivatizablePtrFloating(IRP, A) {}
7870
7871 /// See AbstractAttribute::initialize(...).
7872 void initialize(Attributor &A) override {
7873 // TODO: We can privatize more than arguments.
7874 indicatePessimisticFixpoint();
7875 }
7876
7877 /// See AbstractAttribute::trackStatistics()
7878 void trackStatistics() const override {
7879 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7880 }
7881};
7882} // namespace
7883
7884/// -------------------- Memory Behavior Attributes ----------------------------
7885/// Includes read-none, read-only, and write-only.
7886/// ----------------------------------------------------------------------------
7887namespace {
7888struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7889 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7890 : AAMemoryBehavior(IRP, A) {}
7891
7892 /// See AbstractAttribute::initialize(...).
7893 void initialize(Attributor &A) override {
7894 intersectAssumedBits(BEST_STATE);
7895 getKnownStateFromValue(A, getIRPosition(), getState());
7896 AAMemoryBehavior::initialize(A);
7897 }
7898
7899 /// Return the memory behavior information encoded in the IR for \p IRP.
7900 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7901 BitIntegerState &State,
7902 bool IgnoreSubsumingPositions = false) {
7904 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7905 for (const Attribute &Attr : Attrs) {
7906 switch (Attr.getKindAsEnum()) {
7907 case Attribute::ReadNone:
7908 State.addKnownBits(NO_ACCESSES);
7909 break;
7910 case Attribute::ReadOnly:
7911 State.addKnownBits(NO_WRITES);
7912 break;
7913 case Attribute::WriteOnly:
7914 State.addKnownBits(NO_READS);
7915 break;
7916 default:
7917 llvm_unreachable("Unexpected attribute!");
7918 }
7919 }
7920
7921 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7922 if (!I->mayReadFromMemory())
7923 State.addKnownBits(NO_READS);
7924 if (!I->mayWriteToMemory())
7925 State.addKnownBits(NO_WRITES);
7926 }
7927 }
7928
7929 /// See AbstractAttribute::getDeducedAttributes(...).
7930 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7931 SmallVectorImpl<Attribute> &Attrs) const override {
7932 assert(Attrs.size() == 0);
7933 if (isAssumedReadNone())
7934 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7935 else if (isAssumedReadOnly())
7936 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7937 else if (isAssumedWriteOnly())
7938 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7939 assert(Attrs.size() <= 1);
7940 }
7941
7942 /// See AbstractAttribute::manifest(...).
7943 ChangeStatus manifest(Attributor &A) override {
7944 const IRPosition &IRP = getIRPosition();
7945
7946 if (A.hasAttr(IRP, Attribute::ReadNone,
7947 /* IgnoreSubsumingPositions */ true))
7948 return ChangeStatus::UNCHANGED;
7949
7950 // Check if we would improve the existing attributes first.
7951 SmallVector<Attribute, 4> DeducedAttrs;
7952 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7953 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7954 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7955 /* IgnoreSubsumingPositions */ true);
7956 }))
7957 return ChangeStatus::UNCHANGED;
7958
7959 // Clear existing attributes.
7960 A.removeAttrs(IRP, AttrKinds);
7961 // Clear conflicting writable attribute.
7962 if (isAssumedReadOnly())
7963 A.removeAttrs(IRP, Attribute::Writable);
7964
7965 // Use the generic manifest method.
7966 return IRAttribute::manifest(A);
7967 }
7968
7969 /// See AbstractState::getAsStr().
7970 const std::string getAsStr(Attributor *A) const override {
7971 if (isAssumedReadNone())
7972 return "readnone";
7973 if (isAssumedReadOnly())
7974 return "readonly";
7975 if (isAssumedWriteOnly())
7976 return "writeonly";
7977 return "may-read/write";
7978 }
7979
7980 /// The set of IR attributes AAMemoryBehavior deals with.
7981 static const Attribute::AttrKind AttrKinds[3];
7982};
7983
7984const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7985 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7986
7987/// Memory behavior attribute for a floating value.
7988struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7989 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7990 : AAMemoryBehaviorImpl(IRP, A) {}
7991
7992 /// See AbstractAttribute::updateImpl(...).
7993 ChangeStatus updateImpl(Attributor &A) override;
7994
7995 /// See AbstractAttribute::trackStatistics()
7996 void trackStatistics() const override {
7997 if (isAssumedReadNone())
7999 else if (isAssumedReadOnly())
8001 else if (isAssumedWriteOnly())
8003 }
8004
8005private:
8006 /// Return true if users of \p UserI might access the underlying
8007 /// variable/location described by \p U and should therefore be analyzed.
8008 bool followUsersOfUseIn(Attributor &A, const Use &U,
8009 const Instruction *UserI);
8010
8011 /// Update the state according to the effect of use \p U in \p UserI.
8012 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8013};
8014
8015/// Memory behavior attribute for function argument.
8016struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8017 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8018 : AAMemoryBehaviorFloating(IRP, A) {}
8019
8020 /// See AbstractAttribute::initialize(...).
8021 void initialize(Attributor &A) override {
8022 intersectAssumedBits(BEST_STATE);
8023 const IRPosition &IRP = getIRPosition();
8024 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8025 // can query it when we use has/getAttr. That would allow us to reuse the
8026 // initialize of the base class here.
8027 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8028 /* IgnoreSubsumingPositions */ true);
8029 getKnownStateFromValue(A, IRP, getState(),
8030 /* IgnoreSubsumingPositions */ HasByVal);
8031 }
8032
8033 ChangeStatus manifest(Attributor &A) override {
8034 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8035 if (!getAssociatedValue().getType()->isPointerTy())
8036 return ChangeStatus::UNCHANGED;
8037
8038 // TODO: From readattrs.ll: "inalloca parameters are always
8039 // considered written"
8040 if (A.hasAttr(getIRPosition(),
8041 {Attribute::InAlloca, Attribute::Preallocated})) {
8042 removeKnownBits(NO_WRITES);
8043 removeAssumedBits(NO_WRITES);
8044 }
8045 A.removeAttrs(getIRPosition(), AttrKinds);
8046 return AAMemoryBehaviorFloating::manifest(A);
8047 }
8048
8049 /// See AbstractAttribute::trackStatistics()
8050 void trackStatistics() const override {
8051 if (isAssumedReadNone())
8052 STATS_DECLTRACK_ARG_ATTR(readnone)
8053 else if (isAssumedReadOnly())
8054 STATS_DECLTRACK_ARG_ATTR(readonly)
8055 else if (isAssumedWriteOnly())
8056 STATS_DECLTRACK_ARG_ATTR(writeonly)
8057 }
8058};
8059
8060struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8061 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8062 : AAMemoryBehaviorArgument(IRP, A) {}
8063
8064 /// See AbstractAttribute::initialize(...).
8065 void initialize(Attributor &A) override {
8066 // If we don't have an associated attribute this is either a variadic call
8067 // or an indirect call, either way, nothing to do here.
8068 Argument *Arg = getAssociatedArgument();
8069 if (!Arg) {
8070 indicatePessimisticFixpoint();
8071 return;
8072 }
8073 if (Arg->hasByValAttr()) {
8074 addKnownBits(NO_WRITES);
8075 removeKnownBits(NO_READS);
8076 removeAssumedBits(NO_READS);
8077 }
8078 AAMemoryBehaviorArgument::initialize(A);
8079 if (getAssociatedFunction()->isDeclaration())
8080 indicatePessimisticFixpoint();
8081 }
8082
8083 /// See AbstractAttribute::updateImpl(...).
8084 ChangeStatus updateImpl(Attributor &A) override {
8085 // TODO: Once we have call site specific value information we can provide
8086 // call site specific liveness liveness information and then it makes
8087 // sense to specialize attributes for call sites arguments instead of
8088 // redirecting requests to the callee argument.
8089 Argument *Arg = getAssociatedArgument();
8090 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8091 auto *ArgAA =
8092 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8093 if (!ArgAA)
8094 return indicatePessimisticFixpoint();
8095 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8096 }
8097
8098 /// See AbstractAttribute::trackStatistics()
8099 void trackStatistics() const override {
8100 if (isAssumedReadNone())
8102 else if (isAssumedReadOnly())
8104 else if (isAssumedWriteOnly())
8106 }
8107};
8108
8109/// Memory behavior attribute for a call site return position.
8110struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8111 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8112 : AAMemoryBehaviorFloating(IRP, A) {}
8113
8114 /// See AbstractAttribute::initialize(...).
8115 void initialize(Attributor &A) override {
8116 AAMemoryBehaviorImpl::initialize(A);
8117 }
8118 /// See AbstractAttribute::manifest(...).
8119 ChangeStatus manifest(Attributor &A) override {
8120 // We do not annotate returned values.
8121 return ChangeStatus::UNCHANGED;
8122 }
8123
8124 /// See AbstractAttribute::trackStatistics()
8125 void trackStatistics() const override {}
8126};
8127
8128/// An AA to represent the memory behavior function attributes.
8129struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8130 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8131 : AAMemoryBehaviorImpl(IRP, A) {}
8132
8133 /// See AbstractAttribute::updateImpl(Attributor &A).
8134 ChangeStatus updateImpl(Attributor &A) override;
8135
8136 /// See AbstractAttribute::manifest(...).
8137 ChangeStatus manifest(Attributor &A) override {
8138 // TODO: It would be better to merge this with AAMemoryLocation, so that
8139 // we could determine read/write per location. This would also have the
8140 // benefit of only one place trying to manifest the memory attribute.
8141 Function &F = cast<Function>(getAnchorValue());
8143 if (isAssumedReadNone())
8144 ME = MemoryEffects::none();
8145 else if (isAssumedReadOnly())
8147 else if (isAssumedWriteOnly())
8149
8150 A.removeAttrs(getIRPosition(), AttrKinds);
8151 // Clear conflicting writable attribute.
8152 if (ME.onlyReadsMemory())
8153 for (Argument &Arg : F.args())
8154 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8155 return A.manifestAttrs(getIRPosition(),
8156 Attribute::getWithMemoryEffects(F.getContext(), ME));
8157 }
8158
8159 /// See AbstractAttribute::trackStatistics()
8160 void trackStatistics() const override {
8161 if (isAssumedReadNone())
8162 STATS_DECLTRACK_FN_ATTR(readnone)
8163 else if (isAssumedReadOnly())
8164 STATS_DECLTRACK_FN_ATTR(readonly)
8165 else if (isAssumedWriteOnly())
8166 STATS_DECLTRACK_FN_ATTR(writeonly)
8167 }
8168};
8169
8170/// AAMemoryBehavior attribute for call sites.
8171struct AAMemoryBehaviorCallSite final
8172 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8173 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8174 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8175
8176 /// See AbstractAttribute::manifest(...).
8177 ChangeStatus manifest(Attributor &A) override {
8178 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8179 CallBase &CB = cast<CallBase>(getAnchorValue());
8181 if (isAssumedReadNone())
8182 ME = MemoryEffects::none();
8183 else if (isAssumedReadOnly())
8185 else if (isAssumedWriteOnly())
8187
8188 A.removeAttrs(getIRPosition(), AttrKinds);
8189 // Clear conflicting writable attribute.
8190 if (ME.onlyReadsMemory())
8191 for (Use &U : CB.args())
8192 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8193 Attribute::Writable);
8194 return A.manifestAttrs(
8195 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8196 }
8197
8198 /// See AbstractAttribute::trackStatistics()
8199 void trackStatistics() const override {
8200 if (isAssumedReadNone())
8201 STATS_DECLTRACK_CS_ATTR(readnone)
8202 else if (isAssumedReadOnly())
8203 STATS_DECLTRACK_CS_ATTR(readonly)
8204 else if (isAssumedWriteOnly())
8205 STATS_DECLTRACK_CS_ATTR(writeonly)
8206 }
8207};
8208
8209ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8210
8211 // The current assumed state used to determine a change.
8212 auto AssumedState = getAssumed();
8213
8214 auto CheckRWInst = [&](Instruction &I) {
8215 // If the instruction has an own memory behavior state, use it to restrict
8216 // the local state. No further analysis is required as the other memory
8217 // state is as optimistic as it gets.
8218 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8219 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8221 if (MemBehaviorAA) {
8222 intersectAssumedBits(MemBehaviorAA->getAssumed());
8223 return !isAtFixpoint();
8224 }
8225 }
8226
8227 // Remove access kind modifiers if necessary.
8228 if (I.mayReadFromMemory())
8229 removeAssumedBits(NO_READS);
8230 if (I.mayWriteToMemory())
8231 removeAssumedBits(NO_WRITES);
8232 return !isAtFixpoint();
8233 };
8234
8235 bool UsedAssumedInformation = false;
8236 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8237 UsedAssumedInformation))
8238 return indicatePessimisticFixpoint();
8239
8240 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8242}
8243
8244ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8245
8246 const IRPosition &IRP = getIRPosition();
8247 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8248 AAMemoryBehavior::StateType &S = getState();
8249
8250 // First, check the function scope. We take the known information and we avoid
8251 // work if the assumed information implies the current assumed information for
8252 // this attribute. This is a valid for all but byval arguments.
8253 Argument *Arg = IRP.getAssociatedArgument();
8254 AAMemoryBehavior::base_t FnMemAssumedState =
8256 if (!Arg || !Arg->hasByValAttr()) {
8257 const auto *FnMemAA =
8258 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8259 if (FnMemAA) {
8260 FnMemAssumedState = FnMemAA->getAssumed();
8261 S.addKnownBits(FnMemAA->getKnown());
8262 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8264 }
8265 }
8266
8267 // The current assumed state used to determine a change.
8268 auto AssumedState = S.getAssumed();
8269
8270 // Make sure the value is not captured (except through "return"), if
8271 // it is, any information derived would be irrelevant anyway as we cannot
8272 // check the potential aliases introduced by the capture. However, no need
8273 // to fall back to anythign less optimistic than the function state.
8274 bool IsKnownNoCapture;
8275 const AANoCapture *ArgNoCaptureAA = nullptr;
8276 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8277 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8278 &ArgNoCaptureAA);
8279
8280 if (!IsAssumedNoCapture &&
8281 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8282 S.intersectAssumedBits(FnMemAssumedState);
8283 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8285 }
8286
8287 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8288 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8289 Instruction *UserI = cast<Instruction>(U.getUser());
8290 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8291 << " \n");
8292
8293 // Droppable users, e.g., llvm::assume does not actually perform any action.
8294 if (UserI->isDroppable())
8295 return true;
8296
8297 // Check if the users of UserI should also be visited.
8298 Follow = followUsersOfUseIn(A, U, UserI);
8299
8300 // If UserI might touch memory we analyze the use in detail.
8301 if (UserI->mayReadOrWriteMemory())
8302 analyzeUseIn(A, U, UserI);
8303
8304 return !isAtFixpoint();
8305 };
8306
8307 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8308 return indicatePessimisticFixpoint();
8309
8310 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8312}
8313
8314bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8315 const Instruction *UserI) {
8316 // The loaded value is unrelated to the pointer argument, no need to
8317 // follow the users of the load.
8318 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8319 return false;
8320
8321 // By default we follow all uses assuming UserI might leak information on U,
8322 // we have special handling for call sites operands though.
8323 const auto *CB = dyn_cast<CallBase>(UserI);
8324 if (!CB || !CB->isArgOperand(&U))
8325 return true;
8326
8327 // If the use is a call argument known not to be captured, the users of
8328 // the call do not need to be visited because they have to be unrelated to
8329 // the input. Note that this check is not trivial even though we disallow
8330 // general capturing of the underlying argument. The reason is that the
8331 // call might the argument "through return", which we allow and for which we
8332 // need to check call users.
8333 if (U.get()->getType()->isPointerTy()) {
8334 unsigned ArgNo = CB->getArgOperandNo(&U);
8335 bool IsKnownNoCapture;
8337 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8338 DepClassTy::OPTIONAL, IsKnownNoCapture);
8339 }
8340
8341 return true;
8342}
8343
8344void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8345 const Instruction *UserI) {
8346 assert(UserI->mayReadOrWriteMemory());
8347
8348 switch (UserI->getOpcode()) {
8349 default:
8350 // TODO: Handle all atomics and other side-effect operations we know of.
8351 break;
8352 case Instruction::Load:
8353 // Loads cause the NO_READS property to disappear.
8354 removeAssumedBits(NO_READS);
8355 return;
8356
8357 case Instruction::Store:
8358 // Stores cause the NO_WRITES property to disappear if the use is the
8359 // pointer operand. Note that while capturing was taken care of somewhere
8360 // else we need to deal with stores of the value that is not looked through.
8361 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8362 removeAssumedBits(NO_WRITES);
8363 else
8364 indicatePessimisticFixpoint();
8365 return;
8366
8367 case Instruction::Call:
8368 case Instruction::CallBr:
8369 case Instruction::Invoke: {
8370 // For call sites we look at the argument memory behavior attribute (this
8371 // could be recursive!) in order to restrict our own state.
8372 const auto *CB = cast<CallBase>(UserI);
8373
8374 // Give up on operand bundles.
8375 if (CB->isBundleOperand(&U)) {
8376 indicatePessimisticFixpoint();
8377 return;
8378 }
8379
8380 // Calling a function does read the function pointer, maybe write it if the
8381 // function is self-modifying.
8382 if (CB->isCallee(&U)) {
8383 removeAssumedBits(NO_READS);
8384 break;
8385 }
8386
8387 // Adjust the possible access behavior based on the information on the
8388 // argument.
8389 IRPosition Pos;
8390 if (U.get()->getType()->isPointerTy())
8392 else
8394 const auto *MemBehaviorAA =
8395 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8396 if (!MemBehaviorAA)
8397 break;
8398 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8399 // and at least "known".
8400 intersectAssumedBits(MemBehaviorAA->getAssumed());
8401 return;
8402 }
8403 };
8404
8405 // Generally, look at the "may-properties" and adjust the assumed state if we
8406 // did not trigger special handling before.
8407 if (UserI->mayReadFromMemory())
8408 removeAssumedBits(NO_READS);
8409 if (UserI->mayWriteToMemory())
8410 removeAssumedBits(NO_WRITES);
8411}
8412} // namespace
8413
8414/// -------------------- Memory Locations Attributes ---------------------------
8415/// Includes read-none, argmemonly, inaccessiblememonly,
8416/// inaccessiblememorargmemonly
8417/// ----------------------------------------------------------------------------
8418
8421 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8422 return "all memory";
8424 return "no memory";
8425 std::string S = "memory:";
8426 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8427 S += "stack,";
8428 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8429 S += "constant,";
8431 S += "internal global,";
8433 S += "external global,";
8434 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8435 S += "argument,";
8437 S += "inaccessible,";
8438 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8439 S += "malloced,";
8440 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8441 S += "unknown,";
8442 S.pop_back();
8443 return S;
8444}
8445
8446namespace {
8447struct AAMemoryLocationImpl : public AAMemoryLocation {
8448
8449 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8450 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8451 AccessKind2Accesses.fill(nullptr);
8452 }
8453
8454 ~AAMemoryLocationImpl() override {
8455 // The AccessSets are allocated via a BumpPtrAllocator, we call
8456 // the destructor manually.
8457 for (AccessSet *AS : AccessKind2Accesses)
8458 if (AS)
8459 AS->~AccessSet();
8460 }
8461
8462 /// See AbstractAttribute::initialize(...).
8463 void initialize(Attributor &A) override {
8464 intersectAssumedBits(BEST_STATE);
8465 getKnownStateFromValue(A, getIRPosition(), getState());
8466 AAMemoryLocation::initialize(A);
8467 }
8468
8469 /// Return the memory behavior information encoded in the IR for \p IRP.
8470 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8471 BitIntegerState &State,
8472 bool IgnoreSubsumingPositions = false) {
8473 // For internal functions we ignore `argmemonly` and
8474 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8475 // constant propagation. It is unclear if this is the best way but it is
8476 // unlikely this will cause real performance problems. If we are deriving
8477 // attributes for the anchor function we even remove the attribute in
8478 // addition to ignoring it.
8479 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8480 // MemoryEffects::Other as a possible location.
8481 bool UseArgMemOnly = true;
8482 Function *AnchorFn = IRP.getAnchorScope();
8483 if (AnchorFn && A.isRunOn(*AnchorFn))
8484 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8485
8487 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8488 for (const Attribute &Attr : Attrs) {
8489 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8490 MemoryEffects ME = Attr.getMemoryEffects();
8491 if (ME.doesNotAccessMemory()) {
8492 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8493 continue;
8494 }
8495 if (ME.onlyAccessesInaccessibleMem()) {
8496 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8497 continue;
8498 }
8499 if (ME.onlyAccessesArgPointees()) {
8500 if (UseArgMemOnly)
8501 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8502 else {
8503 // Remove location information, only keep read/write info.
8504 ME = MemoryEffects(ME.getModRef());
8505 A.manifestAttrs(IRP,
8506 Attribute::getWithMemoryEffects(
8507 IRP.getAnchorValue().getContext(), ME),
8508 /*ForceReplace*/ true);
8509 }
8510 continue;
8511 }
8513 if (UseArgMemOnly)
8514 State.addKnownBits(inverseLocation(
8515 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8516 else {
8517 // Remove location information, only keep read/write info.
8518 ME = MemoryEffects(ME.getModRef());
8519 A.manifestAttrs(IRP,
8520 Attribute::getWithMemoryEffects(
8521 IRP.getAnchorValue().getContext(), ME),
8522 /*ForceReplace*/ true);
8523 }
8524 continue;
8525 }
8526 }
8527 }
8528
8529 /// See AbstractAttribute::getDeducedAttributes(...).
8530 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8531 SmallVectorImpl<Attribute> &Attrs) const override {
8532 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8533 assert(Attrs.size() == 0);
8534 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8535 if (isAssumedReadNone())
8536 Attrs.push_back(
8537 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8538 else if (isAssumedInaccessibleMemOnly())
8539 Attrs.push_back(Attribute::getWithMemoryEffects(
8541 else if (isAssumedArgMemOnly())
8542 Attrs.push_back(
8543 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8544 else if (isAssumedInaccessibleOrArgMemOnly())
8545 Attrs.push_back(Attribute::getWithMemoryEffects(
8547 }
8548 assert(Attrs.size() <= 1);
8549 }
8550
8551 /// See AbstractAttribute::manifest(...).
8552 ChangeStatus manifest(Attributor &A) override {
8553 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8554 // provide per-location modref information here.
8555 const IRPosition &IRP = getIRPosition();
8556
8557 SmallVector<Attribute, 1> DeducedAttrs;
8558 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8559 if (DeducedAttrs.size() != 1)
8560 return ChangeStatus::UNCHANGED;
8561 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8562
8563 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8564 IRP.getAnchorValue().getContext(), ME));
8565 }
8566
8567 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8568 bool checkForAllAccessesToMemoryKind(
8569 function_ref<bool(const Instruction *, const Value *, AccessKind,
8570 MemoryLocationsKind)>
8571 Pred,
8572 MemoryLocationsKind RequestedMLK) const override {
8573 if (!isValidState())
8574 return false;
8575
8576 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8577 if (AssumedMLK == NO_LOCATIONS)
8578 return true;
8579
8580 unsigned Idx = 0;
8581 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8582 CurMLK *= 2, ++Idx) {
8583 if (CurMLK & RequestedMLK)
8584 continue;
8585
8586 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8587 for (const AccessInfo &AI : *Accesses)
8588 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8589 return false;
8590 }
8591
8592 return true;
8593 }
8594
8595 ChangeStatus indicatePessimisticFixpoint() override {
8596 // If we give up and indicate a pessimistic fixpoint this instruction will
8597 // become an access for all potential access kinds:
8598 // TODO: Add pointers for argmemonly and globals to improve the results of
8599 // checkForAllAccessesToMemoryKind.
8600 bool Changed = false;
8601 MemoryLocationsKind KnownMLK = getKnown();
8602 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8603 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8604 if (!(CurMLK & KnownMLK))
8605 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8606 getAccessKindFromInst(I));
8607 return AAMemoryLocation::indicatePessimisticFixpoint();
8608 }
8609
8610protected:
8611 /// Helper struct to tie together an instruction that has a read or write
8612 /// effect with the pointer it accesses (if any).
8613 struct AccessInfo {
8614
8615 /// The instruction that caused the access.
8616 const Instruction *I;
8617
8618 /// The base pointer that is accessed, or null if unknown.
8619 const Value *Ptr;
8620
8621 /// The kind of access (read/write/read+write).
8623
8624 bool operator==(const AccessInfo &RHS) const {
8625 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8626 }
8627 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8628 if (LHS.I != RHS.I)
8629 return LHS.I < RHS.I;
8630 if (LHS.Ptr != RHS.Ptr)
8631 return LHS.Ptr < RHS.Ptr;
8632 if (LHS.Kind != RHS.Kind)
8633 return LHS.Kind < RHS.Kind;
8634 return false;
8635 }
8636 };
8637
8638 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8639 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8640 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8641 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8642 AccessKind2Accesses;
8643
8644 /// Categorize the pointer arguments of CB that might access memory in
8645 /// AccessedLoc and update the state and access map accordingly.
8646 void
8647 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8648 AAMemoryLocation::StateType &AccessedLocs,
8649 bool &Changed);
8650
8651 /// Return the kind(s) of location that may be accessed by \p V.
8653 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8654
8655 /// Return the access kind as determined by \p I.
8656 AccessKind getAccessKindFromInst(const Instruction *I) {
8657 AccessKind AK = READ_WRITE;
8658 if (I) {
8659 AK = I->mayReadFromMemory() ? READ : NONE;
8660 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8661 }
8662 return AK;
8663 }
8664
8665 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8666 /// an access of kind \p AK to a \p MLK memory location with the access
8667 /// pointer \p Ptr.
8668 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8669 MemoryLocationsKind MLK, const Instruction *I,
8670 const Value *Ptr, bool &Changed,
8671 AccessKind AK = READ_WRITE) {
8672
8673 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8674 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8675 if (!Accesses)
8676 Accesses = new (Allocator) AccessSet();
8677 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8678 if (MLK == NO_UNKOWN_MEM)
8679 MLK = NO_LOCATIONS;
8680 State.removeAssumedBits(MLK);
8681 }
8682
8683 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8684 /// arguments, and update the state and access map accordingly.
8685 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8686 AAMemoryLocation::StateType &State, bool &Changed,
8687 unsigned AccessAS = 0);
8688
8689 /// Used to allocate access sets.
8691};
8692
8693void AAMemoryLocationImpl::categorizePtrValue(
8694 Attributor &A, const Instruction &I, const Value &Ptr,
8695 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8696 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8697 << Ptr << " ["
8698 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8699
8700 auto Pred = [&](Value &Obj) {
8701 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8702 // TODO: recognize the TBAA used for constant accesses.
8703 MemoryLocationsKind MLK = NO_LOCATIONS;
8704
8705 // Filter accesses to constant (GPU) memory if we have an AS at the access
8706 // site or the object is known to actually have the associated AS.
8707 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8708 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8709 isIdentifiedObject(&Obj))) &&
8710 AA::isGPU(*I.getModule()))
8711 return true;
8712
8713 if (isa<UndefValue>(&Obj))
8714 return true;
8715 if (isa<Argument>(&Obj)) {
8716 // TODO: For now we do not treat byval arguments as local copies performed
8717 // on the call edge, though, we should. To make that happen we need to
8718 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8719 // would also allow us to mark functions only accessing byval arguments as
8720 // readnone again, arguably their accesses have no effect outside of the
8721 // function, like accesses to allocas.
8722 MLK = NO_ARGUMENT_MEM;
8723 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8724 // Reading constant memory is not treated as a read "effect" by the
8725 // function attr pass so we won't neither. Constants defined by TBAA are
8726 // similar. (We know we do not write it because it is constant.)
8727 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8728 if (GVar->isConstant())
8729 return true;
8730
8731 if (GV->hasLocalLinkage())
8732 MLK = NO_GLOBAL_INTERNAL_MEM;
8733 else
8734 MLK = NO_GLOBAL_EXTERNAL_MEM;
8735 } else if (isa<ConstantPointerNull>(&Obj) &&
8736 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8737 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8738 return true;
8739 } else if (isa<AllocaInst>(&Obj)) {
8740 MLK = NO_LOCAL_MEM;
8741 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8742 bool IsKnownNoAlias;
8745 IsKnownNoAlias))
8746 MLK = NO_MALLOCED_MEM;
8747 else
8748 MLK = NO_UNKOWN_MEM;
8749 } else {
8750 MLK = NO_UNKOWN_MEM;
8751 }
8752
8753 assert(MLK != NO_LOCATIONS && "No location specified!");
8754 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8755 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8756 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8757 getAccessKindFromInst(&I));
8758
8759 return true;
8760 };
8761
8762 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8764 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8765 LLVM_DEBUG(
8766 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8767 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8768 getAccessKindFromInst(&I));
8769 return;
8770 }
8771
8772 LLVM_DEBUG(
8773 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8774 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8775}
8776
8777void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8778 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8779 bool &Changed) {
8780 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8781
8782 // Skip non-pointer arguments.
8783 const Value *ArgOp = CB.getArgOperand(ArgNo);
8784 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8785 continue;
8786
8787 // Skip readnone arguments.
8788 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8789 const auto *ArgOpMemLocationAA =
8790 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8791
8792 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8793 continue;
8794
8795 // Categorize potentially accessed pointer arguments as if there was an
8796 // access instruction with them as pointer.
8797 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8798 }
8799}
8800
8802AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8803 bool &Changed) {
8804 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8805 << I << "\n");
8806
8807 AAMemoryLocation::StateType AccessedLocs;
8808 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8809
8810 if (auto *CB = dyn_cast<CallBase>(&I)) {
8811
8812 // First check if we assume any memory is access is visible.
8813 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8815 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8816 << " [" << CBMemLocationAA << "]\n");
8817 if (!CBMemLocationAA) {
8818 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8819 Changed, getAccessKindFromInst(&I));
8820 return NO_UNKOWN_MEM;
8821 }
8822
8823 if (CBMemLocationAA->isAssumedReadNone())
8824 return NO_LOCATIONS;
8825
8826 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8827 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8828 Changed, getAccessKindFromInst(&I));
8829 return AccessedLocs.getAssumed();
8830 }
8831
8832 uint32_t CBAssumedNotAccessedLocs =
8833 CBMemLocationAA->getAssumedNotAccessedLocation();
8834
8835 // Set the argmemonly and global bit as we handle them separately below.
8836 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8837 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8838
8839 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8840 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8841 continue;
8842 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8843 getAccessKindFromInst(&I));
8844 }
8845
8846 // Now handle global memory if it might be accessed. This is slightly tricky
8847 // as NO_GLOBAL_MEM has multiple bits set.
8848 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8849 if (HasGlobalAccesses) {
8850 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8851 AccessKind Kind, MemoryLocationsKind MLK) {
8852 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8853 getAccessKindFromInst(&I));
8854 return true;
8855 };
8856 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8857 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8858 return AccessedLocs.getWorstState();
8859 }
8860
8861 LLVM_DEBUG(
8862 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8863 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8864
8865 // Now handle argument memory if it might be accessed.
8866 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8867 if (HasArgAccesses)
8868 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8869
8870 LLVM_DEBUG(
8871 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8872 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8873
8874 return AccessedLocs.getAssumed();
8875 }
8876
8877 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8878 LLVM_DEBUG(
8879 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8880 << I << " [" << *Ptr << "]\n");
8881 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8882 Ptr->getType()->getPointerAddressSpace());
8883 return AccessedLocs.getAssumed();
8884 }
8885
8886 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8887 << I << "\n");
8888 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8889 getAccessKindFromInst(&I));
8890 return AccessedLocs.getAssumed();
8891}
8892
8893/// An AA to represent the memory behavior function attributes.
8894struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8895 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8896 : AAMemoryLocationImpl(IRP, A) {}
8897
8898 /// See AbstractAttribute::updateImpl(Attributor &A).
8899 ChangeStatus updateImpl(Attributor &A) override {
8900
8901 const auto *MemBehaviorAA =
8902 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8903 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8904 if (MemBehaviorAA->isKnownReadNone())
8905 return indicateOptimisticFixpoint();
8907 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8908 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8909 return ChangeStatus::UNCHANGED;
8910 }
8911
8912 // The current assumed state used to determine a change.
8913 auto AssumedState = getAssumed();
8914 bool Changed = false;
8915
8916 auto CheckRWInst = [&](Instruction &I) {
8917 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8918 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8919 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8920 removeAssumedBits(inverseLocation(MLK, false, false));
8921 // Stop once only the valid bit set in the *not assumed location*, thus
8922 // once we don't actually exclude any memory locations in the state.
8923 return getAssumedNotAccessedLocation() != VALID_STATE;
8924 };
8925
8926 bool UsedAssumedInformation = false;
8927 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8928 UsedAssumedInformation))
8929 return indicatePessimisticFixpoint();
8930
8931 Changed |= AssumedState != getAssumed();
8932 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8933 }
8934
8935 /// See AbstractAttribute::trackStatistics()
8936 void trackStatistics() const override {
8937 if (isAssumedReadNone())
8938 STATS_DECLTRACK_FN_ATTR(readnone)
8939 else if (isAssumedArgMemOnly())
8940 STATS_DECLTRACK_FN_ATTR(argmemonly)
8941 else if (isAssumedInaccessibleMemOnly())
8942 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8943 else if (isAssumedInaccessibleOrArgMemOnly())
8944 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8945 }
8946};
8947
8948/// AAMemoryLocation attribute for call sites.
8949struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8950 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8951 : AAMemoryLocationImpl(IRP, A) {}
8952
8953 /// See AbstractAttribute::updateImpl(...).
8954 ChangeStatus updateImpl(Attributor &A) override {
8955 // TODO: Once we have call site specific value information we can provide
8956 // call site specific liveness liveness information and then it makes
8957 // sense to specialize attributes for call sites arguments instead of
8958 // redirecting requests to the callee argument.
8959 Function *F = getAssociatedFunction();
8960 const IRPosition &FnPos = IRPosition::function(*F);
8961 auto *FnAA =
8962 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8963 if (!FnAA)
8964 return indicatePessimisticFixpoint();
8965 bool Changed = false;
8966 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8967 AccessKind Kind, MemoryLocationsKind MLK) {
8968 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8969 getAccessKindFromInst(I));
8970 return true;
8971 };
8972 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8973 return indicatePessimisticFixpoint();
8974 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8975 }
8976
8977 /// See AbstractAttribute::trackStatistics()
8978 void trackStatistics() const override {
8979 if (isAssumedReadNone())
8980 STATS_DECLTRACK_CS_ATTR(readnone)
8981 }
8982};
8983} // namespace
8984
8985/// ------------------ denormal-fp-math Attribute -------------------------
8986
8987namespace {
8988struct AADenormalFPMathImpl : public AADenormalFPMath {
8989 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8990 : AADenormalFPMath(IRP, A) {}
8991
8992 const std::string getAsStr(Attributor *A) const override {
8993 std::string Str("AADenormalFPMath[");
8994 raw_string_ostream OS(Str);
8995
8996 DenormalState Known = getKnown();
8997 if (Known.Mode.isValid())
8998 OS << "denormal-fp-math=" << Known.Mode;
8999 else
9000 OS << "invalid";
9001
9002 if (Known.ModeF32.isValid())
9003 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9004 OS << ']';
9005 return Str;
9006 }
9007};
9008
9009struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9010 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9011 : AADenormalFPMathImpl(IRP, A) {}
9012
9013 void initialize(Attributor &A) override {
9014 const Function *F = getAnchorScope();
9015 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9016
9017 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9018 if (isModeFixed())
9019 indicateFixpoint();
9020 }
9021
9022 ChangeStatus updateImpl(Attributor &A) override {
9023 ChangeStatus Change = ChangeStatus::UNCHANGED;
9024
9025 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9026 Function *Caller = CS.getInstruction()->getFunction();
9027 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9028 << "->" << getAssociatedFunction()->getName() << '\n');
9029
9030 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9031 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9032 if (!CallerInfo)
9033 return false;
9034
9035 Change = Change | clampStateAndIndicateChange(this->getState(),
9036 CallerInfo->getState());
9037 return true;
9038 };
9039
9040 bool AllCallSitesKnown = true;
9041 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9042 return indicatePessimisticFixpoint();
9043
9044 if (Change == ChangeStatus::CHANGED && isModeFixed())
9045 indicateFixpoint();
9046 return Change;
9047 }
9048
9049 ChangeStatus manifest(Attributor &A) override {
9050 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9051
9052 SmallVector<Attribute, 2> AttrToAdd;
9054
9055 // TODO: Change to use DenormalFPEnv everywhere.
9056 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9057
9058 if (KnownEnv == DenormalFPEnv::getDefault()) {
9059 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9060 } else {
9061 AttrToAdd.push_back(Attribute::get(
9062 Ctx, Attribute::DenormalFPEnv,
9063 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9064 }
9065
9066 auto &IRP = getIRPosition();
9067
9068 // TODO: There should be a combined add and remove API.
9069 return A.removeAttrs(IRP, AttrToRemove) |
9070 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9071 }
9072
9073 void trackStatistics() const override {
9074 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9075 }
9076};
9077} // namespace
9078
9079/// ------------------ Value Constant Range Attribute -------------------------
9080
9081namespace {
9082struct AAValueConstantRangeImpl : AAValueConstantRange {
9083 using StateType = IntegerRangeState;
9084 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9085 : AAValueConstantRange(IRP, A) {}
9086
9087 /// See AbstractAttribute::initialize(..).
9088 void initialize(Attributor &A) override {
9089 if (A.hasSimplificationCallback(getIRPosition())) {
9090 indicatePessimisticFixpoint();
9091 return;
9092 }
9093
9094 // Intersect a range given by SCEV.
9095 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9096
9097 // Intersect a range given by LVI.
9098 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9099 }
9100
9101 /// See AbstractAttribute::getAsStr().
9102 const std::string getAsStr(Attributor *A) const override {
9103 std::string Str;
9104 llvm::raw_string_ostream OS(Str);
9105 OS << "range(" << getBitWidth() << ")<";
9106 getKnown().print(OS);
9107 OS << " / ";
9108 getAssumed().print(OS);
9109 OS << ">";
9110 return Str;
9111 }
9112
9113 /// Helper function to get a SCEV expr for the associated value at program
9114 /// point \p I.
9115 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9116 if (!getAnchorScope())
9117 return nullptr;
9118
9119 ScalarEvolution *SE =
9120 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9121 *getAnchorScope());
9122
9123 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9124 *getAnchorScope());
9125
9126 if (!SE || !LI)
9127 return nullptr;
9128
9129 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9130 if (!I)
9131 return S;
9132
9133 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9134 }
9135
9136 /// Helper function to get a range from SCEV for the associated value at
9137 /// program point \p I.
9138 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9139 const Instruction *I = nullptr) const {
9140 if (!getAnchorScope())
9141 return getWorstState(getBitWidth());
9142
9143 ScalarEvolution *SE =
9144 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9145 *getAnchorScope());
9146
9147 const SCEV *S = getSCEV(A, I);
9148 if (!SE || !S)
9149 return getWorstState(getBitWidth());
9150
9151 return SE->getUnsignedRange(S);
9152 }
9153
9154 /// Helper function to get a range from LVI for the associated value at
9155 /// program point \p I.
9156 ConstantRange
9157 getConstantRangeFromLVI(Attributor &A,
9158 const Instruction *CtxI = nullptr) const {
9159 if (!getAnchorScope())
9160 return getWorstState(getBitWidth());
9161
9162 LazyValueInfo *LVI =
9163 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9164 *getAnchorScope());
9165
9166 if (!LVI || !CtxI)
9167 return getWorstState(getBitWidth());
9168 return LVI->getConstantRange(&getAssociatedValue(),
9169 const_cast<Instruction *>(CtxI),
9170 /*UndefAllowed*/ false);
9171 }
9172
9173 /// Return true if \p CtxI is valid for querying outside analyses.
9174 /// This basically makes sure we do not ask intra-procedural analysis
9175 /// about a context in the wrong function or a context that violates
9176 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9177 /// if the original context of this AA is OK or should be considered invalid.
9178 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9179 const Instruction *CtxI,
9180 bool AllowAACtxI) const {
9181 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9182 return false;
9183
9184 // Our context might be in a different function, neither intra-procedural
9185 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9186 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9187 return false;
9188
9189 // If the context is not dominated by the value there are paths to the
9190 // context that do not define the value. This cannot be handled by
9191 // LazyValueInfo so we need to bail.
9192 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9193 InformationCache &InfoCache = A.getInfoCache();
9194 const DominatorTree *DT =
9195 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9196 *I->getFunction());
9197 return DT && DT->dominates(I, CtxI);
9198 }
9199
9200 return true;
9201 }
9202
9203 /// See AAValueConstantRange::getKnownConstantRange(..).
9204 ConstantRange
9205 getKnownConstantRange(Attributor &A,
9206 const Instruction *CtxI = nullptr) const override {
9207 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9208 /* AllowAACtxI */ false))
9209 return getKnown();
9210
9211 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9212 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9213 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9214 }
9215
9216 /// See AAValueConstantRange::getAssumedConstantRange(..).
9217 ConstantRange
9218 getAssumedConstantRange(Attributor &A,
9219 const Instruction *CtxI = nullptr) const override {
9220 // TODO: Make SCEV use Attributor assumption.
9221 // We may be able to bound a variable range via assumptions in
9222 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9223 // evolve to x^2 + x, then we can say that y is in [2, 12].
9224 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9225 /* AllowAACtxI */ false))
9226 return getAssumed();
9227
9228 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9229 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9230 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9231 }
9232
9233 /// Helper function to create MDNode for range metadata.
9234 static MDNode *
9235 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9236 const ConstantRange &AssumedConstantRange) {
9237 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9238 Ty, AssumedConstantRange.getLower())),
9239 ConstantAsMetadata::get(ConstantInt::get(
9240 Ty, AssumedConstantRange.getUpper()))};
9241 return MDNode::get(Ctx, LowAndHigh);
9242 }
9243
9244 /// Return true if \p Assumed is included in ranges from instruction \p I.
9245 static bool isBetterRange(const ConstantRange &Assumed,
9246 const Instruction &I) {
9247 if (Assumed.isFullSet())
9248 return false;
9249
9250 std::optional<ConstantRange> Known;
9251
9252 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9253 Known = CB->getRange();
9254 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9255 // If multiple ranges are annotated in IR, we give up to annotate assumed
9256 // range for now.
9257
9258 // TODO: If there exists a known range which containts assumed range, we
9259 // can say assumed range is better.
9260 if (KnownRanges->getNumOperands() > 2)
9261 return false;
9262
9263 ConstantInt *Lower =
9264 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9265 ConstantInt *Upper =
9266 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9267
9268 Known.emplace(Lower->getValue(), Upper->getValue());
9269 }
9270 return !Known || (*Known != Assumed && Known->contains(Assumed));
9271 }
9272
9273 /// Helper function to set range metadata.
9274 static bool
9275 setRangeMetadataIfisBetterRange(Instruction *I,
9276 const ConstantRange &AssumedConstantRange) {
9277 if (isBetterRange(AssumedConstantRange, *I)) {
9278 I->setMetadata(LLVMContext::MD_range,
9279 getMDNodeForConstantRange(I->getType(), I->getContext(),
9280 AssumedConstantRange));
9281 return true;
9282 }
9283 return false;
9284 }
9285 /// Helper function to set range return attribute.
9286 static bool
9287 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9288 Instruction *I,
9289 const ConstantRange &AssumedConstantRange) {
9290 if (isBetterRange(AssumedConstantRange, *I)) {
9291 A.manifestAttrs(IRP,
9292 Attribute::get(I->getContext(), Attribute::Range,
9293 AssumedConstantRange),
9294 /*ForceReplace*/ true);
9295 return true;
9296 }
9297 return false;
9298 }
9299
9300 /// See AbstractAttribute::manifest()
9301 ChangeStatus manifest(Attributor &A) override {
9302 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9303 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9304 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9305
9306 auto &V = getAssociatedValue();
9307 if (!AssumedConstantRange.isEmptySet() &&
9308 !AssumedConstantRange.isSingleElement()) {
9309 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9310 assert(I == getCtxI() && "Should not annotate an instruction which is "
9311 "not the context instruction");
9312 if (isa<LoadInst>(I))
9313 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9314 Changed = ChangeStatus::CHANGED;
9315 if (isa<CallInst>(I))
9316 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9317 AssumedConstantRange))
9318 Changed = ChangeStatus::CHANGED;
9319 }
9320 }
9321
9322 return Changed;
9323 }
9324};
9325
9326struct AAValueConstantRangeArgument final
9327 : AAArgumentFromCallSiteArguments<
9328 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9329 true /* BridgeCallBaseContext */> {
9330 using Base = AAArgumentFromCallSiteArguments<
9331 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9332 true /* BridgeCallBaseContext */>;
9333 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9334 : Base(IRP, A) {}
9335
9336 /// See AbstractAttribute::trackStatistics()
9337 void trackStatistics() const override {
9338 STATS_DECLTRACK_ARG_ATTR(value_range)
9339 }
9340};
9341
9342struct AAValueConstantRangeReturned
9343 : AAReturnedFromReturnedValues<AAValueConstantRange,
9344 AAValueConstantRangeImpl,
9345 AAValueConstantRangeImpl::StateType,
9346 /* PropagateCallBaseContext */ true> {
9347 using Base =
9348 AAReturnedFromReturnedValues<AAValueConstantRange,
9349 AAValueConstantRangeImpl,
9350 AAValueConstantRangeImpl::StateType,
9351 /* PropagateCallBaseContext */ true>;
9352 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9353 : Base(IRP, A) {}
9354
9355 /// See AbstractAttribute::initialize(...).
9356 void initialize(Attributor &A) override {
9357 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9358 indicatePessimisticFixpoint();
9359 }
9360
9361 /// See AbstractAttribute::trackStatistics()
9362 void trackStatistics() const override {
9363 STATS_DECLTRACK_FNRET_ATTR(value_range)
9364 }
9365};
9366
9367struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9368 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9369 : AAValueConstantRangeImpl(IRP, A) {}
9370
9371 /// See AbstractAttribute::initialize(...).
9372 void initialize(Attributor &A) override {
9373 AAValueConstantRangeImpl::initialize(A);
9374 if (isAtFixpoint())
9375 return;
9376
9377 Value &V = getAssociatedValue();
9378
9379 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9380 unionAssumed(ConstantRange(C->getValue()));
9381 indicateOptimisticFixpoint();
9382 return;
9383 }
9384
9385 if (isa<UndefValue>(&V)) {
9386 // Collapse the undef state to 0.
9387 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9388 indicateOptimisticFixpoint();
9389 return;
9390 }
9391
9392 if (isa<CallBase>(&V))
9393 return;
9394
9395 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9396 return;
9397
9398 // If it is a load instruction with range metadata, use it.
9399 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9400 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9401 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9402 return;
9403 }
9404
9405 // We can work with PHI and select instruction as we traverse their operands
9406 // during update.
9407 if (isa<SelectInst>(V) || isa<PHINode>(V))
9408 return;
9409
9410 // Otherwise we give up.
9411 indicatePessimisticFixpoint();
9412
9413 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9414 << getAssociatedValue() << "\n");
9415 }
9416
9417 bool calculateBinaryOperator(
9418 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9419 const Instruction *CtxI,
9420 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9421 Value *LHS = BinOp->getOperand(0);
9422 Value *RHS = BinOp->getOperand(1);
9423
9424 // Simplify the operands first.
9425 bool UsedAssumedInformation = false;
9426 const auto &SimplifiedLHS = A.getAssumedSimplified(
9427 IRPosition::value(*LHS, getCallBaseContext()), *this,
9428 UsedAssumedInformation, AA::Interprocedural);
9429 if (!SimplifiedLHS.has_value())
9430 return true;
9431 if (!*SimplifiedLHS)
9432 return false;
9433 LHS = *SimplifiedLHS;
9434
9435 const auto &SimplifiedRHS = A.getAssumedSimplified(
9436 IRPosition::value(*RHS, getCallBaseContext()), *this,
9437 UsedAssumedInformation, AA::Interprocedural);
9438 if (!SimplifiedRHS.has_value())
9439 return true;
9440 if (!*SimplifiedRHS)
9441 return false;
9442 RHS = *SimplifiedRHS;
9443
9444 // TODO: Allow non integers as well.
9445 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9446 return false;
9447
9448 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9449 *this, IRPosition::value(*LHS, getCallBaseContext()),
9450 DepClassTy::REQUIRED);
9451 if (!LHSAA)
9452 return false;
9453 QuerriedAAs.push_back(LHSAA);
9454 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9455
9456 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9457 *this, IRPosition::value(*RHS, getCallBaseContext()),
9458 DepClassTy::REQUIRED);
9459 if (!RHSAA)
9460 return false;
9461 QuerriedAAs.push_back(RHSAA);
9462 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9463
9464 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9465
9466 T.unionAssumed(AssumedRange);
9467
9468 // TODO: Track a known state too.
9469
9470 return T.isValidState();
9471 }
9472
9473 bool calculateCastInst(
9474 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9475 const Instruction *CtxI,
9476 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9477 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9478 // TODO: Allow non integers as well.
9479 Value *OpV = CastI->getOperand(0);
9480
9481 // Simplify the operand first.
9482 bool UsedAssumedInformation = false;
9483 const auto &SimplifiedOpV = A.getAssumedSimplified(
9484 IRPosition::value(*OpV, getCallBaseContext()), *this,
9485 UsedAssumedInformation, AA::Interprocedural);
9486 if (!SimplifiedOpV.has_value())
9487 return true;
9488 if (!*SimplifiedOpV)
9489 return false;
9490 OpV = *SimplifiedOpV;
9491
9492 if (!OpV->getType()->isIntegerTy())
9493 return false;
9494
9495 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9496 *this, IRPosition::value(*OpV, getCallBaseContext()),
9497 DepClassTy::REQUIRED);
9498 if (!OpAA)
9499 return false;
9500 QuerriedAAs.push_back(OpAA);
9501 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9502 getState().getBitWidth()));
9503 return T.isValidState();
9504 }
9505
9506 bool
9507 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9508 const Instruction *CtxI,
9509 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9510 Value *LHS = CmpI->getOperand(0);
9511 Value *RHS = CmpI->getOperand(1);
9512
9513 // Simplify the operands first.
9514 bool UsedAssumedInformation = false;
9515 const auto &SimplifiedLHS = A.getAssumedSimplified(
9516 IRPosition::value(*LHS, getCallBaseContext()), *this,
9517 UsedAssumedInformation, AA::Interprocedural);
9518 if (!SimplifiedLHS.has_value())
9519 return true;
9520 if (!*SimplifiedLHS)
9521 return false;
9522 LHS = *SimplifiedLHS;
9523
9524 const auto &SimplifiedRHS = A.getAssumedSimplified(
9525 IRPosition::value(*RHS, getCallBaseContext()), *this,
9526 UsedAssumedInformation, AA::Interprocedural);
9527 if (!SimplifiedRHS.has_value())
9528 return true;
9529 if (!*SimplifiedRHS)
9530 return false;
9531 RHS = *SimplifiedRHS;
9532
9533 // TODO: Allow non integers as well.
9534 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9535 return false;
9536
9537 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9538 *this, IRPosition::value(*LHS, getCallBaseContext()),
9539 DepClassTy::REQUIRED);
9540 if (!LHSAA)
9541 return false;
9542 QuerriedAAs.push_back(LHSAA);
9543 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9544 *this, IRPosition::value(*RHS, getCallBaseContext()),
9545 DepClassTy::REQUIRED);
9546 if (!RHSAA)
9547 return false;
9548 QuerriedAAs.push_back(RHSAA);
9549 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9550 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9551
9552 // If one of them is empty set, we can't decide.
9553 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9554 return true;
9555
9556 bool MustTrue = false, MustFalse = false;
9557
9558 auto AllowedRegion =
9560
9561 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9562 MustFalse = true;
9563
9564 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9565 MustTrue = true;
9566
9567 assert((!MustTrue || !MustFalse) &&
9568 "Either MustTrue or MustFalse should be false!");
9569
9570 if (MustTrue)
9571 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9572 else if (MustFalse)
9573 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9574 else
9575 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9576
9577 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9578 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9579 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9580 << *RHSAA);
9581
9582 // TODO: Track a known state too.
9583 return T.isValidState();
9584 }
9585
9586 /// See AbstractAttribute::updateImpl(...).
9587 ChangeStatus updateImpl(Attributor &A) override {
9588
9589 IntegerRangeState T(getBitWidth());
9590 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9592 if (!I || isa<CallBase>(I)) {
9593
9594 // Simplify the operand first.
9595 bool UsedAssumedInformation = false;
9596 const auto &SimplifiedOpV = A.getAssumedSimplified(
9597 IRPosition::value(V, getCallBaseContext()), *this,
9598 UsedAssumedInformation, AA::Interprocedural);
9599 if (!SimplifiedOpV.has_value())
9600 return true;
9601 if (!*SimplifiedOpV)
9602 return false;
9603 Value *VPtr = *SimplifiedOpV;
9604
9605 // If the value is not instruction, we query AA to Attributor.
9606 const auto *AA = A.getAAFor<AAValueConstantRange>(
9607 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9608 DepClassTy::REQUIRED);
9609
9610 // Clamp operator is not used to utilize a program point CtxI.
9611 if (AA)
9612 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9613 else
9614 return false;
9615
9616 return T.isValidState();
9617 }
9618
9620 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9621 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9622 return false;
9623 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9624 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9625 return false;
9626 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9627 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9628 return false;
9629 } else {
9630 // Give up with other instructions.
9631 // TODO: Add other instructions
9632
9633 T.indicatePessimisticFixpoint();
9634 return false;
9635 }
9636
9637 // Catch circular reasoning in a pessimistic way for now.
9638 // TODO: Check how the range evolves and if we stripped anything, see also
9639 // AADereferenceable or AAAlign for similar situations.
9640 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9641 if (QueriedAA != this)
9642 continue;
9643 // If we are in a stady state we do not need to worry.
9644 if (T.getAssumed() == getState().getAssumed())
9645 continue;
9646 T.indicatePessimisticFixpoint();
9647 }
9648
9649 return T.isValidState();
9650 };
9651
9652 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9653 return indicatePessimisticFixpoint();
9654
9655 // Ensure that long def-use chains can't cause circular reasoning either by
9656 // introducing a cutoff below.
9657 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9658 return ChangeStatus::UNCHANGED;
9659 if (++NumChanges > MaxNumChanges) {
9660 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9661 << " but only " << MaxNumChanges
9662 << " are allowed to avoid cyclic reasoning.");
9663 return indicatePessimisticFixpoint();
9664 }
9665 return ChangeStatus::CHANGED;
9666 }
9667
9668 /// See AbstractAttribute::trackStatistics()
9669 void trackStatistics() const override {
9671 }
9672
9673 /// Tracker to bail after too many widening steps of the constant range.
9674 int NumChanges = 0;
9675
9676 /// Upper bound for the number of allowed changes (=widening steps) for the
9677 /// constant range before we give up.
9678 static constexpr int MaxNumChanges = 5;
9679};
9680
9681struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9682 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9683 : AAValueConstantRangeImpl(IRP, A) {}
9684
9685 /// See AbstractAttribute::initialize(...).
9686 ChangeStatus updateImpl(Attributor &A) override {
9687 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9688 "not be called");
9689 }
9690
9691 /// See AbstractAttribute::trackStatistics()
9692 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9693};
9694
9695struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9696 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9697 : AAValueConstantRangeFunction(IRP, A) {}
9698
9699 /// See AbstractAttribute::trackStatistics()
9700 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9701};
9702
9703struct AAValueConstantRangeCallSiteReturned
9704 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9705 AAValueConstantRangeImpl::StateType,
9706 /* IntroduceCallBaseContext */ true> {
9707 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9708 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9709 AAValueConstantRangeImpl::StateType,
9710 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9711
9712 /// See AbstractAttribute::initialize(...).
9713 void initialize(Attributor &A) override {
9714 // If it is a call instruction with range attribute, use the range.
9715 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9716 if (std::optional<ConstantRange> Range = CI->getRange())
9717 intersectKnown(*Range);
9718 }
9719
9720 AAValueConstantRangeImpl::initialize(A);
9721 }
9722
9723 /// See AbstractAttribute::trackStatistics()
9724 void trackStatistics() const override {
9725 STATS_DECLTRACK_CSRET_ATTR(value_range)
9726 }
9727};
9728struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9729 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9730 : AAValueConstantRangeFloating(IRP, A) {}
9731
9732 /// See AbstractAttribute::manifest()
9733 ChangeStatus manifest(Attributor &A) override {
9734 return ChangeStatus::UNCHANGED;
9735 }
9736
9737 /// See AbstractAttribute::trackStatistics()
9738 void trackStatistics() const override {
9739 STATS_DECLTRACK_CSARG_ATTR(value_range)
9740 }
9741};
9742} // namespace
9743
9744/// ------------------ Potential Values Attribute -------------------------
9745
9746namespace {
9747struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9748 using StateType = PotentialConstantIntValuesState;
9749
9750 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9751 : AAPotentialConstantValues(IRP, A) {}
9752
9753 /// See AbstractAttribute::initialize(..).
9754 void initialize(Attributor &A) override {
9755 if (A.hasSimplificationCallback(getIRPosition()))
9756 indicatePessimisticFixpoint();
9757 else
9758 AAPotentialConstantValues::initialize(A);
9759 }
9760
9761 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9762 bool &ContainsUndef, bool ForSelf) {
9764 bool UsedAssumedInformation = false;
9765 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9766 UsedAssumedInformation)) {
9767 // Avoid recursion when the caller is computing constant values for this
9768 // IRP itself.
9769 if (ForSelf)
9770 return false;
9771 if (!IRP.getAssociatedType()->isIntegerTy())
9772 return false;
9773 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9774 *this, IRP, DepClassTy::REQUIRED);
9775 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9776 return false;
9777 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9778 S = PotentialValuesAA->getState().getAssumedSet();
9779 return true;
9780 }
9781
9782 // Copy all the constant values, except UndefValue. ContainsUndef is true
9783 // iff Values contains only UndefValue instances. If there are other known
9784 // constants, then UndefValue is dropped.
9785 ContainsUndef = false;
9786 for (auto &It : Values) {
9787 if (isa<UndefValue>(It.getValue())) {
9788 ContainsUndef = true;
9789 continue;
9790 }
9791 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9792 if (!CI)
9793 return false;
9794 S.insert(CI->getValue());
9795 }
9796 ContainsUndef &= S.empty();
9797
9798 return true;
9799 }
9800
9801 /// See AbstractAttribute::getAsStr().
9802 const std::string getAsStr(Attributor *A) const override {
9803 std::string Str;
9804 llvm::raw_string_ostream OS(Str);
9805 OS << getState();
9806 return Str;
9807 }
9808
9809 /// See AbstractAttribute::updateImpl(...).
9810 ChangeStatus updateImpl(Attributor &A) override {
9811 return indicatePessimisticFixpoint();
9812 }
9813};
9814
9815struct AAPotentialConstantValuesArgument final
9816 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9817 AAPotentialConstantValuesImpl,
9818 PotentialConstantIntValuesState> {
9819 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9820 AAPotentialConstantValuesImpl,
9822 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9823 : Base(IRP, A) {}
9824
9825 /// See AbstractAttribute::trackStatistics()
9826 void trackStatistics() const override {
9827 STATS_DECLTRACK_ARG_ATTR(potential_values)
9828 }
9829};
9830
9831struct AAPotentialConstantValuesReturned
9832 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9833 AAPotentialConstantValuesImpl> {
9834 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9835 AAPotentialConstantValuesImpl>;
9836 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9837 : Base(IRP, A) {}
9838
9839 void initialize(Attributor &A) override {
9840 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9841 indicatePessimisticFixpoint();
9842 Base::initialize(A);
9843 }
9844
9845 /// See AbstractAttribute::trackStatistics()
9846 void trackStatistics() const override {
9847 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9848 }
9849};
9850
9851struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9852 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9853 : AAPotentialConstantValuesImpl(IRP, A) {}
9854
9855 /// See AbstractAttribute::initialize(..).
9856 void initialize(Attributor &A) override {
9857 AAPotentialConstantValuesImpl::initialize(A);
9858 if (isAtFixpoint())
9859 return;
9860
9861 Value &V = getAssociatedValue();
9862
9863 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9864 unionAssumed(C->getValue());
9865 indicateOptimisticFixpoint();
9866 return;
9867 }
9868
9869 if (isa<UndefValue>(&V)) {
9870 unionAssumedWithUndef();
9871 indicateOptimisticFixpoint();
9872 return;
9873 }
9874
9875 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9876 return;
9877
9878 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9879 return;
9880
9881 indicatePessimisticFixpoint();
9882
9883 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9884 << getAssociatedValue() << "\n");
9885 }
9886
9887 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9888 const APInt &RHS) {
9889 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9890 }
9891
9892 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9893 uint32_t ResultBitWidth) {
9894 Instruction::CastOps CastOp = CI->getOpcode();
9895 switch (CastOp) {
9896 default:
9897 llvm_unreachable("unsupported or not integer cast");
9898 case Instruction::Trunc:
9899 return Src.trunc(ResultBitWidth);
9900 case Instruction::SExt:
9901 return Src.sext(ResultBitWidth);
9902 case Instruction::ZExt:
9903 return Src.zext(ResultBitWidth);
9904 case Instruction::BitCast:
9905 return Src;
9906 }
9907 }
9908
9909 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9910 const APInt &LHS, const APInt &RHS,
9911 bool &SkipOperation, bool &Unsupported) {
9912 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9913 // Unsupported is set to true when the binary operator is not supported.
9914 // SkipOperation is set to true when UB occur with the given operand pair
9915 // (LHS, RHS).
9916 // TODO: we should look at nsw and nuw keywords to handle operations
9917 // that create poison or undef value.
9918 switch (BinOpcode) {
9919 default:
9920 Unsupported = true;
9921 return LHS;
9922 case Instruction::Add:
9923 return LHS + RHS;
9924 case Instruction::Sub:
9925 return LHS - RHS;
9926 case Instruction::Mul:
9927 return LHS * RHS;
9928 case Instruction::UDiv:
9929 if (RHS.isZero()) {
9930 SkipOperation = true;
9931 return LHS;
9932 }
9933 return LHS.udiv(RHS);
9934 case Instruction::SDiv:
9935 if (RHS.isZero()) {
9936 SkipOperation = true;
9937 return LHS;
9938 }
9939 return LHS.sdiv(RHS);
9940 case Instruction::URem:
9941 if (RHS.isZero()) {
9942 SkipOperation = true;
9943 return LHS;
9944 }
9945 return LHS.urem(RHS);
9946 case Instruction::SRem:
9947 if (RHS.isZero()) {
9948 SkipOperation = true;
9949 return LHS;
9950 }
9951 return LHS.srem(RHS);
9952 case Instruction::Shl:
9953 return LHS.shl(RHS);
9954 case Instruction::LShr:
9955 return LHS.lshr(RHS);
9956 case Instruction::AShr:
9957 return LHS.ashr(RHS);
9958 case Instruction::And:
9959 return LHS & RHS;
9960 case Instruction::Or:
9961 return LHS | RHS;
9962 case Instruction::Xor:
9963 return LHS ^ RHS;
9964 }
9965 }
9966
9967 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9968 const APInt &LHS, const APInt &RHS) {
9969 bool SkipOperation = false;
9970 bool Unsupported = false;
9971 APInt Result =
9972 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9973 if (Unsupported)
9974 return false;
9975 // If SkipOperation is true, we can ignore this operand pair (L, R).
9976 if (!SkipOperation)
9977 unionAssumed(Result);
9978 return isValidState();
9979 }
9980
9981 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9982 auto AssumedBefore = getAssumed();
9983 Value *LHS = ICI->getOperand(0);
9984 Value *RHS = ICI->getOperand(1);
9985
9986 bool LHSContainsUndef = false, RHSContainsUndef = false;
9987 SetTy LHSAAPVS, RHSAAPVS;
9988 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9989 LHSContainsUndef, /* ForSelf */ false) ||
9990 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9991 RHSContainsUndef, /* ForSelf */ false))
9992 return indicatePessimisticFixpoint();
9993
9994 // TODO: make use of undef flag to limit potential values aggressively.
9995 bool MaybeTrue = false, MaybeFalse = false;
9996 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9997 if (LHSContainsUndef && RHSContainsUndef) {
9998 // The result of any comparison between undefs can be soundly replaced
9999 // with undef.
10000 unionAssumedWithUndef();
10001 } else if (LHSContainsUndef) {
10002 for (const APInt &R : RHSAAPVS) {
10003 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10004 MaybeTrue |= CmpResult;
10005 MaybeFalse |= !CmpResult;
10006 if (MaybeTrue & MaybeFalse)
10007 return indicatePessimisticFixpoint();
10008 }
10009 } else if (RHSContainsUndef) {
10010 for (const APInt &L : LHSAAPVS) {
10011 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10012 MaybeTrue |= CmpResult;
10013 MaybeFalse |= !CmpResult;
10014 if (MaybeTrue & MaybeFalse)
10015 return indicatePessimisticFixpoint();
10016 }
10017 } else {
10018 for (const APInt &L : LHSAAPVS) {
10019 for (const APInt &R : RHSAAPVS) {
10020 bool CmpResult = calculateICmpInst(ICI, L, R);
10021 MaybeTrue |= CmpResult;
10022 MaybeFalse |= !CmpResult;
10023 if (MaybeTrue & MaybeFalse)
10024 return indicatePessimisticFixpoint();
10025 }
10026 }
10027 }
10028 if (MaybeTrue)
10029 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10030 if (MaybeFalse)
10031 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10032 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10033 : ChangeStatus::CHANGED;
10034 }
10035
10036 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10037 auto AssumedBefore = getAssumed();
10038 Value *LHS = SI->getTrueValue();
10039 Value *RHS = SI->getFalseValue();
10040
10041 bool UsedAssumedInformation = false;
10042 std::optional<Constant *> C = A.getAssumedConstant(
10043 *SI->getCondition(), *this, UsedAssumedInformation);
10044
10045 // Check if we only need one operand.
10046 bool OnlyLeft = false, OnlyRight = false;
10047 if (C && *C && (*C)->isOneValue())
10048 OnlyLeft = true;
10049 else if (C && *C && (*C)->isNullValue())
10050 OnlyRight = true;
10051
10052 bool LHSContainsUndef = false, RHSContainsUndef = false;
10053 SetTy LHSAAPVS, RHSAAPVS;
10054 if (!OnlyRight &&
10055 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10056 LHSContainsUndef, /* ForSelf */ false))
10057 return indicatePessimisticFixpoint();
10058
10059 if (!OnlyLeft &&
10060 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10061 RHSContainsUndef, /* ForSelf */ false))
10062 return indicatePessimisticFixpoint();
10063
10064 if (OnlyLeft || OnlyRight) {
10065 // select (true/false), lhs, rhs
10066 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10067 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10068
10069 if (Undef)
10070 unionAssumedWithUndef();
10071 else {
10072 for (const auto &It : *OpAA)
10073 unionAssumed(It);
10074 }
10075
10076 } else if (LHSContainsUndef && RHSContainsUndef) {
10077 // select i1 *, undef , undef => undef
10078 unionAssumedWithUndef();
10079 } else {
10080 for (const auto &It : LHSAAPVS)
10081 unionAssumed(It);
10082 for (const auto &It : RHSAAPVS)
10083 unionAssumed(It);
10084 }
10085 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10086 : ChangeStatus::CHANGED;
10087 }
10088
10089 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10090 auto AssumedBefore = getAssumed();
10091 if (!CI->isIntegerCast())
10092 return indicatePessimisticFixpoint();
10093 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10094 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10095 Value *Src = CI->getOperand(0);
10096
10097 bool SrcContainsUndef = false;
10098 SetTy SrcPVS;
10099 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10100 SrcContainsUndef, /* ForSelf */ false))
10101 return indicatePessimisticFixpoint();
10102
10103 if (SrcContainsUndef)
10104 unionAssumedWithUndef();
10105 else {
10106 for (const APInt &S : SrcPVS) {
10107 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10108 unionAssumed(T);
10109 }
10110 }
10111 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10112 : ChangeStatus::CHANGED;
10113 }
10114
10115 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10116 auto AssumedBefore = getAssumed();
10117 Value *LHS = BinOp->getOperand(0);
10118 Value *RHS = BinOp->getOperand(1);
10119
10120 bool LHSContainsUndef = false, RHSContainsUndef = false;
10121 SetTy LHSAAPVS, RHSAAPVS;
10122 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10123 LHSContainsUndef, /* ForSelf */ false) ||
10124 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10125 RHSContainsUndef, /* ForSelf */ false))
10126 return indicatePessimisticFixpoint();
10127
10128 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10129
10130 // TODO: make use of undef flag to limit potential values aggressively.
10131 if (LHSContainsUndef && RHSContainsUndef) {
10132 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10133 return indicatePessimisticFixpoint();
10134 } else if (LHSContainsUndef) {
10135 for (const APInt &R : RHSAAPVS) {
10136 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10137 return indicatePessimisticFixpoint();
10138 }
10139 } else if (RHSContainsUndef) {
10140 for (const APInt &L : LHSAAPVS) {
10141 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10142 return indicatePessimisticFixpoint();
10143 }
10144 } else {
10145 for (const APInt &L : LHSAAPVS) {
10146 for (const APInt &R : RHSAAPVS) {
10147 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10148 return indicatePessimisticFixpoint();
10149 }
10150 }
10151 }
10152 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10153 : ChangeStatus::CHANGED;
10154 }
10155
10156 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10157 auto AssumedBefore = getAssumed();
10158 SetTy Incoming;
10159 bool ContainsUndef;
10160 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10161 ContainsUndef, /* ForSelf */ true))
10162 return indicatePessimisticFixpoint();
10163 if (ContainsUndef) {
10164 unionAssumedWithUndef();
10165 } else {
10166 for (const auto &It : Incoming)
10167 unionAssumed(It);
10168 }
10169 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10170 : ChangeStatus::CHANGED;
10171 }
10172
10173 /// See AbstractAttribute::updateImpl(...).
10174 ChangeStatus updateImpl(Attributor &A) override {
10175 Value &V = getAssociatedValue();
10177
10178 if (auto *ICI = dyn_cast<ICmpInst>(I))
10179 return updateWithICmpInst(A, ICI);
10180
10181 if (auto *SI = dyn_cast<SelectInst>(I))
10182 return updateWithSelectInst(A, SI);
10183
10184 if (auto *CI = dyn_cast<CastInst>(I))
10185 return updateWithCastInst(A, CI);
10186
10187 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10188 return updateWithBinaryOperator(A, BinOp);
10189
10190 if (isa<PHINode>(I) || isa<LoadInst>(I))
10191 return updateWithInstruction(A, I);
10192
10193 return indicatePessimisticFixpoint();
10194 }
10195
10196 /// See AbstractAttribute::trackStatistics()
10197 void trackStatistics() const override {
10198 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10199 }
10200};
10201
10202struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10203 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10204 : AAPotentialConstantValuesImpl(IRP, A) {}
10205
10206 /// See AbstractAttribute::initialize(...).
10207 ChangeStatus updateImpl(Attributor &A) override {
10209 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10210 "not be called");
10211 }
10212
10213 /// See AbstractAttribute::trackStatistics()
10214 void trackStatistics() const override {
10215 STATS_DECLTRACK_FN_ATTR(potential_values)
10216 }
10217};
10218
10219struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10220 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10221 : AAPotentialConstantValuesFunction(IRP, A) {}
10222
10223 /// See AbstractAttribute::trackStatistics()
10224 void trackStatistics() const override {
10225 STATS_DECLTRACK_CS_ATTR(potential_values)
10226 }
10227};
10228
10229struct AAPotentialConstantValuesCallSiteReturned
10230 : AACalleeToCallSite<AAPotentialConstantValues,
10231 AAPotentialConstantValuesImpl> {
10232 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10233 Attributor &A)
10234 : AACalleeToCallSite<AAPotentialConstantValues,
10235 AAPotentialConstantValuesImpl>(IRP, A) {}
10236
10237 /// See AbstractAttribute::trackStatistics()
10238 void trackStatistics() const override {
10239 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10240 }
10241};
10242
10243struct AAPotentialConstantValuesCallSiteArgument
10244 : AAPotentialConstantValuesFloating {
10245 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10246 Attributor &A)
10247 : AAPotentialConstantValuesFloating(IRP, A) {}
10248
10249 /// See AbstractAttribute::initialize(..).
10250 void initialize(Attributor &A) override {
10251 AAPotentialConstantValuesImpl::initialize(A);
10252 if (isAtFixpoint())
10253 return;
10254
10255 Value &V = getAssociatedValue();
10256
10257 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10258 unionAssumed(C->getValue());
10259 indicateOptimisticFixpoint();
10260 return;
10261 }
10262
10263 if (isa<UndefValue>(&V)) {
10264 unionAssumedWithUndef();
10265 indicateOptimisticFixpoint();
10266 return;
10267 }
10268 }
10269
10270 /// See AbstractAttribute::updateImpl(...).
10271 ChangeStatus updateImpl(Attributor &A) override {
10272 Value &V = getAssociatedValue();
10273 auto AssumedBefore = getAssumed();
10274 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10275 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10276 if (!AA)
10277 return indicatePessimisticFixpoint();
10278 const auto &S = AA->getAssumed();
10279 unionAssumed(S);
10280 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10281 : ChangeStatus::CHANGED;
10282 }
10283
10284 /// See AbstractAttribute::trackStatistics()
10285 void trackStatistics() const override {
10286 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10287 }
10288};
10289} // namespace
10290
10291/// ------------------------ NoUndef Attribute ---------------------------------
10293 Attribute::AttrKind ImpliedAttributeKind,
10294 bool IgnoreSubsumingPositions) {
10295 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10296 "Unexpected attribute kind");
10297 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10298 Attribute::NoUndef))
10299 return true;
10300
10301 Value &Val = IRP.getAssociatedValue();
10304 LLVMContext &Ctx = Val.getContext();
10305 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10306 return true;
10307 }
10308
10309 return false;
10310}
10311
10312namespace {
10313struct AANoUndefImpl : AANoUndef {
10314 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10315
10316 /// See AbstractAttribute::initialize(...).
10317 void initialize(Attributor &A) override {
10318 Value &V = getAssociatedValue();
10319 if (isa<UndefValue>(V))
10320 indicatePessimisticFixpoint();
10321 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10322 }
10323
10324 /// See followUsesInMBEC
10325 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10326 AANoUndef::StateType &State) {
10327 const Value *UseV = U->get();
10328 const DominatorTree *DT = nullptr;
10329 AssumptionCache *AC = nullptr;
10330 InformationCache &InfoCache = A.getInfoCache();
10331 if (Function *F = getAnchorScope()) {
10332 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10333 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10334 }
10335 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10336 bool TrackUse = false;
10337 // Track use for instructions which must produce undef or poison bits when
10338 // at least one operand contains such bits.
10340 TrackUse = true;
10341 return TrackUse;
10342 }
10343
10344 /// See AbstractAttribute::getAsStr().
10345 const std::string getAsStr(Attributor *A) const override {
10346 return getAssumed() ? "noundef" : "may-undef-or-poison";
10347 }
10348
10349 ChangeStatus manifest(Attributor &A) override {
10350 // We don't manifest noundef attribute for dead positions because the
10351 // associated values with dead positions would be replaced with undef
10352 // values.
10353 bool UsedAssumedInformation = false;
10354 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10355 UsedAssumedInformation))
10356 return ChangeStatus::UNCHANGED;
10357 // A position whose simplified value does not have any value is
10358 // considered to be dead. We don't manifest noundef in such positions for
10359 // the same reason above.
10360 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10362 .has_value())
10363 return ChangeStatus::UNCHANGED;
10364 return AANoUndef::manifest(A);
10365 }
10366};
10367
10368struct AANoUndefFloating : public AANoUndefImpl {
10369 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10370 : AANoUndefImpl(IRP, A) {}
10371
10372 /// See AbstractAttribute::initialize(...).
10373 void initialize(Attributor &A) override {
10374 AANoUndefImpl::initialize(A);
10375 if (!getState().isAtFixpoint() && getAnchorScope() &&
10376 !getAnchorScope()->isDeclaration())
10377 if (Instruction *CtxI = getCtxI())
10378 followUsesInMBEC(*this, A, getState(), *CtxI);
10379 }
10380
10381 /// See AbstractAttribute::updateImpl(...).
10382 ChangeStatus updateImpl(Attributor &A) override {
10383 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10384 bool IsKnownNoUndef;
10386 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10387 };
10388
10389 bool Stripped;
10390 bool UsedAssumedInformation = false;
10391 Value *AssociatedValue = &getAssociatedValue();
10393 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10394 AA::AnyScope, UsedAssumedInformation))
10395 Stripped = false;
10396 else
10397 Stripped =
10398 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10399
10400 if (!Stripped) {
10401 // If we haven't stripped anything we might still be able to use a
10402 // different AA, but only if the IRP changes. Effectively when we
10403 // interpret this not as a call site value but as a floating/argument
10404 // value.
10405 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10406 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10407 return indicatePessimisticFixpoint();
10408 return ChangeStatus::UNCHANGED;
10409 }
10410
10411 for (const auto &VAC : Values)
10412 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10413 return indicatePessimisticFixpoint();
10414
10415 return ChangeStatus::UNCHANGED;
10416 }
10417
10418 /// See AbstractAttribute::trackStatistics()
10419 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10420};
10421
10422struct AANoUndefReturned final
10423 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10424 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10425 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10426
10427 /// See AbstractAttribute::trackStatistics()
10428 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10429};
10430
10431struct AANoUndefArgument final
10432 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10433 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10434 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10435
10436 /// See AbstractAttribute::trackStatistics()
10437 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10438};
10439
10440struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10441 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10442 : AANoUndefFloating(IRP, A) {}
10443
10444 /// See AbstractAttribute::trackStatistics()
10445 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10446};
10447
10448struct AANoUndefCallSiteReturned final
10449 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10450 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10451 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10452
10453 /// See AbstractAttribute::trackStatistics()
10454 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10455};
10456
10457/// ------------------------ NoFPClass Attribute -------------------------------
10458
10459struct AANoFPClassImpl : AANoFPClass {
10460 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10461
10462 void initialize(Attributor &A) override {
10463 const IRPosition &IRP = getIRPosition();
10464
10465 Value &V = IRP.getAssociatedValue();
10466 if (isa<UndefValue>(V)) {
10467 indicateOptimisticFixpoint();
10468 return;
10469 }
10470
10472 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10473 for (const auto &Attr : Attrs) {
10474 addKnownBits(Attr.getNoFPClass());
10475 }
10476
10477 Instruction *CtxI = getCtxI();
10478
10479 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10480 const DataLayout &DL = A.getDataLayout();
10481 InformationCache &InfoCache = A.getInfoCache();
10482
10483 const DominatorTree *DT = nullptr;
10484 AssumptionCache *AC = nullptr;
10485 const TargetLibraryInfo *TLI = nullptr;
10486 Function *F = getAnchorScope();
10487 if (F) {
10488 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10489 if (!F->isDeclaration()) {
10490 DT =
10491 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10492 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10493 }
10494 }
10495
10496 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10497
10498 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10499 addKnownBits(~KnownFPClass.KnownFPClasses);
10500 }
10501
10502 if (CtxI)
10503 followUsesInMBEC(*this, A, getState(), *CtxI);
10504 }
10505
10506 /// See followUsesInMBEC
10507 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10508 AANoFPClass::StateType &State) {
10509 // TODO: Determine what instructions can be looked through.
10510 auto *CB = dyn_cast<CallBase>(I);
10511 if (!CB)
10512 return false;
10513
10514 if (!CB->isArgOperand(U))
10515 return false;
10516
10517 unsigned ArgNo = CB->getArgOperandNo(U);
10518 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10519 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10520 State.addKnownBits(NoFPAA->getState().getKnown());
10521 return false;
10522 }
10523
10524 const std::string getAsStr(Attributor *A) const override {
10525 std::string Result = "nofpclass";
10526 raw_string_ostream OS(Result);
10527 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10528 return Result;
10529 }
10530
10531 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10532 SmallVectorImpl<Attribute> &Attrs) const override {
10533 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10534 }
10535};
10536
10537struct AANoFPClassFloating : public AANoFPClassImpl {
10538 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10539 : AANoFPClassImpl(IRP, A) {}
10540
10541 /// See AbstractAttribute::updateImpl(...).
10542 ChangeStatus updateImpl(Attributor &A) override {
10544 bool UsedAssumedInformation = false;
10545 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10546 AA::AnyScope, UsedAssumedInformation)) {
10547 Values.push_back({getAssociatedValue(), getCtxI()});
10548 }
10549
10550 StateType T;
10551 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10552 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10553 DepClassTy::REQUIRED);
10554 if (!AA || this == AA) {
10555 T.indicatePessimisticFixpoint();
10556 } else {
10557 const AANoFPClass::StateType &S =
10558 static_cast<const AANoFPClass::StateType &>(AA->getState());
10559 T ^= S;
10560 }
10561 return T.isValidState();
10562 };
10563
10564 for (const auto &VAC : Values)
10565 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10566 return indicatePessimisticFixpoint();
10567
10568 return clampStateAndIndicateChange(getState(), T);
10569 }
10570
10571 /// See AbstractAttribute::trackStatistics()
10572 void trackStatistics() const override {
10574 }
10575};
10576
10577struct AANoFPClassReturned final
10578 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10579 AANoFPClassImpl::StateType, false,
10580 Attribute::None, false> {
10581 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10582 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10583 AANoFPClassImpl::StateType, false,
10584 Attribute::None, false>(IRP, A) {}
10585
10586 /// See AbstractAttribute::trackStatistics()
10587 void trackStatistics() const override {
10589 }
10590};
10591
10592struct AANoFPClassArgument final
10593 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10594 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10595 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10596
10597 /// See AbstractAttribute::trackStatistics()
10598 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10599};
10600
10601struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10602 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10603 : AANoFPClassFloating(IRP, A) {}
10604
10605 /// See AbstractAttribute::trackStatistics()
10606 void trackStatistics() const override {
10608 }
10609};
10610
10611struct AANoFPClassCallSiteReturned final
10612 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10613 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10614 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10615
10616 /// See AbstractAttribute::trackStatistics()
10617 void trackStatistics() const override {
10619 }
10620};
10621
10622struct AACallEdgesImpl : public AACallEdges {
10623 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10624
10625 const SetVector<Function *> &getOptimisticEdges() const override {
10626 return CalledFunctions;
10627 }
10628
10629 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10630
10631 bool hasNonAsmUnknownCallee() const override {
10632 return HasUnknownCalleeNonAsm;
10633 }
10634
10635 const std::string getAsStr(Attributor *A) const override {
10636 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10637 std::to_string(CalledFunctions.size()) + "]";
10638 }
10639
10640 void trackStatistics() const override {}
10641
10642protected:
10643 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10644 if (CalledFunctions.insert(Fn)) {
10645 Change = ChangeStatus::CHANGED;
10646 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10647 << "\n");
10648 }
10649 }
10650
10651 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10652 if (!HasUnknownCallee)
10653 Change = ChangeStatus::CHANGED;
10654 if (NonAsm && !HasUnknownCalleeNonAsm)
10655 Change = ChangeStatus::CHANGED;
10656 HasUnknownCalleeNonAsm |= NonAsm;
10657 HasUnknownCallee = true;
10658 }
10659
10660private:
10661 /// Optimistic set of functions that might be called by this position.
10662 SetVector<Function *> CalledFunctions;
10663
10664 /// Is there any call with a unknown callee.
10665 bool HasUnknownCallee = false;
10666
10667 /// Is there any call with a unknown callee, excluding any inline asm.
10668 bool HasUnknownCalleeNonAsm = false;
10669};
10670
10671struct AACallEdgesCallSite : public AACallEdgesImpl {
10672 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10673 : AACallEdgesImpl(IRP, A) {}
10674 /// See AbstractAttribute::updateImpl(...).
10675 ChangeStatus updateImpl(Attributor &A) override {
10676 ChangeStatus Change = ChangeStatus::UNCHANGED;
10677
10678 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10679 if (Function *Fn = dyn_cast<Function>(&V)) {
10680 addCalledFunction(Fn, Change);
10681 } else {
10682 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10683 setHasUnknownCallee(true, Change);
10684 }
10685
10686 // Explore all values.
10687 return true;
10688 };
10689
10691 // Process any value that we might call.
10692 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10693 if (isa<Constant>(V)) {
10694 VisitValue(*V, CtxI);
10695 return;
10696 }
10697
10698 bool UsedAssumedInformation = false;
10699 Values.clear();
10700 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10701 AA::AnyScope, UsedAssumedInformation)) {
10702 Values.push_back({*V, CtxI});
10703 }
10704 for (auto &VAC : Values)
10705 VisitValue(*VAC.getValue(), VAC.getCtxI());
10706 };
10707
10708 CallBase *CB = cast<CallBase>(getCtxI());
10709
10710 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10711 if (IA->hasSideEffects() &&
10712 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10713 !hasAssumption(*CB, "ompx_no_call_asm")) {
10714 setHasUnknownCallee(false, Change);
10715 }
10716 return Change;
10717 }
10718
10719 if (CB->isIndirectCall())
10720 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10721 *this, getIRPosition(), DepClassTy::OPTIONAL))
10722 if (IndirectCallAA->foreachCallee(
10723 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10724 return Change;
10725
10726 // The most simple case.
10727 ProcessCalledOperand(CB->getCalledOperand(), CB);
10728
10729 // Process callback functions.
10730 SmallVector<const Use *, 4u> CallbackUses;
10731 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10732 for (const Use *U : CallbackUses)
10733 ProcessCalledOperand(U->get(), CB);
10734
10735 return Change;
10736 }
10737};
10738
10739struct AACallEdgesFunction : public AACallEdgesImpl {
10740 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10741 : AACallEdgesImpl(IRP, A) {}
10742
10743 /// See AbstractAttribute::updateImpl(...).
10744 ChangeStatus updateImpl(Attributor &A) override {
10745 ChangeStatus Change = ChangeStatus::UNCHANGED;
10746
10747 auto ProcessCallInst = [&](Instruction &Inst) {
10748 CallBase &CB = cast<CallBase>(Inst);
10749
10750 auto *CBEdges = A.getAAFor<AACallEdges>(
10751 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10752 if (!CBEdges)
10753 return false;
10754 if (CBEdges->hasNonAsmUnknownCallee())
10755 setHasUnknownCallee(true, Change);
10756 if (CBEdges->hasUnknownCallee())
10757 setHasUnknownCallee(false, Change);
10758
10759 for (Function *F : CBEdges->getOptimisticEdges())
10760 addCalledFunction(F, Change);
10761
10762 return true;
10763 };
10764
10765 // Visit all callable instructions.
10766 bool UsedAssumedInformation = false;
10767 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10768 UsedAssumedInformation,
10769 /* CheckBBLivenessOnly */ true)) {
10770 // If we haven't looked at all call like instructions, assume that there
10771 // are unknown callees.
10772 setHasUnknownCallee(true, Change);
10773 }
10774
10775 return Change;
10776 }
10777};
10778
10779/// -------------------AAInterFnReachability Attribute--------------------------
10780
10781struct AAInterFnReachabilityFunction
10782 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10783 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10784 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10785 : Base(IRP, A) {}
10786
10787 bool instructionCanReach(
10788 Attributor &A, const Instruction &From, const Function &To,
10789 const AA::InstExclusionSetTy *ExclusionSet) const override {
10790 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10791 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10792
10793 RQITy StackRQI(A, From, To, ExclusionSet, false);
10794 RQITy::Reachable Result;
10795 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10796 return NonConstThis->isReachableImpl(A, StackRQI,
10797 /*IsTemporaryRQI=*/true);
10798 return Result == RQITy::Reachable::Yes;
10799 }
10800
10801 bool isReachableImpl(Attributor &A, RQITy &RQI,
10802 bool IsTemporaryRQI) override {
10803 const Instruction *EntryI =
10804 &RQI.From->getFunction()->getEntryBlock().front();
10805 if (EntryI != RQI.From &&
10806 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10807 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10808 IsTemporaryRQI);
10809
10810 auto CheckReachableCallBase = [&](CallBase *CB) {
10811 auto *CBEdges = A.getAAFor<AACallEdges>(
10812 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10813 if (!CBEdges || !CBEdges->getState().isValidState())
10814 return false;
10815 // TODO Check To backwards in this case.
10816 if (CBEdges->hasUnknownCallee())
10817 return false;
10818
10819 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10820 if (Fn == RQI.To)
10821 return false;
10822
10823 if (Fn->isDeclaration()) {
10824 if (Fn->hasFnAttribute(Attribute::NoCallback))
10825 continue;
10826 // TODO Check To backwards in this case.
10827 return false;
10828 }
10829
10830 if (Fn == getAnchorScope()) {
10831 if (EntryI == RQI.From)
10832 continue;
10833 return false;
10834 }
10835
10836 const AAInterFnReachability *InterFnReachability =
10837 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10838 DepClassTy::OPTIONAL);
10839
10840 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10841 if (!InterFnReachability ||
10842 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10843 RQI.ExclusionSet))
10844 return false;
10845 }
10846 return true;
10847 };
10848
10849 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10850 *this, IRPosition::function(*RQI.From->getFunction()),
10851 DepClassTy::OPTIONAL);
10852
10853 // Determine call like instructions that we can reach from the inst.
10854 auto CheckCallBase = [&](Instruction &CBInst) {
10855 // There are usually less nodes in the call graph, check inter function
10856 // reachability first.
10857 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10858 return true;
10859 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10860 A, *RQI.From, CBInst, RQI.ExclusionSet);
10861 };
10862
10863 bool UsedExclusionSet = /* conservative */ true;
10864 bool UsedAssumedInformation = false;
10865 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10866 UsedAssumedInformation,
10867 /* CheckBBLivenessOnly */ true))
10868 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10869 IsTemporaryRQI);
10870
10871 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10872 IsTemporaryRQI);
10873 }
10874
10875 void trackStatistics() const override {}
10876};
10877} // namespace
10878
10879template <typename AAType>
10880static std::optional<Constant *>
10882 const IRPosition &IRP, Type &Ty) {
10883 if (!Ty.isIntegerTy())
10884 return nullptr;
10885
10886 // This will also pass the call base context.
10887 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10888 if (!AA)
10889 return nullptr;
10890
10891 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10892
10893 if (!COpt.has_value()) {
10894 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10895 return std::nullopt;
10896 }
10897 if (auto *C = *COpt) {
10898 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10899 return C;
10900 }
10901 return nullptr;
10902}
10903
10905 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10907 Type &Ty = *IRP.getAssociatedType();
10908 std::optional<Value *> V;
10909 for (auto &It : Values) {
10910 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10911 if (V.has_value() && !*V)
10912 break;
10913 }
10914 if (!V.has_value())
10915 return UndefValue::get(&Ty);
10916 return *V;
10917}
10918
10919namespace {
10920struct AAPotentialValuesImpl : AAPotentialValues {
10921 using StateType = PotentialLLVMValuesState;
10922
10923 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10924 : AAPotentialValues(IRP, A) {}
10925
10926 /// See AbstractAttribute::initialize(..).
10927 void initialize(Attributor &A) override {
10928 if (A.hasSimplificationCallback(getIRPosition())) {
10929 indicatePessimisticFixpoint();
10930 return;
10931 }
10932 Value *Stripped = getAssociatedValue().stripPointerCasts();
10933 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10934 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10935 getAnchorScope());
10936 indicateOptimisticFixpoint();
10937 return;
10938 }
10939 AAPotentialValues::initialize(A);
10940 }
10941
10942 /// See AbstractAttribute::getAsStr().
10943 const std::string getAsStr(Attributor *A) const override {
10944 std::string Str;
10945 llvm::raw_string_ostream OS(Str);
10946 OS << getState();
10947 return Str;
10948 }
10949
10950 template <typename AAType>
10951 static std::optional<Value *> askOtherAA(Attributor &A,
10952 const AbstractAttribute &AA,
10953 const IRPosition &IRP, Type &Ty) {
10955 return &IRP.getAssociatedValue();
10956 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10957 if (!C)
10958 return std::nullopt;
10959 if (*C)
10960 if (auto *CC = AA::getWithType(**C, Ty))
10961 return CC;
10962 return nullptr;
10963 }
10964
10965 virtual void addValue(Attributor &A, StateType &State, Value &V,
10966 const Instruction *CtxI, AA::ValueScope S,
10967 Function *AnchorScope) const {
10968
10969 IRPosition ValIRP = IRPosition::value(V);
10970 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10971 for (const auto &U : CB->args()) {
10972 if (U.get() != &V)
10973 continue;
10974 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10975 break;
10976 }
10977 }
10978
10979 Value *VPtr = &V;
10980 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10981 Type &Ty = *getAssociatedType();
10982 std::optional<Value *> SimpleV =
10983 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10984 if (SimpleV.has_value() && !*SimpleV) {
10985 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10986 *this, ValIRP, DepClassTy::OPTIONAL);
10987 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10988 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10989 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10990 if (PotentialConstantsAA->undefIsContained())
10991 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10992 return;
10993 }
10994 }
10995 if (!SimpleV.has_value())
10996 return;
10997
10998 if (*SimpleV)
10999 VPtr = *SimpleV;
11000 }
11001
11002 if (isa<ConstantInt>(VPtr))
11003 CtxI = nullptr;
11004 if (!AA::isValidInScope(*VPtr, AnchorScope))
11006
11007 State.unionAssumed({{*VPtr, CtxI}, S});
11008 }
11009
11010 /// Helper struct to tie a value+context pair together with the scope for
11011 /// which this is the simplified version.
11012 struct ItemInfo {
11013 AA::ValueAndContext I;
11015
11016 bool operator==(const ItemInfo &II) const {
11017 return II.I == I && II.S == S;
11018 };
11019 bool operator<(const ItemInfo &II) const {
11020 return std::tie(I, S) < std::tie(II.I, II.S);
11021 };
11022 };
11023
11024 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11025 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11026 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11027 if (!(CS & S))
11028 continue;
11029
11030 bool UsedAssumedInformation = false;
11032 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11033 UsedAssumedInformation))
11034 return false;
11035
11036 for (auto &It : Values)
11037 ValueScopeMap[It] += CS;
11038 }
11039 for (auto &It : ValueScopeMap)
11040 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11041 AA::ValueScope(It.second), getAnchorScope());
11042
11043 return true;
11044 }
11045
11046 void giveUpOnIntraprocedural(Attributor &A) {
11047 auto NewS = StateType::getBestState(getState());
11048 for (const auto &It : getAssumedSet()) {
11049 if (It.second == AA::Intraprocedural)
11050 continue;
11051 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11052 AA::Interprocedural, getAnchorScope());
11053 }
11054 assert(!undefIsContained() && "Undef should be an explicit value!");
11055 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11056 getAnchorScope());
11057 getState() = NewS;
11058 }
11059
11060 /// See AbstractState::indicatePessimisticFixpoint(...).
11061 ChangeStatus indicatePessimisticFixpoint() override {
11062 getState() = StateType::getBestState(getState());
11063 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11064 AAPotentialValues::indicateOptimisticFixpoint();
11065 return ChangeStatus::CHANGED;
11066 }
11067
11068 /// See AbstractAttribute::updateImpl(...).
11069 ChangeStatus updateImpl(Attributor &A) override {
11070 return indicatePessimisticFixpoint();
11071 }
11072
11073 /// See AbstractAttribute::manifest(...).
11074 ChangeStatus manifest(Attributor &A) override {
11077 Values.clear();
11078 if (!getAssumedSimplifiedValues(A, Values, S))
11079 continue;
11080 Value &OldV = getAssociatedValue();
11081 if (isa<UndefValue>(OldV))
11082 continue;
11083 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11084 if (!NewV || NewV == &OldV)
11085 continue;
11086 if (getCtxI() &&
11087 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11088 continue;
11089 if (A.changeAfterManifest(getIRPosition(), *NewV))
11090 return ChangeStatus::CHANGED;
11091 }
11092 return ChangeStatus::UNCHANGED;
11093 }
11094
11095 bool getAssumedSimplifiedValues(
11096 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11097 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11098 if (!isValidState())
11099 return false;
11100 bool UsedAssumedInformation = false;
11101 for (const auto &It : getAssumedSet())
11102 if (It.second & S) {
11103 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11104 isa<SelectInst>(It.first.getValue()))) {
11105 if (A.getAssumedSimplifiedValues(
11106 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11107 this, Values, S, UsedAssumedInformation))
11108 continue;
11109 }
11110 Values.push_back(It.first);
11111 }
11112 assert(!undefIsContained() && "Undef should be an explicit value!");
11113 return true;
11114 }
11115};
11116
11117struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11118 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11119 : AAPotentialValuesImpl(IRP, A) {}
11120
11121 /// See AbstractAttribute::updateImpl(...).
11122 ChangeStatus updateImpl(Attributor &A) override {
11123 auto AssumedBefore = getAssumed();
11124
11125 genericValueTraversal(A, &getAssociatedValue());
11126
11127 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11128 : ChangeStatus::CHANGED;
11129 }
11130
11131 /// Helper struct to remember which AAIsDead instances we actually used.
11132 struct LivenessInfo {
11133 const AAIsDead *LivenessAA = nullptr;
11134 bool AnyDead = false;
11135 };
11136
11137 /// Check if \p Cmp is a comparison we can simplify.
11138 ///
11139 /// We handle multiple cases, one in which at least one operand is an
11140 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11141 /// operand. Return true if successful, in that case Worklist will be updated.
11142 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11143 CmpInst::Predicate Pred, ItemInfo II,
11144 SmallVectorImpl<ItemInfo> &Worklist) {
11145
11146 // Simplify the operands first.
11147 bool UsedAssumedInformation = false;
11148 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11149 auto GetSimplifiedValues = [&](Value &V,
11151 if (!A.getAssumedSimplifiedValues(
11152 IRPosition::value(V, getCallBaseContext()), this, Values,
11153 AA::Intraprocedural, UsedAssumedInformation)) {
11154 Values.clear();
11155 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11156 }
11157 return Values.empty();
11158 };
11159 if (GetSimplifiedValues(*LHS, LHSValues))
11160 return true;
11161 if (GetSimplifiedValues(*RHS, RHSValues))
11162 return true;
11163
11164 LLVMContext &Ctx = LHS->getContext();
11165
11166 InformationCache &InfoCache = A.getInfoCache();
11167 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11168 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11169 const auto *DT =
11170 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11171 : nullptr;
11172 const auto *TLI =
11173 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11174 auto *AC =
11175 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11176 : nullptr;
11177
11178 const DataLayout &DL = A.getDataLayout();
11179 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11180
11181 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11182 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11183 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11184 /* CtxI */ nullptr, II.S, getAnchorScope());
11185 return true;
11186 }
11187
11188 // Handle the trivial case first in which we don't even need to think
11189 // about null or non-null.
11190 if (&LHSV == &RHSV &&
11192 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11194 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11195 getAnchorScope());
11196 return true;
11197 }
11198
11199 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11200 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11201 if (TypedLHS && TypedRHS) {
11202 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11203 if (NewV && NewV != &Cmp) {
11204 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11205 getAnchorScope());
11206 return true;
11207 }
11208 }
11209
11210 // From now on we only handle equalities (==, !=).
11211 if (!CmpInst::isEquality(Pred))
11212 return false;
11213
11214 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11215 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11216 if (!LHSIsNull && !RHSIsNull)
11217 return false;
11218
11219 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11220 // non-nullptr operand and if we assume it's non-null we can conclude the
11221 // result of the comparison.
11222 assert((LHSIsNull || RHSIsNull) &&
11223 "Expected nullptr versus non-nullptr comparison at this point");
11224
11225 // The index is the operand that we assume is not null.
11226 unsigned PtrIdx = LHSIsNull;
11227 bool IsKnownNonNull;
11228 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11229 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11230 DepClassTy::REQUIRED, IsKnownNonNull);
11231 if (!IsAssumedNonNull)
11232 return false;
11233
11234 // The new value depends on the predicate, true for != and false for ==.
11235 Constant *NewV =
11236 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11237 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11238 getAnchorScope());
11239 return true;
11240 };
11241
11242 for (auto &LHSValue : LHSValues)
11243 for (auto &RHSValue : RHSValues)
11244 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11245 return false;
11246 return true;
11247 }
11248
11249 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11250 SmallVectorImpl<ItemInfo> &Worklist) {
11251 const Instruction *CtxI = II.I.getCtxI();
11252 bool UsedAssumedInformation = false;
11253
11254 std::optional<Constant *> C =
11255 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11256 bool NoValueYet = !C.has_value();
11257 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11258 return true;
11259 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11260 if (CI->isZero())
11261 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11262 else
11263 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11264 } else if (&SI == &getAssociatedValue()) {
11265 // We could not simplify the condition, assume both values.
11266 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11267 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11268 } else {
11269 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11270 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11271 if (!SimpleV.has_value())
11272 return true;
11273 if (*SimpleV) {
11274 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11275 return true;
11276 }
11277 return false;
11278 }
11279 return true;
11280 }
11281
11282 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11283 SmallVectorImpl<ItemInfo> &Worklist) {
11284 SmallSetVector<Value *, 4> PotentialCopies;
11285 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11286 bool UsedAssumedInformation = false;
11287 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11288 PotentialValueOrigins, *this,
11289 UsedAssumedInformation,
11290 /* OnlyExact */ true)) {
11291 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11292 "loaded values for load instruction "
11293 << LI << "\n");
11294 return false;
11295 }
11296
11297 // Do not simplify loads that are only used in llvm.assume if we cannot also
11298 // remove all stores that may feed into the load. The reason is that the
11299 // assume is probably worth something as long as the stores are around.
11300 InformationCache &InfoCache = A.getInfoCache();
11301 if (InfoCache.isOnlyUsedByAssume(LI)) {
11302 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11303 if (!I || isa<AssumeInst>(I))
11304 return true;
11305 if (auto *SI = dyn_cast<StoreInst>(I))
11306 return A.isAssumedDead(SI->getOperandUse(0), this,
11307 /* LivenessAA */ nullptr,
11308 UsedAssumedInformation,
11309 /* CheckBBLivenessOnly */ false);
11310 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11311 UsedAssumedInformation,
11312 /* CheckBBLivenessOnly */ false);
11313 })) {
11314 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11315 "and we cannot delete all the stores: "
11316 << LI << "\n");
11317 return false;
11318 }
11319 }
11320
11321 // Values have to be dynamically unique or we loose the fact that a
11322 // single llvm::Value might represent two runtime values (e.g.,
11323 // stack locations in different recursive calls).
11324 const Instruction *CtxI = II.I.getCtxI();
11325 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11326 bool AllLocal = ScopeIsLocal;
11327 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11328 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11329 return AA::isDynamicallyUnique(A, *this, *PC);
11330 });
11331 if (!DynamicallyUnique) {
11332 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11333 "values are dynamically unique: "
11334 << LI << "\n");
11335 return false;
11336 }
11337
11338 for (auto *PotentialCopy : PotentialCopies) {
11339 if (AllLocal) {
11340 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11341 } else {
11342 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11343 }
11344 }
11345 if (!AllLocal && ScopeIsLocal)
11346 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11347 return true;
11348 }
11349
11350 bool handlePHINode(
11351 Attributor &A, PHINode &PHI, ItemInfo II,
11352 SmallVectorImpl<ItemInfo> &Worklist,
11353 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11354 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11355 LivenessInfo &LI = LivenessAAs[&F];
11356 if (!LI.LivenessAA)
11357 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11358 DepClassTy::NONE);
11359 return LI;
11360 };
11361
11362 if (&PHI == &getAssociatedValue()) {
11363 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11364 const auto *CI =
11365 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11366 *PHI.getFunction());
11367
11368 Cycle *C = nullptr;
11369 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11370 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11371 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11372 if (LI.LivenessAA &&
11373 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11374 LI.AnyDead = true;
11375 continue;
11376 }
11377 Value *V = PHI.getIncomingValue(u);
11378 if (V == &PHI)
11379 continue;
11380
11381 // If the incoming value is not the PHI but an instruction in the same
11382 // cycle we might have multiple versions of it flying around.
11383 if (CyclePHI && isa<Instruction>(V) &&
11384 (!C || C->contains(cast<Instruction>(V)->getParent())))
11385 return false;
11386
11387 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11388 }
11389 return true;
11390 }
11391
11392 bool UsedAssumedInformation = false;
11393 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11394 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11395 if (!SimpleV.has_value())
11396 return true;
11397 if (!(*SimpleV))
11398 return false;
11399 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11400 return true;
11401 }
11402
11403 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11404 /// simplify any operand of the instruction \p I. Return true if successful,
11405 /// in that case Worklist will be updated.
11406 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11407 SmallVectorImpl<ItemInfo> &Worklist) {
11408 bool SomeSimplified = false;
11409 bool UsedAssumedInformation = false;
11410
11411 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11412 int Idx = 0;
11413 for (Value *Op : I.operands()) {
11414 const auto &SimplifiedOp = A.getAssumedSimplified(
11415 IRPosition::value(*Op, getCallBaseContext()), *this,
11416 UsedAssumedInformation, AA::Intraprocedural);
11417 // If we are not sure about any operand we are not sure about the entire
11418 // instruction, we'll wait.
11419 if (!SimplifiedOp.has_value())
11420 return true;
11421
11422 if (*SimplifiedOp)
11423 NewOps[Idx] = *SimplifiedOp;
11424 else
11425 NewOps[Idx] = Op;
11426
11427 SomeSimplified |= (NewOps[Idx] != Op);
11428 ++Idx;
11429 }
11430
11431 // We won't bother with the InstSimplify interface if we didn't simplify any
11432 // operand ourselves.
11433 if (!SomeSimplified)
11434 return false;
11435
11436 InformationCache &InfoCache = A.getInfoCache();
11437 Function *F = I.getFunction();
11438 const auto *DT =
11439 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11440 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11441 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11442
11443 const DataLayout &DL = I.getDataLayout();
11444 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11445 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11446 if (!NewV || NewV == &I)
11447 return false;
11448
11449 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11450 << *NewV << "\n");
11451 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11452 return true;
11453 }
11454
11456 Attributor &A, Instruction &I, ItemInfo II,
11457 SmallVectorImpl<ItemInfo> &Worklist,
11458 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11459 if (auto *CI = dyn_cast<CmpInst>(&I))
11460 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11461 CI->getPredicate(), II, Worklist);
11462
11463 switch (I.getOpcode()) {
11464 case Instruction::Select:
11465 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11466 case Instruction::PHI:
11467 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11468 case Instruction::Load:
11469 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11470 default:
11471 return handleGenericInst(A, I, II, Worklist);
11472 };
11473 return false;
11474 }
11475
11476 void genericValueTraversal(Attributor &A, Value *InitialV) {
11477 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11478
11479 SmallSet<ItemInfo, 16> Visited;
11481 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11482
11483 int Iteration = 0;
11484 do {
11485 ItemInfo II = Worklist.pop_back_val();
11486 Value *V = II.I.getValue();
11487 assert(V);
11488 const Instruction *CtxI = II.I.getCtxI();
11489 AA::ValueScope S = II.S;
11490
11491 // Check if we should process the current value. To prevent endless
11492 // recursion keep a record of the values we followed!
11493 if (!Visited.insert(II).second)
11494 continue;
11495
11496 // Make sure we limit the compile time for complex expressions.
11497 if (Iteration++ >= MaxPotentialValuesIterations) {
11498 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11499 << Iteration << "!\n");
11500 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11501 continue;
11502 }
11503
11504 // Explicitly look through calls with a "returned" attribute if we do
11505 // not have a pointer as stripPointerCasts only works on them.
11506 Value *NewV = nullptr;
11507 if (V->getType()->isPointerTy()) {
11508 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11509 } else {
11510 if (auto *CB = dyn_cast<CallBase>(V))
11511 if (auto *Callee =
11513 for (Argument &Arg : Callee->args())
11514 if (Arg.hasReturnedAttr()) {
11515 NewV = CB->getArgOperand(Arg.getArgNo());
11516 break;
11517 }
11518 }
11519 }
11520 if (NewV && NewV != V) {
11521 Worklist.push_back({{*NewV, CtxI}, S});
11522 continue;
11523 }
11524
11525 if (auto *I = dyn_cast<Instruction>(V)) {
11526 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11527 continue;
11528 }
11529
11530 if (V != InitialV || isa<Argument>(V))
11531 if (recurseForValue(A, IRPosition::value(*V), II.S))
11532 continue;
11533
11534 // If we haven't stripped anything we give up.
11535 if (V == InitialV && CtxI == getCtxI()) {
11536 indicatePessimisticFixpoint();
11537 return;
11538 }
11539
11540 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11541 } while (!Worklist.empty());
11542
11543 // If we actually used liveness information so we have to record a
11544 // dependence.
11545 for (auto &It : LivenessAAs)
11546 if (It.second.AnyDead)
11547 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11548 }
11549
11550 /// See AbstractAttribute::trackStatistics()
11551 void trackStatistics() const override {
11552 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11553 }
11554};
11555
11556struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11557 using Base = AAPotentialValuesImpl;
11558 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11559 : Base(IRP, A) {}
11560
11561 /// See AbstractAttribute::initialize(..).
11562 void initialize(Attributor &A) override {
11563 auto &Arg = cast<Argument>(getAssociatedValue());
11565 indicatePessimisticFixpoint();
11566 }
11567
11568 /// See AbstractAttribute::updateImpl(...).
11569 ChangeStatus updateImpl(Attributor &A) override {
11570 auto AssumedBefore = getAssumed();
11571
11572 unsigned ArgNo = getCalleeArgNo();
11573
11574 bool UsedAssumedInformation = false;
11576 auto CallSitePred = [&](AbstractCallSite ACS) {
11577 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11578 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11579 return false;
11580
11581 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11583 UsedAssumedInformation))
11584 return false;
11585
11586 return isValidState();
11587 };
11588
11589 if (!A.checkForAllCallSites(CallSitePred, *this,
11590 /* RequireAllCallSites */ true,
11591 UsedAssumedInformation))
11592 return indicatePessimisticFixpoint();
11593
11594 Function *Fn = getAssociatedFunction();
11595 bool AnyNonLocal = false;
11596 for (auto &It : Values) {
11597 if (isa<Constant>(It.getValue())) {
11598 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11599 getAnchorScope());
11600 continue;
11601 }
11602 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11603 return indicatePessimisticFixpoint();
11604
11605 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11606 if (Arg->getParent() == Fn) {
11607 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11608 getAnchorScope());
11609 continue;
11610 }
11611 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11612 getAnchorScope());
11613 AnyNonLocal = true;
11614 }
11615 assert(!undefIsContained() && "Undef should be an explicit value!");
11616 if (AnyNonLocal)
11617 giveUpOnIntraprocedural(A);
11618
11619 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11620 : ChangeStatus::CHANGED;
11621 }
11622
11623 /// See AbstractAttribute::trackStatistics()
11624 void trackStatistics() const override {
11625 STATS_DECLTRACK_ARG_ATTR(potential_values)
11626 }
11627};
11628
11629struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11630 using Base = AAPotentialValuesFloating;
11631 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11632 : Base(IRP, A) {}
11633
11634 /// See AbstractAttribute::initialize(..).
11635 void initialize(Attributor &A) override {
11636 Function *F = getAssociatedFunction();
11637 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11638 indicatePessimisticFixpoint();
11639 return;
11640 }
11641
11642 for (Argument &Arg : F->args())
11643 if (Arg.hasReturnedAttr()) {
11644 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11645 ReturnedArg = &Arg;
11646 break;
11647 }
11648 if (!A.isFunctionIPOAmendable(*F) ||
11649 A.hasSimplificationCallback(getIRPosition())) {
11650 if (!ReturnedArg)
11651 indicatePessimisticFixpoint();
11652 else
11653 indicateOptimisticFixpoint();
11654 }
11655 }
11656
11657 /// See AbstractAttribute::updateImpl(...).
11658 ChangeStatus updateImpl(Attributor &A) override {
11659 auto AssumedBefore = getAssumed();
11660 bool UsedAssumedInformation = false;
11661
11663 Function *AnchorScope = getAnchorScope();
11664 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11665 bool AddValues) {
11667 Values.clear();
11668 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11669 UsedAssumedInformation,
11670 /* RecurseForSelectAndPHI */ true))
11671 return false;
11672 if (!AddValues)
11673 continue;
11674
11675 bool AllInterAreIntra = false;
11676 if (S == AA::Interprocedural)
11677 AllInterAreIntra =
11678 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11679 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11680 });
11681
11682 for (const AA::ValueAndContext &VAC : Values) {
11683 addValue(A, getState(), *VAC.getValue(),
11684 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11685 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11686 }
11687 if (AllInterAreIntra)
11688 break;
11689 }
11690 return true;
11691 };
11692
11693 if (ReturnedArg) {
11694 HandleReturnedValue(*ReturnedArg, nullptr, true);
11695 } else {
11696 auto RetInstPred = [&](Instruction &RetI) {
11697 bool AddValues = true;
11698 if (isa<PHINode>(RetI.getOperand(0)) ||
11699 isa<SelectInst>(RetI.getOperand(0))) {
11700 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11701 AnchorScope);
11702 AddValues = false;
11703 }
11704 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11705 };
11706
11707 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11708 UsedAssumedInformation,
11709 /* CheckBBLivenessOnly */ true))
11710 return indicatePessimisticFixpoint();
11711 }
11712
11713 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11714 : ChangeStatus::CHANGED;
11715 }
11716
11717 ChangeStatus manifest(Attributor &A) override {
11718 if (ReturnedArg)
11719 return ChangeStatus::UNCHANGED;
11721 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11722 /* RecurseForSelectAndPHI */ true))
11723 return ChangeStatus::UNCHANGED;
11724 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11725 if (!NewVal)
11726 return ChangeStatus::UNCHANGED;
11727
11728 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11729 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11730 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11731 "Number of function with unique return");
11732 Changed |= A.manifestAttrs(
11734 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11735 STATS_DECLTRACK_ARG_ATTR(returned);
11736 }
11737
11738 auto RetInstPred = [&](Instruction &RetI) {
11739 Value *RetOp = RetI.getOperand(0);
11740 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11741 return true;
11742 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11743 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11744 Changed = ChangeStatus::CHANGED;
11745 return true;
11746 };
11747 bool UsedAssumedInformation = false;
11748 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11749 UsedAssumedInformation,
11750 /* CheckBBLivenessOnly */ true);
11751 return Changed;
11752 }
11753
11754 ChangeStatus indicatePessimisticFixpoint() override {
11755 return AAPotentialValues::indicatePessimisticFixpoint();
11756 }
11757
11758 /// See AbstractAttribute::trackStatistics()
11759 void trackStatistics() const override{
11760 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11761
11762 /// The argumented with an existing `returned` attribute.
11763 Argument *ReturnedArg = nullptr;
11764};
11765
11766struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11767 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11768 : AAPotentialValuesImpl(IRP, A) {}
11769
11770 /// See AbstractAttribute::updateImpl(...).
11771 ChangeStatus updateImpl(Attributor &A) override {
11772 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11773 "not be called");
11774 }
11775
11776 /// See AbstractAttribute::trackStatistics()
11777 void trackStatistics() const override {
11778 STATS_DECLTRACK_FN_ATTR(potential_values)
11779 }
11780};
11781
11782struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11783 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11784 : AAPotentialValuesFunction(IRP, A) {}
11785
11786 /// See AbstractAttribute::trackStatistics()
11787 void trackStatistics() const override {
11788 STATS_DECLTRACK_CS_ATTR(potential_values)
11789 }
11790};
11791
11792struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11793 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11794 : AAPotentialValuesImpl(IRP, A) {}
11795
11796 /// See AbstractAttribute::updateImpl(...).
11797 ChangeStatus updateImpl(Attributor &A) override {
11798 auto AssumedBefore = getAssumed();
11799
11800 Function *Callee = getAssociatedFunction();
11801 if (!Callee)
11802 return indicatePessimisticFixpoint();
11803
11804 bool UsedAssumedInformation = false;
11805 auto *CB = cast<CallBase>(getCtxI());
11806 if (CB->isMustTailCall() &&
11807 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11808 UsedAssumedInformation))
11809 return indicatePessimisticFixpoint();
11810
11811 Function *Caller = CB->getCaller();
11812
11813 auto AddScope = [&](AA::ValueScope S) {
11815 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11816 Values, S, UsedAssumedInformation))
11817 return false;
11818
11819 for (auto &It : Values) {
11820 Value *V = It.getValue();
11821 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11822 V, *CB, *this, UsedAssumedInformation);
11823 if (!CallerV.has_value()) {
11824 // Nothing to do as long as no value was determined.
11825 continue;
11826 }
11827 V = *CallerV ? *CallerV : V;
11828 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11829 if (recurseForValue(A, IRPosition::value(*V), S))
11830 continue;
11831 }
11832 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11833 giveUpOnIntraprocedural(A);
11834 return true;
11835 }
11836 addValue(A, getState(), *V, CB, S, getAnchorScope());
11837 }
11838 return true;
11839 };
11840 if (!AddScope(AA::Intraprocedural))
11841 return indicatePessimisticFixpoint();
11842 if (!AddScope(AA::Interprocedural))
11843 return indicatePessimisticFixpoint();
11844 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11845 : ChangeStatus::CHANGED;
11846 }
11847
11848 ChangeStatus indicatePessimisticFixpoint() override {
11849 return AAPotentialValues::indicatePessimisticFixpoint();
11850 }
11851
11852 /// See AbstractAttribute::trackStatistics()
11853 void trackStatistics() const override {
11854 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11855 }
11856};
11857
11858struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11859 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11860 : AAPotentialValuesFloating(IRP, A) {}
11861
11862 /// See AbstractAttribute::trackStatistics()
11863 void trackStatistics() const override {
11864 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11865 }
11866};
11867} // namespace
11868
11869/// ---------------------- Assumption Propagation ------------------------------
11870namespace {
11871struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11872 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11873 const DenseSet<StringRef> &Known)
11874 : AAAssumptionInfo(IRP, A, Known) {}
11875
11876 /// See AbstractAttribute::manifest(...).
11877 ChangeStatus manifest(Attributor &A) override {
11878 // Don't manifest a universal set if it somehow made it here.
11879 if (getKnown().isUniversal())
11880 return ChangeStatus::UNCHANGED;
11881
11882 const IRPosition &IRP = getIRPosition();
11883 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11884 getAssumed().getSet().end());
11885 llvm::sort(Set);
11886 return A.manifestAttrs(IRP,
11887 Attribute::get(IRP.getAnchorValue().getContext(),
11889 llvm::join(Set, ",")),
11890 /*ForceReplace=*/true);
11891 }
11892
11893 bool hasAssumption(const StringRef Assumption) const override {
11894 return isValidState() && setContains(Assumption);
11895 }
11896
11897 /// See AbstractAttribute::getAsStr()
11898 const std::string getAsStr(Attributor *A) const override {
11899 const SetContents &Known = getKnown();
11900 const SetContents &Assumed = getAssumed();
11901
11902 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11903 llvm::sort(Set);
11904 const std::string KnownStr = llvm::join(Set, ",");
11905
11906 std::string AssumedStr = "Universal";
11907 if (!Assumed.isUniversal()) {
11908 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11909 AssumedStr = llvm::join(Set, ",");
11910 }
11911 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11912 }
11913};
11914
11915/// Propagates assumption information from parent functions to all of their
11916/// successors. An assumption can be propagated if the containing function
11917/// dominates the called function.
11918///
11919/// We start with a "known" set of assumptions already valid for the associated
11920/// function and an "assumed" set that initially contains all possible
11921/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11922/// contents as concrete values are known. The concrete values are seeded by the
11923/// first nodes that are either entries into the call graph, or contains no
11924/// assumptions. Each node is updated as the intersection of the assumed state
11925/// with all of its predecessors.
11926struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11927 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11928 : AAAssumptionInfoImpl(IRP, A,
11929 getAssumptions(*IRP.getAssociatedFunction())) {}
11930
11931 /// See AbstractAttribute::updateImpl(...).
11932 ChangeStatus updateImpl(Attributor &A) override {
11933 bool Changed = false;
11934
11935 auto CallSitePred = [&](AbstractCallSite ACS) {
11936 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11937 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11938 DepClassTy::REQUIRED);
11939 if (!AssumptionAA)
11940 return false;
11941 // Get the set of assumptions shared by all of this function's callers.
11942 Changed |= getIntersection(AssumptionAA->getAssumed());
11943 return !getAssumed().empty() || !getKnown().empty();
11944 };
11945
11946 bool UsedAssumedInformation = false;
11947 // Get the intersection of all assumptions held by this node's predecessors.
11948 // If we don't know all the call sites then this is either an entry into the
11949 // call graph or an empty node. This node is known to only contain its own
11950 // assumptions and can be propagated to its successors.
11951 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11952 UsedAssumedInformation))
11953 return indicatePessimisticFixpoint();
11954
11955 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11956 }
11957
11958 void trackStatistics() const override {}
11959};
11960
11961/// Assumption Info defined for call sites.
11962struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11963
11964 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11965 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11966
11967 /// See AbstractAttribute::initialize(...).
11968 void initialize(Attributor &A) override {
11969 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11970 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11971 }
11972
11973 /// See AbstractAttribute::updateImpl(...).
11974 ChangeStatus updateImpl(Attributor &A) override {
11975 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11976 auto *AssumptionAA =
11977 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11978 if (!AssumptionAA)
11979 return indicatePessimisticFixpoint();
11980 bool Changed = getIntersection(AssumptionAA->getAssumed());
11981 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11982 }
11983
11984 /// See AbstractAttribute::trackStatistics()
11985 void trackStatistics() const override {}
11986
11987private:
11988 /// Helper to initialized the known set as all the assumptions this call and
11989 /// the callee contain.
11990 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11991 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11992 auto Assumptions = getAssumptions(CB);
11993 if (const Function *F = CB.getCaller())
11994 set_union(Assumptions, getAssumptions(*F));
11995 if (Function *F = IRP.getAssociatedFunction())
11996 set_union(Assumptions, getAssumptions(*F));
11997 return Assumptions;
11998 }
11999};
12000} // namespace
12001
12003 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12004 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12005}
12006
12008
12009/// ------------------------ UnderlyingObjects ---------------------------------
12010
12011namespace {
12012struct AAUnderlyingObjectsImpl
12013 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12015 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12016
12017 /// See AbstractAttribute::getAsStr().
12018 const std::string getAsStr(Attributor *A) const override {
12019 if (!isValidState())
12020 return "<invalid>";
12021 std::string Str;
12023 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12024 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12025 << " objects.\n";
12026 if (!InterAssumedUnderlyingObjects.empty()) {
12027 OS << "inter objects:\n";
12028 for (auto *Obj : InterAssumedUnderlyingObjects)
12029 OS << *Obj << '\n';
12030 }
12031 if (!IntraAssumedUnderlyingObjects.empty()) {
12032 OS << "intra objects:\n";
12033 for (auto *Obj : IntraAssumedUnderlyingObjects)
12034 OS << *Obj << '\n';
12035 }
12036 return Str;
12037 }
12038
12039 /// See AbstractAttribute::trackStatistics()
12040 void trackStatistics() const override {}
12041
12042 /// See AbstractAttribute::updateImpl(...).
12043 ChangeStatus updateImpl(Attributor &A) override {
12044 auto &Ptr = getAssociatedValue();
12045
12046 bool UsedAssumedInformation = false;
12047 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12049 SmallPtrSet<Value *, 8> SeenObjects;
12051
12052 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12053 Scope, UsedAssumedInformation))
12054 return UnderlyingObjects.insert(&Ptr);
12055
12056 bool Changed = false;
12057
12058 for (unsigned I = 0; I < Values.size(); ++I) {
12059 auto &VAC = Values[I];
12060 auto *Obj = VAC.getValue();
12061 Value *UO = getUnderlyingObject(Obj);
12062 if (!SeenObjects.insert(UO ? UO : Obj).second)
12063 continue;
12064 if (UO && UO != Obj) {
12065 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12066 Changed |= UnderlyingObjects.insert(UO);
12067 continue;
12068 }
12069
12070 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12071 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12072 auto Pred = [&](Value &V) {
12073 if (&V == UO)
12074 Changed |= UnderlyingObjects.insert(UO);
12075 else
12076 Values.emplace_back(V, nullptr);
12077 return true;
12078 };
12079
12080 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12082 "The forall call should not return false at this position");
12083 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12084 continue;
12085 }
12086
12087 if (isa<SelectInst>(Obj)) {
12088 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12089 UsedAssumedInformation);
12090 continue;
12091 }
12092 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12093 // Explicitly look through PHIs as we do not care about dynamically
12094 // uniqueness.
12095 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12096 Changed |=
12097 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12098 Scope, UsedAssumedInformation);
12099 }
12100 continue;
12101 }
12102
12103 Changed |= UnderlyingObjects.insert(Obj);
12104 }
12105
12106 return Changed;
12107 };
12108
12109 bool Changed = false;
12110 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12111 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12112 if (!UsedAssumedInformation)
12113 indicateOptimisticFixpoint();
12114 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12115 }
12116
12117 bool forallUnderlyingObjects(
12118 function_ref<bool(Value &)> Pred,
12119 AA::ValueScope Scope = AA::Interprocedural) const override {
12120 if (!isValidState())
12121 return Pred(getAssociatedValue());
12122
12123 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12124 ? IntraAssumedUnderlyingObjects
12125 : InterAssumedUnderlyingObjects;
12126 for (Value *Obj : AssumedUnderlyingObjects)
12127 if (!Pred(*Obj))
12128 return false;
12129
12130 return true;
12131 }
12132
12133private:
12134 /// Handle the case where the value is not the actual underlying value, such
12135 /// as a phi node or a select instruction.
12136 bool handleIndirect(Attributor &A, Value &V,
12137 SmallSetVector<Value *, 8> &UnderlyingObjects,
12138 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12139 bool Changed = false;
12140 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12141 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12142 auto Pred = [&](Value &V) {
12143 Changed |= UnderlyingObjects.insert(&V);
12144 return true;
12145 };
12146 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12148 "The forall call should not return false at this position");
12149 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12150 return Changed;
12151 }
12152
12153 /// All the underlying objects collected so far via intra procedural scope.
12154 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12155 /// All the underlying objects collected so far via inter procedural scope.
12156 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12157};
12158
12159struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12160 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12161 : AAUnderlyingObjectsImpl(IRP, A) {}
12162};
12163
12164struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12165 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12166 : AAUnderlyingObjectsImpl(IRP, A) {}
12167};
12168
12169struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12170 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12171 : AAUnderlyingObjectsImpl(IRP, A) {}
12172};
12173
12174struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12175 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12176 : AAUnderlyingObjectsImpl(IRP, A) {}
12177};
12178
12179struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12180 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12181 : AAUnderlyingObjectsImpl(IRP, A) {}
12182};
12183
12184struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12185 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12186 : AAUnderlyingObjectsImpl(IRP, A) {}
12187};
12188
12189struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12190 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12191 : AAUnderlyingObjectsImpl(IRP, A) {}
12192};
12193} // namespace
12194
12195/// ------------------------ Global Value Info -------------------------------
12196namespace {
12197struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12198 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12199 : AAGlobalValueInfo(IRP, A) {}
12200
12201 /// See AbstractAttribute::initialize(...).
12202 void initialize(Attributor &A) override {}
12203
12204 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12205 SmallVectorImpl<const Value *> &Worklist) {
12206 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12207 if (!UInst) {
12208 Follow = true;
12209 return true;
12210 }
12211
12212 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12213 << *UInst << "\n");
12214
12215 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12216 int Idx = &Cmp->getOperandUse(0) == &U;
12217 if (isa<Constant>(Cmp->getOperand(Idx)))
12218 return true;
12219 return U == &getAnchorValue();
12220 }
12221
12222 // Explicitly catch return instructions.
12223 if (isa<ReturnInst>(UInst)) {
12224 auto CallSitePred = [&](AbstractCallSite ACS) {
12225 Worklist.push_back(ACS.getInstruction());
12226 return true;
12227 };
12228 bool UsedAssumedInformation = false;
12229 // TODO: We should traverse the uses or add a "non-call-site" CB.
12230 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12231 /*RequireAllCallSites=*/true, this,
12232 UsedAssumedInformation))
12233 return false;
12234 return true;
12235 }
12236
12237 // For now we only use special logic for call sites. However, the tracker
12238 // itself knows about a lot of other non-capturing cases already.
12239 auto *CB = dyn_cast<CallBase>(UInst);
12240 if (!CB)
12241 return false;
12242 // Direct calls are OK uses.
12243 if (CB->isCallee(&U))
12244 return true;
12245 // Non-argument uses are scary.
12246 if (!CB->isArgOperand(&U))
12247 return false;
12248 // TODO: Iterate callees.
12249 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12250 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12251 return false;
12252
12253 unsigned ArgNo = CB->getArgOperandNo(&U);
12254 Worklist.push_back(Fn->getArg(ArgNo));
12255 return true;
12256 }
12257
12258 ChangeStatus updateImpl(Attributor &A) override {
12259 unsigned NumUsesBefore = Uses.size();
12260
12261 SmallPtrSet<const Value *, 8> Visited;
12263 Worklist.push_back(&getAnchorValue());
12264
12265 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12266 Uses.insert(&U);
12267 // TODO(captures): Make this more precise.
12268 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12269 if (CI.isPassthrough()) {
12270 Follow = true;
12271 return true;
12272 }
12273 return checkUse(A, U, Follow, Worklist);
12274 };
12275 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12276 Uses.insert(&OldU);
12277 return true;
12278 };
12279
12280 while (!Worklist.empty()) {
12281 const Value *V = Worklist.pop_back_val();
12282 if (!Visited.insert(V).second)
12283 continue;
12284 if (!A.checkForAllUses(UsePred, *this, *V,
12285 /* CheckBBLivenessOnly */ true,
12286 DepClassTy::OPTIONAL,
12287 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12288 return indicatePessimisticFixpoint();
12289 }
12290 }
12291
12292 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12293 : ChangeStatus::CHANGED;
12294 }
12295
12296 bool isPotentialUse(const Use &U) const override {
12297 return !isValidState() || Uses.contains(&U);
12298 }
12299
12300 /// See AbstractAttribute::manifest(...).
12301 ChangeStatus manifest(Attributor &A) override {
12302 return ChangeStatus::UNCHANGED;
12303 }
12304
12305 /// See AbstractAttribute::getAsStr().
12306 const std::string getAsStr(Attributor *A) const override {
12307 return "[" + std::to_string(Uses.size()) + " uses]";
12308 }
12309
12310 void trackStatistics() const override {
12311 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12312 }
12313
12314private:
12315 /// Set of (transitive) uses of this GlobalValue.
12316 SmallPtrSet<const Use *, 8> Uses;
12317};
12318} // namespace
12319
12320/// ------------------------ Indirect Call Info -------------------------------
12321namespace {
12322struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12323 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12324 : AAIndirectCallInfo(IRP, A) {}
12325
12326 /// See AbstractAttribute::initialize(...).
12327 void initialize(Attributor &A) override {
12328 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12329 if (!MD && !A.isClosedWorldModule())
12330 return;
12331
12332 if (MD) {
12333 for (const auto &Op : MD->operands())
12334 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12335 PotentialCallees.insert(Callee);
12336 } else if (A.isClosedWorldModule()) {
12337 ArrayRef<Function *> IndirectlyCallableFunctions =
12338 A.getInfoCache().getIndirectlyCallableFunctions(A);
12339 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12340 }
12341
12342 if (PotentialCallees.empty())
12343 indicateOptimisticFixpoint();
12344 }
12345
12346 ChangeStatus updateImpl(Attributor &A) override {
12347 CallBase *CB = cast<CallBase>(getCtxI());
12348 const Use &CalleeUse = CB->getCalledOperandUse();
12349 Value *FP = CB->getCalledOperand();
12350
12351 SmallSetVector<Function *, 4> AssumedCalleesNow;
12352 bool AllCalleesKnownNow = AllCalleesKnown;
12353
12354 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12355 bool &UsedAssumedInformation) {
12356 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12357 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12358 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12359 return true;
12360 UsedAssumedInformation = !GIAA->isAtFixpoint();
12361 return false;
12362 };
12363
12364 auto AddPotentialCallees = [&]() {
12365 for (auto *PotentialCallee : PotentialCallees) {
12366 bool UsedAssumedInformation = false;
12367 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12368 AssumedCalleesNow.insert(PotentialCallee);
12369 }
12370 };
12371
12372 // Use simplification to find potential callees, if !callees was present,
12373 // fallback to that set if necessary.
12374 bool UsedAssumedInformation = false;
12376 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12377 AA::ValueScope::AnyScope,
12378 UsedAssumedInformation)) {
12379 if (PotentialCallees.empty())
12380 return indicatePessimisticFixpoint();
12381 AddPotentialCallees();
12382 }
12383
12384 // Try to find a reason for \p Fn not to be a potential callee. If none was
12385 // found, add it to the assumed callees set.
12386 auto CheckPotentialCallee = [&](Function &Fn) {
12387 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12388 return false;
12389
12390 auto &CachedResult = FilterResults[&Fn];
12391 if (CachedResult.has_value())
12392 return CachedResult.value();
12393
12394 bool UsedAssumedInformation = false;
12395 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12396 if (!UsedAssumedInformation)
12397 CachedResult = false;
12398 return false;
12399 }
12400
12401 int NumFnArgs = Fn.arg_size();
12402 int NumCBArgs = CB->arg_size();
12403
12404 // Check if any excess argument (which we fill up with poison) is known to
12405 // be UB on undef.
12406 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12407 bool IsKnown = false;
12409 A, this, IRPosition::argument(*Fn.getArg(I)),
12410 DepClassTy::OPTIONAL, IsKnown)) {
12411 if (IsKnown)
12412 CachedResult = false;
12413 return false;
12414 }
12415 }
12416
12417 CachedResult = true;
12418 return true;
12419 };
12420
12421 // Check simplification result, prune known UB callees, also restrict it to
12422 // the !callees set, if present.
12423 for (auto &VAC : Values) {
12424 if (isa<UndefValue>(VAC.getValue()))
12425 continue;
12427 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12428 continue;
12429 // TODO: Check for known UB, e.g., poison + noundef.
12430 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12431 if (CheckPotentialCallee(*VACFn))
12432 AssumedCalleesNow.insert(VACFn);
12433 continue;
12434 }
12435 if (!PotentialCallees.empty()) {
12436 AddPotentialCallees();
12437 break;
12438 }
12439 AllCalleesKnownNow = false;
12440 }
12441
12442 if (AssumedCalleesNow == AssumedCallees &&
12443 AllCalleesKnown == AllCalleesKnownNow)
12444 return ChangeStatus::UNCHANGED;
12445
12446 std::swap(AssumedCallees, AssumedCalleesNow);
12447 AllCalleesKnown = AllCalleesKnownNow;
12448 return ChangeStatus::CHANGED;
12449 }
12450
12451 /// See AbstractAttribute::manifest(...).
12452 ChangeStatus manifest(Attributor &A) override {
12453 // If we can't specialize at all, give up now.
12454 if (!AllCalleesKnown && AssumedCallees.empty())
12455 return ChangeStatus::UNCHANGED;
12456
12457 CallBase *CB = cast<CallBase>(getCtxI());
12458 bool UsedAssumedInformation = false;
12459 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12460 UsedAssumedInformation))
12461 return ChangeStatus::UNCHANGED;
12462
12463 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12464 Value *FP = CB->getCalledOperand();
12465 if (FP->getType()->getPointerAddressSpace())
12466 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12467 FP->getName() + ".as0", CB->getIterator());
12468
12469 bool CBIsVoid = CB->getType()->isVoidTy();
12471 FunctionType *CSFT = CB->getFunctionType();
12472 SmallVector<Value *> CSArgs(CB->args());
12473
12474 // If we know all callees and there are none, the call site is (effectively)
12475 // dead (or UB).
12476 if (AssumedCallees.empty()) {
12477 assert(AllCalleesKnown &&
12478 "Expected all callees to be known if there are none.");
12479 A.changeToUnreachableAfterManifest(CB);
12480 return ChangeStatus::CHANGED;
12481 }
12482
12483 // Special handling for the single callee case.
12484 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12485 auto *NewCallee = AssumedCallees.front();
12486 if (isLegalToPromote(*CB, NewCallee)) {
12487 promoteCall(*CB, NewCallee, nullptr);
12488 NumIndirectCallsPromoted++;
12489 return ChangeStatus::CHANGED;
12490 }
12491 Instruction *NewCall =
12492 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12493 CB->getName(), CB->getIterator());
12494 if (!CBIsVoid)
12495 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12496 A.deleteAfterManifest(*CB);
12497 return ChangeStatus::CHANGED;
12498 }
12499
12500 // For each potential value we create a conditional
12501 //
12502 // ```
12503 // if (ptr == value) value(args);
12504 // else ...
12505 // ```
12506 //
12507 bool SpecializedForAnyCallees = false;
12508 bool SpecializedForAllCallees = AllCalleesKnown;
12509 ICmpInst *LastCmp = nullptr;
12510 SmallVector<Function *, 8> SkippedAssumedCallees;
12512 for (Function *NewCallee : AssumedCallees) {
12513 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12514 AssumedCallees.size())) {
12515 SkippedAssumedCallees.push_back(NewCallee);
12516 SpecializedForAllCallees = false;
12517 continue;
12518 }
12519 SpecializedForAnyCallees = true;
12520
12521 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12522 Instruction *ThenTI =
12523 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12524 BasicBlock *CBBB = CB->getParent();
12525 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12526 A.registerManifestAddedBasicBlock(*IP->getParent());
12527 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12528 BasicBlock *ElseBB;
12529 if (&*IP == CB) {
12530 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12531 ThenTI->getFunction(), CBBB);
12532 A.registerManifestAddedBasicBlock(*ElseBB);
12533 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12534 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12535 } else {
12536 ElseBB = IP->getParent();
12537 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12538 }
12539 CastInst *RetBC = nullptr;
12540 CallInst *NewCall = nullptr;
12541 if (isLegalToPromote(*CB, NewCallee)) {
12542 auto *CBClone = cast<CallBase>(CB->clone());
12543 CBClone->insertBefore(ThenTI->getIterator());
12544 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12545 NumIndirectCallsPromoted++;
12546 } else {
12547 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12548 CB->getName(), ThenTI->getIterator());
12549 }
12550 NewCalls.push_back({NewCall, RetBC});
12551 }
12552
12553 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12554 if (!AllCalleesKnown)
12555 return ChangeStatus::UNCHANGED;
12556 MDBuilder MDB(IndirectCB.getContext());
12557 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12558 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12559 return ChangeStatus::CHANGED;
12560 };
12561
12562 if (!SpecializedForAnyCallees)
12563 return AttachCalleeMetadata(*CB);
12564
12565 // Check if we need the fallback indirect call still.
12566 if (SpecializedForAllCallees) {
12568 LastCmp->eraseFromParent();
12569 new UnreachableInst(IP->getContext(), IP);
12570 IP->eraseFromParent();
12571 } else {
12572 auto *CBClone = cast<CallInst>(CB->clone());
12573 CBClone->setName(CB->getName());
12574 CBClone->insertBefore(*IP->getParent(), IP);
12575 NewCalls.push_back({CBClone, nullptr});
12576 AttachCalleeMetadata(*CBClone);
12577 }
12578
12579 // Check if we need a PHI to merge the results.
12580 if (!CBIsVoid) {
12581 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12582 CB->getName() + ".phi",
12583 CB->getParent()->getFirstInsertionPt());
12584 for (auto &It : NewCalls) {
12585 CallBase *NewCall = It.first;
12586 Instruction *CallRet = It.second ? It.second : It.first;
12587 if (CallRet->getType() == CB->getType())
12588 PHI->addIncoming(CallRet, CallRet->getParent());
12589 else if (NewCall->getType()->isVoidTy())
12590 PHI->addIncoming(PoisonValue::get(CB->getType()),
12591 NewCall->getParent());
12592 else
12593 llvm_unreachable("Call return should match or be void!");
12594 }
12595 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12596 }
12597
12598 A.deleteAfterManifest(*CB);
12599 Changed = ChangeStatus::CHANGED;
12600
12601 return Changed;
12602 }
12603
12604 /// See AbstractAttribute::getAsStr().
12605 const std::string getAsStr(Attributor *A) const override {
12606 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12607 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12608 " functions";
12609 }
12610
12611 void trackStatistics() const override {
12612 if (AllCalleesKnown) {
12614 Eliminated, CallSites,
12615 "Number of indirect call sites eliminated via specialization")
12616 } else {
12617 STATS_DECLTRACK(Specialized, CallSites,
12618 "Number of indirect call sites specialized")
12619 }
12620 }
12621
12622 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12623 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12624 }
12625
12626private:
12627 /// Map to remember filter results.
12628 DenseMap<Function *, std::optional<bool>> FilterResults;
12629
12630 /// If the !callee metadata was present, this set will contain all potential
12631 /// callees (superset).
12632 SmallSetVector<Function *, 4> PotentialCallees;
12633
12634 /// This set contains all currently assumed calllees, which might grow over
12635 /// time.
12636 SmallSetVector<Function *, 4> AssumedCallees;
12637
12638 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12639 /// if there could be others.
12640 bool AllCalleesKnown = true;
12641};
12642} // namespace
12643
12644/// --------------------- Invariant Load Pointer -------------------------------
12645namespace {
12646
12647struct AAInvariantLoadPointerImpl
12648 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12649 AAInvariantLoadPointer> {
12650
12651 enum {
12652 // pointer does not alias within the bounds of the function
12653 IS_NOALIAS = 1 << 0,
12654 // pointer is not involved in any effectful instructions within the bounds
12655 // of the function
12656 IS_NOEFFECT = 1 << 1,
12657 // loads are invariant within the bounds of the function
12658 IS_LOCALLY_INVARIANT = 1 << 2,
12659 // memory lifetime is constrained within the bounds of the function
12660 IS_LOCALLY_CONSTRAINED = 1 << 3,
12661
12662 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12663 IS_LOCALLY_CONSTRAINED,
12664 };
12665 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12666
12667 using Base =
12668 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12669
12670 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12671 // pessimistic about IS_KNOWN_INVARIANT
12672 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12673 : Base(IRP) {}
12674
12675 bool isKnownInvariant() const final {
12676 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12677 }
12678
12679 bool isKnownLocallyInvariant() const final {
12680 if (isKnown(IS_LOCALLY_INVARIANT))
12681 return true;
12682 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12683 }
12684
12685 bool isAssumedInvariant() const final {
12686 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12687 }
12688
12689 bool isAssumedLocallyInvariant() const final {
12690 if (isAssumed(IS_LOCALLY_INVARIANT))
12691 return true;
12692 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12693 }
12694
12695 ChangeStatus updateImpl(Attributor &A) override {
12696 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12697
12698 Changed |= updateNoAlias(A);
12699 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12700 return indicatePessimisticFixpoint();
12701
12702 Changed |= updateNoEffect(A);
12703
12704 Changed |= updateLocalInvariance(A);
12705
12706 return Changed;
12707 }
12708
12709 ChangeStatus manifest(Attributor &A) override {
12710 if (!isKnownInvariant())
12711 return ChangeStatus::UNCHANGED;
12712
12713 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12714 const Value *Ptr = &getAssociatedValue();
12715 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12716 if (U.get() != Ptr)
12717 return true;
12718 auto *I = dyn_cast<Instruction>(U.getUser());
12719 if (!I)
12720 return true;
12721
12722 // Ensure that we are only changing uses from the corresponding callgraph
12723 // SSC in the case that the AA isn't run on the entire module
12724 if (!A.isRunOn(I->getFunction()))
12725 return true;
12726
12727 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12728 return true;
12729
12730 if (auto *LI = dyn_cast<LoadInst>(I)) {
12731 LI->setMetadata(LLVMContext::MD_invariant_load,
12732 MDNode::get(LI->getContext(), {}));
12733 Changed = ChangeStatus::CHANGED;
12734 }
12735 return true;
12736 };
12737
12738 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12739 return Changed;
12740 }
12741
12742 /// See AbstractAttribute::getAsStr().
12743 const std::string getAsStr(Attributor *) const override {
12744 if (isKnownInvariant())
12745 return "load-invariant pointer";
12746 return "non-invariant pointer";
12747 }
12748
12749 /// See AbstractAttribute::trackStatistics().
12750 void trackStatistics() const override {}
12751
12752private:
12753 /// Indicate that noalias is required for the pointer to be invariant.
12754 bool requiresNoAlias() const {
12755 switch (getPositionKind()) {
12756 default:
12757 // Conservatively default to require noalias.
12758 return true;
12759 case IRP_FLOAT:
12760 case IRP_RETURNED:
12761 case IRP_CALL_SITE:
12762 return false;
12763 case IRP_CALL_SITE_RETURNED: {
12764 const auto &CB = cast<CallBase>(getAnchorValue());
12766 &CB, /*MustPreserveNullness=*/false);
12767 }
12768 case IRP_ARGUMENT: {
12769 const Function *F = getAssociatedFunction();
12770 assert(F && "no associated function for argument");
12771 return !isCallableCC(F->getCallingConv());
12772 }
12773 }
12774 }
12775
12776 bool isExternal() const {
12777 const Function *F = getAssociatedFunction();
12778 if (!F)
12779 return true;
12780 return isCallableCC(F->getCallingConv()) &&
12781 getPositionKind() != IRP_CALL_SITE_RETURNED;
12782 }
12783
12784 ChangeStatus updateNoAlias(Attributor &A) {
12785 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12786 return ChangeStatus::UNCHANGED;
12787
12788 // Try to use AANoAlias.
12789 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12790 getIRPosition(), this, DepClassTy::REQUIRED)) {
12791 if (ANoAlias->isKnownNoAlias()) {
12792 addKnownBits(IS_NOALIAS);
12793 return ChangeStatus::CHANGED;
12794 }
12795
12796 if (!ANoAlias->isAssumedNoAlias()) {
12797 removeAssumedBits(IS_NOALIAS);
12798 return ChangeStatus::CHANGED;
12799 }
12800
12801 return ChangeStatus::UNCHANGED;
12802 }
12803
12804 // Try to infer noalias from argument attribute, since it is applicable for
12805 // the duration of the function.
12806 if (const Argument *Arg = getAssociatedArgument()) {
12807 if (Arg->hasNoAliasAttr()) {
12808 addKnownBits(IS_NOALIAS);
12809 return ChangeStatus::UNCHANGED;
12810 }
12811
12812 // Noalias information is not provided, and cannot be inferred,
12813 // so we conservatively assume the pointer aliases.
12814 removeAssumedBits(IS_NOALIAS);
12815 return ChangeStatus::CHANGED;
12816 }
12817
12818 return ChangeStatus::UNCHANGED;
12819 }
12820
12821 ChangeStatus updateNoEffect(Attributor &A) {
12822 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12823 return ChangeStatus::UNCHANGED;
12824
12825 if (!getAssociatedFunction())
12826 return indicatePessimisticFixpoint();
12827
12828 if (isa<AllocaInst>(&getAssociatedValue()))
12829 return indicatePessimisticFixpoint();
12830
12831 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12832 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12833 return !LI || !LI->mayHaveSideEffects();
12834 };
12835 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12836 return indicatePessimisticFixpoint();
12837
12838 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12839 getIRPosition(), this, DepClassTy::REQUIRED)) {
12840 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12841 // attribute
12842 if (!AMemoryBehavior->isAssumedReadOnly())
12843 return indicatePessimisticFixpoint();
12844
12845 if (AMemoryBehavior->isKnownReadOnly()) {
12846 addKnownBits(IS_NOEFFECT);
12847 return ChangeStatus::UNCHANGED;
12848 }
12849
12850 return ChangeStatus::UNCHANGED;
12851 }
12852
12853 if (const Argument *Arg = getAssociatedArgument()) {
12854 if (Arg->onlyReadsMemory()) {
12855 addKnownBits(IS_NOEFFECT);
12856 return ChangeStatus::UNCHANGED;
12857 }
12858
12859 // Readonly information is not provided, and cannot be inferred from
12860 // AAMemoryBehavior.
12861 return indicatePessimisticFixpoint();
12862 }
12863
12864 return ChangeStatus::UNCHANGED;
12865 }
12866
12867 ChangeStatus updateLocalInvariance(Attributor &A) {
12868 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12869 return ChangeStatus::UNCHANGED;
12870
12871 // try to infer invariance from underlying objects
12872 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12873 getIRPosition(), this, DepClassTy::REQUIRED);
12874 if (!AUO)
12875 return ChangeStatus::UNCHANGED;
12876
12877 bool UsedAssumedInformation = false;
12878 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12879 if (!V.getType()->isPointerTy())
12880 return true;
12881 const auto *IsInvariantLoadPointer =
12882 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12883 DepClassTy::REQUIRED);
12884 // Conservatively fail if invariance cannot be inferred.
12885 if (!IsInvariantLoadPointer)
12886 return false;
12887
12888 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12889 return true;
12890 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12891 return false;
12892
12893 UsedAssumedInformation = true;
12894 return true;
12895 };
12896 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12897 return indicatePessimisticFixpoint();
12898
12899 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12901 CB, /*MustPreserveNullness=*/false)) {
12902 for (const Value *Arg : CB->args()) {
12903 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12904 return indicatePessimisticFixpoint();
12905 }
12906 }
12907 }
12908
12909 if (!UsedAssumedInformation) {
12910 // Pointer is known and not just assumed to be locally invariant.
12911 addKnownBits(IS_LOCALLY_INVARIANT);
12912 return ChangeStatus::CHANGED;
12913 }
12914
12915 return ChangeStatus::UNCHANGED;
12916 }
12917};
12918
12919struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12920 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12921 : AAInvariantLoadPointerImpl(IRP, A) {}
12922};
12923
12924struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12925 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12926 : AAInvariantLoadPointerImpl(IRP, A) {}
12927
12928 void initialize(Attributor &) override {
12929 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12930 }
12931};
12932
12933struct AAInvariantLoadPointerCallSiteReturned final
12934 : AAInvariantLoadPointerImpl {
12935 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12936 : AAInvariantLoadPointerImpl(IRP, A) {}
12937
12938 void initialize(Attributor &A) override {
12939 const Function *F = getAssociatedFunction();
12940 assert(F && "no associated function for return from call");
12941
12942 if (!F->isDeclaration() && !F->isIntrinsic())
12943 return AAInvariantLoadPointerImpl::initialize(A);
12944
12945 const auto &CB = cast<CallBase>(getAnchorValue());
12947 &CB, /*MustPreserveNullness=*/false))
12948 return AAInvariantLoadPointerImpl::initialize(A);
12949
12950 if (F->onlyReadsMemory() && F->hasNoSync())
12951 return AAInvariantLoadPointerImpl::initialize(A);
12952
12953 // At this point, the function is opaque, so we conservatively assume
12954 // non-invariance.
12955 indicatePessimisticFixpoint();
12956 }
12957};
12958
12959struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12960 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12961 : AAInvariantLoadPointerImpl(IRP, A) {}
12962
12963 void initialize(Attributor &) override {
12964 const Function *F = getAssociatedFunction();
12965 assert(F && "no associated function for argument");
12966
12967 if (!isCallableCC(F->getCallingConv())) {
12968 addKnownBits(IS_LOCALLY_CONSTRAINED);
12969 return;
12970 }
12971
12972 if (!F->hasLocalLinkage())
12973 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12974 }
12975};
12976
12977struct AAInvariantLoadPointerCallSiteArgument final
12978 : AAInvariantLoadPointerImpl {
12979 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12980 : AAInvariantLoadPointerImpl(IRP, A) {}
12981};
12982} // namespace
12983
12984/// ------------------------ Address Space ------------------------------------
12985namespace {
12986
12987template <typename InstType>
12988static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12989 Value *OriginalValue, PointerType *NewPtrTy,
12990 bool UseOriginalValue) {
12991 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12992 return false;
12993
12994 if (MemInst->isVolatile()) {
12995 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12996 *MemInst->getFunction());
12997 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12998 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12999 return false;
13000 }
13001
13002 if (UseOriginalValue) {
13003 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13004 return true;
13005 }
13006
13007 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13008 CastInst->insertBefore(MemInst->getIterator());
13009 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13010 return true;
13011}
13012
13013struct AAAddressSpaceImpl : public AAAddressSpace {
13014 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13015 : AAAddressSpace(IRP, A) {}
13016
13017 uint32_t getAddressSpace() const override {
13018 assert(isValidState() && "the AA is invalid");
13019 return AssumedAddressSpace;
13020 }
13021
13022 /// See AbstractAttribute::initialize(...).
13023 void initialize(Attributor &A) override {
13024 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13025 "Associated value is not a pointer");
13026
13027 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13028 indicatePessimisticFixpoint();
13029 return;
13030 }
13031
13032 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13033 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13034 if (AS != FlatAS) {
13035 [[maybe_unused]] bool R = takeAddressSpace(AS);
13036 assert(R && "The take should happen");
13037 indicateOptimisticFixpoint();
13038 }
13039 }
13040
13041 ChangeStatus updateImpl(Attributor &A) override {
13042 uint32_t OldAddressSpace = AssumedAddressSpace;
13043 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13044
13045 auto CheckAddressSpace = [&](Value &Obj) {
13046 // Ignore undef.
13047 if (isa<UndefValue>(&Obj))
13048 return true;
13049
13050 // If the object already has a non-flat address space, we simply take it.
13051 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13052 if (ObjAS != FlatAS)
13053 return takeAddressSpace(ObjAS);
13054
13055 // At this point, we know Obj is in the flat address space. For a final
13056 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13057 // associated function, if possible.
13058 Function *F = nullptr;
13059 if (auto *Arg = dyn_cast<Argument>(&Obj))
13060 F = Arg->getParent();
13061 else if (auto *I = dyn_cast<Instruction>(&Obj))
13062 F = I->getFunction();
13063
13064 // Use getAssumedAddrSpace if the associated function exists.
13065 if (F) {
13066 auto *TTI =
13067 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13068 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13069 if (AssumedAS != ~0U)
13070 return takeAddressSpace(AssumedAS);
13071 }
13072
13073 // Now we can't do anything else but to take the flat AS.
13074 return takeAddressSpace(FlatAS);
13075 };
13076
13077 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13078 DepClassTy::REQUIRED);
13079 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13080 return indicatePessimisticFixpoint();
13081
13082 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13083 : ChangeStatus::CHANGED;
13084 }
13085
13086 /// See AbstractAttribute::manifest(...).
13087 ChangeStatus manifest(Attributor &A) override {
13088 unsigned NewAS = getAddressSpace();
13089
13090 if (NewAS == InvalidAddressSpace ||
13091 NewAS == getAssociatedType()->getPointerAddressSpace())
13092 return ChangeStatus::UNCHANGED;
13093
13094 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13095
13096 Value *AssociatedValue = &getAssociatedValue();
13097 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13098
13099 PointerType *NewPtrTy =
13100 PointerType::get(getAssociatedType()->getContext(), NewAS);
13101 bool UseOriginalValue =
13102 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13103
13104 bool Changed = false;
13105
13106 auto Pred = [&](const Use &U, bool &) {
13107 if (U.get() != AssociatedValue)
13108 return true;
13109 auto *Inst = dyn_cast<Instruction>(U.getUser());
13110 if (!Inst)
13111 return true;
13112 // This is a WA to make sure we only change uses from the corresponding
13113 // CGSCC if the AA is run on CGSCC instead of the entire module.
13114 if (!A.isRunOn(Inst->getFunction()))
13115 return true;
13116 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13117 Changed |=
13118 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13119 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13120 Changed |=
13121 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13122 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13123 Changed |=
13124 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13125 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13126 Changed |=
13127 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13128 }
13129 return true;
13130 };
13131
13132 // It doesn't matter if we can't check all uses as we can simply
13133 // conservatively ignore those that can not be visited.
13134 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13135 /* CheckBBLivenessOnly */ true);
13136
13137 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13138 }
13139
13140 /// See AbstractAttribute::getAsStr().
13141 const std::string getAsStr(Attributor *A) const override {
13142 if (!isValidState())
13143 return "addrspace(<invalid>)";
13144 return "addrspace(" +
13145 (AssumedAddressSpace == InvalidAddressSpace
13146 ? "none"
13147 : std::to_string(AssumedAddressSpace)) +
13148 ")";
13149 }
13150
13151private:
13152 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13153
13154 bool takeAddressSpace(uint32_t AS) {
13155 if (AssumedAddressSpace == InvalidAddressSpace) {
13156 AssumedAddressSpace = AS;
13157 return true;
13158 }
13159 return AssumedAddressSpace == AS;
13160 }
13161
13162 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13163 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13164 assert(I->getSrcAddressSpace() != FlatAS &&
13165 "there should not be flat AS -> non-flat AS");
13166 return I->getPointerOperand();
13167 }
13168 if (auto *C = dyn_cast<ConstantExpr>(V))
13169 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13170 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13171 FlatAS &&
13172 "there should not be flat AS -> non-flat AS X");
13173 return C->getOperand(0);
13174 }
13175 return V;
13176 }
13177};
13178
13179struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13180 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13181 : AAAddressSpaceImpl(IRP, A) {}
13182
13183 void trackStatistics() const override {
13185 }
13186};
13187
13188struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13189 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13190 : AAAddressSpaceImpl(IRP, A) {}
13191
13192 /// See AbstractAttribute::initialize(...).
13193 void initialize(Attributor &A) override {
13194 // TODO: we don't rewrite function argument for now because it will need to
13195 // rewrite the function signature and all call sites.
13196 (void)indicatePessimisticFixpoint();
13197 }
13198
13199 void trackStatistics() const override {
13200 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13201 }
13202};
13203
13204struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13205 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13206 : AAAddressSpaceImpl(IRP, A) {}
13207
13208 void trackStatistics() const override {
13209 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13210 }
13211};
13212
13213struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13214 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13215 : AAAddressSpaceImpl(IRP, A) {}
13216
13217 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13218};
13219
13220struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13221 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13222 : AAAddressSpaceImpl(IRP, A) {}
13223
13224 /// See AbstractAttribute::initialize(...).
13225 void initialize(Attributor &A) override {
13226 // TODO: we don't rewrite call site argument for now because it will need to
13227 // rewrite the function signature of the callee.
13228 (void)indicatePessimisticFixpoint();
13229 }
13230
13231 void trackStatistics() const override {
13232 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13233 }
13234};
13235} // namespace
13236
13237/// ------------------------ No Alias Address Space ---------------------------
13238// This attribute assumes flat address space can alias all other address space
13239
13240// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13241// But merging it created failing cased on gateway test that cannot be
13242// reproduced locally. So should open a separated PR to handle the merge of
13243// AANoAliasAddrSpace and AAAddressSpace attribute
13244
13245namespace {
13246struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13247 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13248 : AANoAliasAddrSpace(IRP, A) {}
13249
13250 void initialize(Attributor &A) override {
13251 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13252 "Associated value is not a pointer");
13253
13254 resetASRanges(A);
13255
13256 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13257 if (!FlatAS.has_value()) {
13258 indicatePessimisticFixpoint();
13259 return;
13260 }
13261
13262 removeAS(*FlatAS);
13263
13264 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13265 if (AS != *FlatAS) {
13266 removeAS(AS);
13267 indicateOptimisticFixpoint();
13268 }
13269 }
13270
13271 ChangeStatus updateImpl(Attributor &A) override {
13272 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13273 uint32_t OldAssumed = getAssumed();
13274
13275 auto CheckAddressSpace = [&](Value &Obj) {
13276 if (isa<PoisonValue>(&Obj))
13277 return true;
13278
13279 unsigned AS = Obj.getType()->getPointerAddressSpace();
13280 if (AS == FlatAS)
13281 return false;
13282
13283 removeAS(Obj.getType()->getPointerAddressSpace());
13284 return true;
13285 };
13286
13287 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13288 getIRPosition(), this, DepClassTy::REQUIRED);
13289 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13290 return indicatePessimisticFixpoint();
13291
13292 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13293 : ChangeStatus::CHANGED;
13294 }
13295
13296 /// See AbstractAttribute::manifest(...).
13297 ChangeStatus manifest(Attributor &A) override {
13298 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13299
13300 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13301 if (AS != FlatAS || Map.empty())
13302 return ChangeStatus::UNCHANGED;
13303
13304 LLVMContext &Ctx = getAssociatedValue().getContext();
13305 MDNode *NoAliasASNode = nullptr;
13306 MDBuilder MDB(Ctx);
13307 // Has to use iterator to get the range info.
13308 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13309 if (!I.value())
13310 continue;
13311 unsigned Upper = I.stop();
13312 unsigned Lower = I.start();
13313 if (!NoAliasASNode) {
13314 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13315 continue;
13316 }
13317 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13318 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13319 }
13320
13321 Value *AssociatedValue = &getAssociatedValue();
13322 bool Changed = false;
13323
13324 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13325 if (U.get() != AssociatedValue)
13326 return true;
13327 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13328 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13329 return true;
13330 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13332 return true;
13333 if (!A.isRunOn(Inst->getFunction()))
13334 return true;
13335 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13336 Changed = true;
13337 return true;
13338 };
13339 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13340 /*CheckBBLivenessOnly=*/true);
13341 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13342 }
13343
13344 /// See AbstractAttribute::getAsStr().
13345 const std::string getAsStr(Attributor *A) const override {
13346 if (!isValidState())
13347 return "<invalid>";
13348 std::string Str;
13349 raw_string_ostream OS(Str);
13350 OS << "CanNotBeAddrSpace(";
13351 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13352 unsigned Upper = I.stop();
13353 unsigned Lower = I.start();
13354 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13355 }
13356 OS << " )";
13357 return OS.str();
13358 }
13359
13360private:
13361 void removeAS(unsigned AS) {
13362 RangeMap::iterator I = Map.find(AS);
13363
13364 if (I != Map.end()) {
13365 unsigned Upper = I.stop();
13366 unsigned Lower = I.start();
13367 I.erase();
13368 if (Upper == Lower)
13369 return;
13370 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13371 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13372 if (AS != 0 && Lower <= AS - 1)
13373 Map.insert(Lower, AS - 1, true);
13374 }
13375 }
13376
13377 void resetASRanges(Attributor &A) {
13378 Map.clear();
13379 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13380 }
13381};
13382
13383struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13384 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13385 : AANoAliasAddrSpaceImpl(IRP, A) {}
13386
13387 void trackStatistics() const override {
13388 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13389 }
13390};
13391
13392struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13393 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13394 : AANoAliasAddrSpaceImpl(IRP, A) {}
13395
13396 void trackStatistics() const override {
13397 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13398 }
13399};
13400
13401struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13402 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13403 : AANoAliasAddrSpaceImpl(IRP, A) {}
13404
13405 void trackStatistics() const override {
13406 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13407 }
13408};
13409
13410struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13411 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13412 : AANoAliasAddrSpaceImpl(IRP, A) {}
13413
13414 void trackStatistics() const override {
13415 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13416 }
13417};
13418
13419struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13420 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13421 : AANoAliasAddrSpaceImpl(IRP, A) {}
13422
13423 void trackStatistics() const override {
13424 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13425 }
13426};
13427} // namespace
13428/// ----------- Allocation Info ----------
13429namespace {
13430struct AAAllocationInfoImpl : public AAAllocationInfo {
13431 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13432 : AAAllocationInfo(IRP, A) {}
13433
13434 std::optional<TypeSize> getAllocatedSize() const override {
13435 assert(isValidState() && "the AA is invalid");
13436 return AssumedAllocatedSize;
13437 }
13438
13439 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13440 const DataLayout &DL) {
13441
13442 // TODO: implement case for malloc like instructions
13443 switch (I->getOpcode()) {
13444 case Instruction::Alloca: {
13445 AllocaInst *AI = cast<AllocaInst>(I);
13446 return AI->getAllocationSize(DL);
13447 }
13448 default:
13449 return std::nullopt;
13450 }
13451 }
13452
13453 ChangeStatus updateImpl(Attributor &A) override {
13454
13455 const IRPosition &IRP = getIRPosition();
13456 Instruction *I = IRP.getCtxI();
13457
13458 // TODO: update check for malloc like calls
13459 if (!isa<AllocaInst>(I))
13460 return indicatePessimisticFixpoint();
13461
13462 bool IsKnownNoCapture;
13464 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13465 return indicatePessimisticFixpoint();
13466
13467 const AAPointerInfo *PI =
13468 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13469
13470 if (!PI)
13471 return indicatePessimisticFixpoint();
13472
13473 if (!PI->getState().isValidState() || PI->reachesReturn())
13474 return indicatePessimisticFixpoint();
13475
13476 const DataLayout &DL = A.getDataLayout();
13477 const auto AllocationSize = findInitialAllocationSize(I, DL);
13478
13479 // If allocation size is nullopt, we give up.
13480 if (!AllocationSize)
13481 return indicatePessimisticFixpoint();
13482
13483 // For zero sized allocations, we give up.
13484 // Since we can't reduce further
13485 if (*AllocationSize == 0)
13486 return indicatePessimisticFixpoint();
13487
13488 int64_t BinSize = PI->numOffsetBins();
13489
13490 // TODO: implement for multiple bins
13491 if (BinSize > 1)
13492 return indicatePessimisticFixpoint();
13493
13494 if (BinSize == 0) {
13495 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13496 if (!changeAllocationSize(NewAllocationSize))
13497 return ChangeStatus::UNCHANGED;
13498 return ChangeStatus::CHANGED;
13499 }
13500
13501 // TODO: refactor this to be part of multiple bin case
13502 const auto &It = PI->begin();
13503
13504 // TODO: handle if Offset is not zero
13505 if (It->first.Offset != 0)
13506 return indicatePessimisticFixpoint();
13507
13508 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13509
13510 if (SizeOfBin >= *AllocationSize)
13511 return indicatePessimisticFixpoint();
13512
13513 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13514
13515 if (!changeAllocationSize(NewAllocationSize))
13516 return ChangeStatus::UNCHANGED;
13517
13518 return ChangeStatus::CHANGED;
13519 }
13520
13521 /// See AbstractAttribute::manifest(...).
13522 ChangeStatus manifest(Attributor &A) override {
13523
13524 assert(isValidState() &&
13525 "Manifest should only be called if the state is valid.");
13526
13527 Instruction *I = getIRPosition().getCtxI();
13528
13529 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13530
13531 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13532
13533 switch (I->getOpcode()) {
13534 // TODO: add case for malloc like calls
13535 case Instruction::Alloca: {
13536
13537 AllocaInst *AI = cast<AllocaInst>(I);
13538
13539 Type *CharType = Type::getInt8Ty(I->getContext());
13540
13541 auto *NumBytesToValue =
13542 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13543
13544 BasicBlock::iterator insertPt = AI->getIterator();
13545 insertPt = std::next(insertPt);
13546 AllocaInst *NewAllocaInst =
13547 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13548 AI->getAlign(), AI->getName(), insertPt);
13549
13550 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13551 return ChangeStatus::CHANGED;
13552
13553 break;
13554 }
13555 default:
13556 break;
13557 }
13558
13559 return ChangeStatus::UNCHANGED;
13560 }
13561
13562 /// See AbstractAttribute::getAsStr().
13563 const std::string getAsStr(Attributor *A) const override {
13564 if (!isValidState())
13565 return "allocationinfo(<invalid>)";
13566 return "allocationinfo(" +
13567 (AssumedAllocatedSize == HasNoAllocationSize
13568 ? "none"
13569 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13570 ")";
13571 }
13572
13573private:
13574 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13575
13576 // Maintain the computed allocation size of the object.
13577 // Returns (bool) weather the size of the allocation was modified or not.
13578 bool changeAllocationSize(std::optional<TypeSize> Size) {
13579 if (AssumedAllocatedSize == HasNoAllocationSize ||
13580 AssumedAllocatedSize != Size) {
13581 AssumedAllocatedSize = Size;
13582 return true;
13583 }
13584 return false;
13585 }
13586};
13587
13588struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13589 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13590 : AAAllocationInfoImpl(IRP, A) {}
13591
13592 void trackStatistics() const override {
13593 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13594 }
13595};
13596
13597struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13598 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13599 : AAAllocationInfoImpl(IRP, A) {}
13600
13601 /// See AbstractAttribute::initialize(...).
13602 void initialize(Attributor &A) override {
13603 // TODO: we don't rewrite function argument for now because it will need to
13604 // rewrite the function signature and all call sites
13605 (void)indicatePessimisticFixpoint();
13606 }
13607
13608 void trackStatistics() const override {
13609 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13610 }
13611};
13612
13613struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13614 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13615 : AAAllocationInfoImpl(IRP, A) {}
13616
13617 void trackStatistics() const override {
13618 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13619 }
13620};
13621
13622struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13623 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13624 : AAAllocationInfoImpl(IRP, A) {}
13625
13626 void trackStatistics() const override {
13627 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13628 }
13629};
13630
13631struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13632 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13633 : AAAllocationInfoImpl(IRP, A) {}
13634
13635 /// See AbstractAttribute::initialize(...).
13636 void initialize(Attributor &A) override {
13637
13638 (void)indicatePessimisticFixpoint();
13639 }
13640
13641 void trackStatistics() const override {
13642 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13643 }
13644};
13645} // namespace
13646
13647const char AANoUnwind::ID = 0;
13648const char AANoSync::ID = 0;
13649const char AANoFree::ID = 0;
13650const char AANonNull::ID = 0;
13651const char AAMustProgress::ID = 0;
13652const char AANoRecurse::ID = 0;
13653const char AANonConvergent::ID = 0;
13654const char AAWillReturn::ID = 0;
13655const char AAUndefinedBehavior::ID = 0;
13656const char AANoAlias::ID = 0;
13657const char AAIntraFnReachability::ID = 0;
13658const char AANoReturn::ID = 0;
13659const char AAIsDead::ID = 0;
13660const char AADereferenceable::ID = 0;
13661const char AAAlign::ID = 0;
13662const char AAInstanceInfo::ID = 0;
13663const char AANoCapture::ID = 0;
13664const char AAValueSimplify::ID = 0;
13665const char AAHeapToStack::ID = 0;
13666const char AAPrivatizablePtr::ID = 0;
13667const char AAMemoryBehavior::ID = 0;
13668const char AAMemoryLocation::ID = 0;
13669const char AAValueConstantRange::ID = 0;
13670const char AAPotentialConstantValues::ID = 0;
13671const char AAPotentialValues::ID = 0;
13672const char AANoUndef::ID = 0;
13673const char AANoFPClass::ID = 0;
13674const char AACallEdges::ID = 0;
13675const char AAInterFnReachability::ID = 0;
13676const char AAPointerInfo::ID = 0;
13677const char AAAssumptionInfo::ID = 0;
13678const char AAUnderlyingObjects::ID = 0;
13679const char AAInvariantLoadPointer::ID = 0;
13680const char AAAddressSpace::ID = 0;
13681const char AANoAliasAddrSpace::ID = 0;
13682const char AAAllocationInfo::ID = 0;
13683const char AAIndirectCallInfo::ID = 0;
13684const char AAGlobalValueInfo::ID = 0;
13685const char AADenormalFPMath::ID = 0;
13686
13687// Macro magic to create the static generator function for attributes that
13688// follow the naming scheme.
13689
13690#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13691 case IRPosition::PK: \
13692 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13693
13694#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13695 case IRPosition::PK: \
13696 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13697 ++NumAAs; \
13698 break;
13699
13700#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13701 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13702 CLASS *AA = nullptr; \
13703 switch (IRP.getPositionKind()) { \
13704 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13705 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13706 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13707 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13708 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13709 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13710 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13711 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13712 } \
13713 return *AA; \
13714 }
13715
13716#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13717 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13718 CLASS *AA = nullptr; \
13719 switch (IRP.getPositionKind()) { \
13720 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13721 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13722 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13723 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13724 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13725 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13726 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13727 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13728 } \
13729 return *AA; \
13730 }
13731
13732#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13733 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13734 CLASS *AA = nullptr; \
13735 switch (IRP.getPositionKind()) { \
13736 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13737 default: \
13738 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13739 " position!"); \
13740 } \
13741 return *AA; \
13742 }
13743
13744#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13745 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13746 CLASS *AA = nullptr; \
13747 switch (IRP.getPositionKind()) { \
13748 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13749 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13750 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13751 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13752 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13753 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13754 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13755 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13756 } \
13757 return *AA; \
13758 }
13759
13760#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13761 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13762 CLASS *AA = nullptr; \
13763 switch (IRP.getPositionKind()) { \
13764 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13765 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13766 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13767 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13768 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13769 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13770 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13771 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13772 } \
13773 return *AA; \
13774 }
13775
13776#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13777 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13778 CLASS *AA = nullptr; \
13779 switch (IRP.getPositionKind()) { \
13780 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13781 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13782 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13783 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13784 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13785 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13786 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13787 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13788 } \
13789 return *AA; \
13790 }
13791
13801
13819
13824
13829
13836
13838
13839#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13840#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13841#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13842#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13843#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13844#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13845#undef SWITCH_PK_CREATE
13846#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1577
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:272
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:308
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:296
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:610
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:617
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:948
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:942
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:256
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
iterator end()
Definition DenseMap.h:81
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:159
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2048
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:2811
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1572
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:77
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:736
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:767
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:772
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:284
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:287
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:808
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:807
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:323
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:182
@ Intraprocedural
Definition Attributor.h:183
@ Interprocedural
Definition Attributor.h:184
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:375
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:328
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1630
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:366
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:369
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:496
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:508
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:509
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:507
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:345
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:241
static constexpr int64_t Unknown
Definition Attributor.h:320
static RangeTy getUnknown()
Definition Attributor.h:247
Value * getValue() const
Definition Attributor.h:194
const Instruction * getCtxI() const
Definition Attributor.h:195
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:593
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:724
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:661
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:643
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:617
CallBase CallBaseContext
Definition Attributor.h:596
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:811
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:629
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:666
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:607
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:603
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:606
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:604
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:605
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:608
@ IRP_INVALID
An invalid position.
Definition Attributor.h:600
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:777
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:650
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:800
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:636
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:939
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:791
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:710
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:820
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:689
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:889
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:921
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:656
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:765
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.