LLVM 22.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
670 if (Br->isConditional())
671 BrInsts.push_back(Br);
672 return true;
673 };
674
675 // Here, accumulate conditional branch instructions in the context. We
676 // explore the child paths and collect the known states. The disjunction of
677 // those states can be merged to its own state. Let ParentState_i be a state
678 // to indicate the known information for an i-th branch instruction in the
679 // context. ChildStates are created for its successors respectively.
680 //
681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
683 // ...
684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
685 //
686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
687 //
688 // FIXME: Currently, recursive branches are not handled. For example, we
689 // can't deduce that ptr must be dereferenced in below function.
690 //
691 // void f(int a, int c, int *ptr) {
692 // if(a)
693 // if (b) {
694 // *ptr = 0;
695 // } else {
696 // *ptr = 1;
697 // }
698 // else {
699 // if (b) {
700 // *ptr = 0;
701 // } else {
702 // *ptr = 1;
703 // }
704 // }
705 // }
706
707 Explorer->checkForAllContext(&CtxI, Pred);
708 for (const BranchInst *Br : BrInsts) {
709 StateType ParentState;
710
711 // The known state of the parent state is a conjunction of children's
712 // known states so it is initialized with a best state.
713 ParentState.indicateOptimisticFixpoint();
714
715 for (const BasicBlock *BB : Br->successors()) {
716 StateType ChildState;
717
718 size_t BeforeSize = Uses.size();
719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
720
721 // Erase uses which only appear in the child.
722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
723 It = Uses.erase(It);
724
725 ParentState &= ChildState;
726 }
727
728 // Use only known state.
729 S += ParentState;
730 }
731}
732} // namespace
733
734/// ------------------------ PointerInfo ---------------------------------------
735
736namespace llvm {
737namespace AA {
738namespace PointerInfo {
739
740struct State;
741
742} // namespace PointerInfo
743} // namespace AA
744
745/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
746template <>
749 static inline Access getEmptyKey();
750 static inline Access getTombstoneKey();
751 static unsigned getHashValue(const Access &A);
752 static bool isEqual(const Access &LHS, const Access &RHS);
753};
754
755/// Helper that allows RangeTy as a key in a DenseMap.
756template <> struct DenseMapInfo<AA::RangeTy> {
757 static inline AA::RangeTy getEmptyKey() {
758 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
759 return AA::RangeTy{EmptyKey, EmptyKey};
760 }
761
762 static inline AA::RangeTy getTombstoneKey() {
763 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
764 return AA::RangeTy{TombstoneKey, TombstoneKey};
765 }
766
772
773 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
774 return A == B;
775 }
776};
777
778/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
779/// but the instruction
780struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
783 static inline Access getEmptyKey();
784 static inline Access getTombstoneKey();
785 static unsigned getHashValue(const Access &A);
786 static bool isEqual(const Access &LHS, const Access &RHS);
787};
788
789} // namespace llvm
790
791/// A type to track pointer/struct usage and accesses for AAPointerInfo.
793 /// Return the best possible representable state.
794 static State getBestState(const State &SIS) { return State(); }
795
796 /// Return the worst possible representable state.
797 static State getWorstState(const State &SIS) {
798 State R;
799 R.indicatePessimisticFixpoint();
800 return R;
801 }
802
803 State() = default;
804 State(State &&SIS) = default;
805
806 const State &getAssumed() const { return *this; }
807
808 /// See AbstractState::isValidState().
809 bool isValidState() const override { return BS.isValidState(); }
810
811 /// See AbstractState::isAtFixpoint().
812 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
813
814 /// See AbstractState::indicateOptimisticFixpoint().
816 BS.indicateOptimisticFixpoint();
818 }
819
820 /// See AbstractState::indicatePessimisticFixpoint().
822 BS.indicatePessimisticFixpoint();
824 }
825
826 State &operator=(const State &R) {
827 if (this == &R)
828 return *this;
829 BS = R.BS;
830 AccessList = R.AccessList;
831 OffsetBins = R.OffsetBins;
832 RemoteIMap = R.RemoteIMap;
833 ReturnedOffsets = R.ReturnedOffsets;
834 return *this;
835 }
836
838 if (this == &R)
839 return *this;
840 std::swap(BS, R.BS);
841 std::swap(AccessList, R.AccessList);
842 std::swap(OffsetBins, R.OffsetBins);
843 std::swap(RemoteIMap, R.RemoteIMap);
844 std::swap(ReturnedOffsets, R.ReturnedOffsets);
845 return *this;
846 }
847
848 /// Add a new Access to the state at offset \p Offset and with size \p Size.
849 /// The access is associated with \p I, writes \p Content (if anything), and
850 /// is of kind \p Kind. If an Access already exists for the same \p I and same
851 /// \p RemoteI, the two are combined, potentially losing information about
852 /// offset and size. The resulting access must now be moved from its original
853 /// OffsetBin to the bin for its new offset.
854 ///
855 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
857 Instruction &I, std::optional<Value *> Content,
859 Instruction *RemoteI = nullptr);
860
863 int64_t numOffsetBins() const { return OffsetBins.size(); }
864
865 const AAPointerInfo::Access &getAccess(unsigned Index) const {
866 return AccessList[Index];
867 }
868
869protected:
870 // Every memory instruction results in an Access object. We maintain a list of
871 // all Access objects that we own, along with the following maps:
872 //
873 // - OffsetBins: RangeTy -> { Access }
874 // - RemoteIMap: RemoteI x LocalI -> Access
875 //
876 // A RemoteI is any instruction that accesses memory. RemoteI is different
877 // from LocalI if and only if LocalI is a call; then RemoteI is some
878 // instruction in the callgraph starting from LocalI. Multiple paths in the
879 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
880 // are all combined into a single Access object. This may result in loss of
881 // information in RangeTy in the Access object.
885
886 /// Flag to determine if the underlying pointer is reaching a return statement
887 /// in the associated function or not. Returns in other functions cause
888 /// invalidation.
890
891 /// See AAPointerInfo::forallInterferingAccesses.
892 template <typename F>
894 if (!isValidState() || !ReturnedOffsets.isUnassigned())
895 return false;
896
897 for (const auto &It : OffsetBins) {
898 AA::RangeTy ItRange = It.getFirst();
899 if (!Range.mayOverlap(ItRange))
900 continue;
901 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
902 for (auto Index : It.getSecond()) {
903 auto &Access = AccessList[Index];
904 if (!CB(Access, IsExact))
905 return false;
906 }
907 }
908 return true;
909 }
910
911 /// See AAPointerInfo::forallInterferingAccesses.
912 template <typename F>
914 AA::RangeTy &Range) const {
915 if (!isValidState() || !ReturnedOffsets.isUnassigned())
916 return false;
917
918 auto LocalList = RemoteIMap.find(&I);
919 if (LocalList == RemoteIMap.end()) {
920 return true;
921 }
922
923 for (unsigned Index : LocalList->getSecond()) {
924 for (auto &R : AccessList[Index]) {
925 Range &= R;
926 if (Range.offsetAndSizeAreUnknown())
927 break;
928 }
929 }
931 }
932
933private:
934 /// State to track fixpoint and validity.
935 BooleanState BS;
936};
937
940 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
941 Instruction *RemoteI) {
942 RemoteI = RemoteI ? RemoteI : &I;
943
944 // Check if we have an access for this instruction, if not, simply add it.
945 auto &LocalList = RemoteIMap[RemoteI];
946 bool AccExists = false;
947 unsigned AccIndex = AccessList.size();
948 for (auto Index : LocalList) {
949 auto &A = AccessList[Index];
950 if (A.getLocalInst() == &I) {
951 AccExists = true;
952 AccIndex = Index;
953 break;
954 }
955 }
956
957 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
958 LLVM_DEBUG(if (ToAdd.size()) dbgs()
959 << "[AAPointerInfo] Inserting access in new offset bins\n";);
960
961 for (auto Key : ToAdd) {
962 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
963 OffsetBins[Key].insert(AccIndex);
964 }
965 };
966
967 if (!AccExists) {
968 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
969 assert((AccessList.size() == AccIndex + 1) &&
970 "New Access should have been at AccIndex");
971 LocalList.push_back(AccIndex);
972 AddToBins(AccessList[AccIndex].getRanges());
974 }
975
976 // Combine the new Access with the existing Access, and then update the
977 // mapping in the offset bins.
978 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
979 auto &Current = AccessList[AccIndex];
980 auto Before = Current;
981 Current &= Acc;
982 if (Current == Before)
984
985 auto &ExistingRanges = Before.getRanges();
986 auto &NewRanges = Current.getRanges();
987
988 // Ranges that are in the old access but not the new access need to be removed
989 // from the offset bins.
991 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
992 LLVM_DEBUG(if (ToRemove.size()) dbgs()
993 << "[AAPointerInfo] Removing access from old offset bins\n";);
994
995 for (auto Key : ToRemove) {
996 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
997 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
998 auto &Bin = OffsetBins[Key];
999 assert(Bin.count(AccIndex) &&
1000 "Expected bin to actually contain the Access.");
1001 Bin.erase(AccIndex);
1002 }
1003
1004 // Ranges that are in the new access but not the old access need to be added
1005 // to the offset bins.
1007 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1008 AddToBins(ToAdd);
1009 return ChangeStatus::CHANGED;
1010}
1011
1012namespace {
1013
1014#ifndef NDEBUG
1016 const AAPointerInfo::OffsetInfo &OI) {
1017 OS << llvm::interleaved_array(OI);
1018 return OS;
1019}
1020#endif // NDEBUG
1021
1022struct AAPointerInfoImpl
1023 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1025 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1026
1027 /// See AbstractAttribute::getAsStr().
1028 const std::string getAsStr(Attributor *A) const override {
1029 return std::string("PointerInfo ") +
1030 (isValidState() ? (std::string("#") +
1031 std::to_string(OffsetBins.size()) + " bins")
1032 : "<invalid>") +
1033 (reachesReturn()
1034 ? (" (returned:" +
1035 join(map_range(ReturnedOffsets,
1036 [](int64_t O) { return std::to_string(O); }),
1037 ", ") +
1038 ")")
1039 : "");
1040 }
1041
1042 /// See AbstractAttribute::manifest(...).
1043 ChangeStatus manifest(Attributor &A) override {
1044 return AAPointerInfo::manifest(A);
1045 }
1046
1047 const_bin_iterator begin() const override { return State::begin(); }
1048 const_bin_iterator end() const override { return State::end(); }
1049 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1050 bool reachesReturn() const override {
1051 return !ReturnedOffsets.isUnassigned();
1052 }
1053 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1054 if (ReturnedOffsets.isUnknown()) {
1055 OI.setUnknown();
1056 return;
1057 }
1058
1059 OffsetInfo MergedOI;
1060 for (auto Offset : ReturnedOffsets) {
1061 OffsetInfo TmpOI = OI;
1062 TmpOI.addToAll(Offset);
1063 MergedOI.merge(TmpOI);
1064 }
1065 OI = std::move(MergedOI);
1066 }
1067
1068 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1069 if (ReturnedOffsets.isUnknown())
1070 return ChangeStatus::UNCHANGED;
1071 if (ReachedReturnedOffsets.isUnknown()) {
1072 ReturnedOffsets.setUnknown();
1073 return ChangeStatus::CHANGED;
1074 }
1075 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1076 return ChangeStatus::CHANGED;
1077 return ChangeStatus::UNCHANGED;
1078 }
1079
1080 bool forallInterferingAccesses(
1081 AA::RangeTy Range,
1082 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1083 const override {
1084 return State::forallInterferingAccesses(Range, CB);
1085 }
1086
1087 bool forallInterferingAccesses(
1088 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1089 bool FindInterferingWrites, bool FindInterferingReads,
1090 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1091 AA::RangeTy &Range,
1092 function_ref<bool(const Access &)> SkipCB) const override {
1093 HasBeenWrittenTo = false;
1094
1095 SmallPtrSet<const Access *, 8> DominatingWrites;
1096 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1097
1098 Function &Scope = *I.getFunction();
1099 bool IsKnownNoSync;
1100 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1101 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1102 IsKnownNoSync);
1103 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1104 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1105 bool AllInSameNoSyncFn = IsAssumedNoSync;
1106 bool InstIsExecutedByInitialThreadOnly =
1107 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1108
1109 // If the function is not ending in aligned barriers, we need the stores to
1110 // be in aligned barriers. The load being in one is not sufficient since the
1111 // store might be executed by a thread that disappears after, causing the
1112 // aligned barrier guarding the load to unblock and the load to read a value
1113 // that has no CFG path to the load.
1114 bool InstIsExecutedInAlignedRegion =
1115 FindInterferingReads && ExecDomainAA &&
1116 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1117
1118 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1119 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1120
1121 InformationCache &InfoCache = A.getInfoCache();
1122 bool IsThreadLocalObj =
1123 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1124
1125 // Helper to determine if we need to consider threading, which we cannot
1126 // right now. However, if the function is (assumed) nosync or the thread
1127 // executing all instructions is the main thread only we can ignore
1128 // threading. Also, thread-local objects do not require threading reasoning.
1129 // Finally, we can ignore threading if either access is executed in an
1130 // aligned region.
1131 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1132 if (IsThreadLocalObj || AllInSameNoSyncFn)
1133 return true;
1134 const auto *FnExecDomainAA =
1135 I.getFunction() == &Scope
1136 ? ExecDomainAA
1137 : A.lookupAAFor<AAExecutionDomain>(
1138 IRPosition::function(*I.getFunction()), &QueryingAA,
1139 DepClassTy::NONE);
1140 if (!FnExecDomainAA)
1141 return false;
1142 if (InstIsExecutedInAlignedRegion ||
1143 (FindInterferingWrites &&
1144 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1145 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1146 return true;
1147 }
1148 if (InstIsExecutedByInitialThreadOnly &&
1149 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1150 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1151 return true;
1152 }
1153 return false;
1154 };
1155
1156 // Helper to determine if the access is executed by the same thread as the
1157 // given instruction, for now it is sufficient to avoid any potential
1158 // threading effects as we cannot deal with them anyway.
1159 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1160 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1161 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1162 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1163 };
1164
1165 // TODO: Use inter-procedural reachability and dominance.
1166 bool IsKnownNoRecurse;
1168 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1169 IsKnownNoRecurse);
1170
1171 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1172 // AAExecutionDomain) such that we allow scopes other than kernels as long
1173 // as the reaching kernels are disjoint.
1174 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1175 bool ObjHasKernelLifetime = false;
1176 const bool UseDominanceReasoning =
1177 FindInterferingWrites && IsKnownNoRecurse;
1178 const DominatorTree *DT =
1179 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1180
1181 // Helper to check if a value has "kernel lifetime", that is it will not
1182 // outlive a GPU kernel. This is true for shared, constant, and local
1183 // globals on AMD and NVIDIA GPUs.
1184 auto HasKernelLifetime = [&](Value *V, Module &M) {
1185 if (!AA::isGPU(M))
1186 return false;
1187 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1188 case AA::GPUAddressSpace::Shared:
1189 case AA::GPUAddressSpace::Constant:
1190 case AA::GPUAddressSpace::Local:
1191 return true;
1192 default:
1193 return false;
1194 };
1195 };
1196
1197 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1198 // to determine if we should look at reachability from the callee. For
1199 // certain pointers we know the lifetime and we do not have to step into the
1200 // callee to determine reachability as the pointer would be dead in the
1201 // callee. See the conditional initialization below.
1202 std::function<bool(const Function &)> IsLiveInCalleeCB;
1203
1204 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1205 // If the alloca containing function is not recursive the alloca
1206 // must be dead in the callee.
1207 const Function *AIFn = AI->getFunction();
1208 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1209 bool IsKnownNoRecurse;
1211 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1212 IsKnownNoRecurse)) {
1213 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1214 }
1215 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1216 // If the global has kernel lifetime we can stop if we reach a kernel
1217 // as it is "dead" in the (unknown) callees.
1218 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1219 if (ObjHasKernelLifetime)
1220 IsLiveInCalleeCB = [&A](const Function &Fn) {
1221 return !A.getInfoCache().isKernel(Fn);
1222 };
1223 }
1224
1225 // Set of accesses/instructions that will overwrite the result and are
1226 // therefore blockers in the reachability traversal.
1227 AA::InstExclusionSetTy ExclusionSet;
1228
1229 auto AccessCB = [&](const Access &Acc, bool Exact) {
1230 Function *AccScope = Acc.getRemoteInst()->getFunction();
1231 bool AccInSameScope = AccScope == &Scope;
1232
1233 // If the object has kernel lifetime we can ignore accesses only reachable
1234 // by other kernels. For now we only skip accesses *in* other kernels.
1235 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1236 A.getInfoCache().isKernel(*AccScope))
1237 return true;
1238
1239 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1240 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1241 ExclusionSet.insert(Acc.getRemoteInst());
1242 }
1243
1244 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1245 (!FindInterferingReads || !Acc.isRead()))
1246 return true;
1247
1248 bool Dominates = FindInterferingWrites && DT && Exact &&
1249 Acc.isMustAccess() && AccInSameScope &&
1250 DT->dominates(Acc.getRemoteInst(), &I);
1251 if (Dominates)
1252 DominatingWrites.insert(&Acc);
1253
1254 // Track if all interesting accesses are in the same `nosync` function as
1255 // the given instruction.
1256 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1257
1258 InterferingAccesses.push_back({&Acc, Exact});
1259 return true;
1260 };
1261 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1262 return false;
1263
1264 HasBeenWrittenTo = !DominatingWrites.empty();
1265
1266 // Dominating writes form a chain, find the least/lowest member.
1267 Instruction *LeastDominatingWriteInst = nullptr;
1268 for (const Access *Acc : DominatingWrites) {
1269 if (!LeastDominatingWriteInst) {
1270 LeastDominatingWriteInst = Acc->getRemoteInst();
1271 } else if (DT->dominates(LeastDominatingWriteInst,
1272 Acc->getRemoteInst())) {
1273 LeastDominatingWriteInst = Acc->getRemoteInst();
1274 }
1275 }
1276
1277 // Helper to determine if we can skip a specific write access.
1278 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1279 if (SkipCB && SkipCB(Acc))
1280 return true;
1281 if (!CanIgnoreThreading(Acc))
1282 return false;
1283
1284 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1285 // If we successfully excluded all effects we are interested in, the
1286 // access can be skipped.
1287 bool ReadChecked = !FindInterferingReads;
1288 bool WriteChecked = !FindInterferingWrites;
1289
1290 // If the instruction cannot reach the access, the former does not
1291 // interfere with what the access reads.
1292 if (!ReadChecked) {
1293 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1294 &ExclusionSet, IsLiveInCalleeCB))
1295 ReadChecked = true;
1296 }
1297 // If the instruction cannot be reach from the access, the latter does not
1298 // interfere with what the instruction reads.
1299 if (!WriteChecked) {
1300 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1301 &ExclusionSet, IsLiveInCalleeCB))
1302 WriteChecked = true;
1303 }
1304
1305 // If we still might be affected by the write of the access but there are
1306 // dominating writes in the function of the instruction
1307 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1308 // by them. This would have happend above if they are all in the same
1309 // function, so we only check the inter-procedural case. Effectively, we
1310 // want to show that there is no call after the dominting write that might
1311 // reach the access, and when it returns reach the instruction with the
1312 // updated value. To this end, we iterate all call sites, check if they
1313 // might reach the instruction without going through another access
1314 // (ExclusionSet) and at the same time might reach the access. However,
1315 // that is all part of AAInterFnReachability.
1316 if (!WriteChecked && HasBeenWrittenTo &&
1317 Acc.getRemoteInst()->getFunction() != &Scope) {
1318
1319 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1320 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1321 if (FnReachabilityAA) {
1322 // Without going backwards in the call tree, can we reach the access
1323 // from the least dominating write. Do not allow to pass the
1324 // instruction itself either.
1325 bool Inserted = ExclusionSet.insert(&I).second;
1326
1327 if (!FnReachabilityAA->instructionCanReach(
1328 A, *LeastDominatingWriteInst,
1329 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1330 WriteChecked = true;
1331
1332 if (Inserted)
1333 ExclusionSet.erase(&I);
1334 }
1335 }
1336
1337 if (ReadChecked && WriteChecked)
1338 return true;
1339
1340 if (!DT || !UseDominanceReasoning)
1341 return false;
1342 if (!DominatingWrites.count(&Acc))
1343 return false;
1344 return LeastDominatingWriteInst != Acc.getRemoteInst();
1345 };
1346
1347 // Run the user callback on all accesses we cannot skip and return if
1348 // that succeeded for all or not.
1349 for (auto &It : InterferingAccesses) {
1350 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1351 !CanSkipAccess(*It.first, It.second)) {
1352 if (!UserCB(*It.first, It.second))
1353 return false;
1354 }
1355 }
1356 return true;
1357 }
1358
1359 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1360 const AAPointerInfo &OtherAA,
1361 CallBase &CB) {
1362 using namespace AA::PointerInfo;
1363 if (!OtherAA.getState().isValidState() || !isValidState())
1364 return indicatePessimisticFixpoint();
1365
1366 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1367 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1368 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1369 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1370
1371 // Combine the accesses bin by bin.
1372 const auto &State = OtherAAImpl.getState();
1373 for (const auto &It : State) {
1374 for (auto Index : It.getSecond()) {
1375 const auto &RAcc = State.getAccess(Index);
1376 if (IsByval && !RAcc.isRead())
1377 continue;
1378 bool UsedAssumedInformation = false;
1379 AccessKind AK = RAcc.getKind();
1380 auto Content = A.translateArgumentToCallSiteContent(
1381 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1382 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1383 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1384
1385 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1386 RAcc.getType(), RAcc.getRemoteInst());
1387 }
1388 }
1389 return Changed;
1390 }
1391
1392 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1393 const OffsetInfo &Offsets, CallBase &CB,
1394 bool IsMustAcc) {
1395 using namespace AA::PointerInfo;
1396 if (!OtherAA.getState().isValidState() || !isValidState())
1397 return indicatePessimisticFixpoint();
1398
1399 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1400
1401 // Combine the accesses bin by bin.
1402 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1403 const auto &State = OtherAAImpl.getState();
1404 for (const auto &It : State) {
1405 for (auto Index : It.getSecond()) {
1406 const auto &RAcc = State.getAccess(Index);
1407 if (!IsMustAcc && RAcc.isAssumption())
1408 continue;
1409 for (auto Offset : Offsets) {
1410 auto NewRanges = Offset == AA::RangeTy::Unknown
1412 : RAcc.getRanges();
1413 if (!NewRanges.isUnknown()) {
1414 NewRanges.addToAllOffsets(Offset);
1415 }
1416 AccessKind AK = RAcc.getKind();
1417 if (!IsMustAcc)
1418 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1419 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1420 RAcc.getType(), RAcc.getRemoteInst());
1421 }
1422 }
1423 }
1424 return Changed;
1425 }
1426
1427 /// Statistic tracking for all AAPointerInfo implementations.
1428 /// See AbstractAttribute::trackStatistics().
1429 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1430
1431 /// Dump the state into \p O.
1432 void dumpState(raw_ostream &O) {
1433 for (auto &It : OffsetBins) {
1434 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1435 << "] : " << It.getSecond().size() << "\n";
1436 for (auto AccIndex : It.getSecond()) {
1437 auto &Acc = AccessList[AccIndex];
1438 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1439 if (Acc.getLocalInst() != Acc.getRemoteInst())
1440 O << " --> " << *Acc.getRemoteInst()
1441 << "\n";
1442 if (!Acc.isWrittenValueYetUndetermined()) {
1443 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1444 O << " - c: func " << Acc.getWrittenValue()->getName()
1445 << "\n";
1446 else if (Acc.getWrittenValue())
1447 O << " - c: " << *Acc.getWrittenValue() << "\n";
1448 else
1449 O << " - c: <unknown>\n";
1450 }
1451 }
1452 }
1453 }
1454};
1455
1456struct AAPointerInfoFloating : public AAPointerInfoImpl {
1458 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1459 : AAPointerInfoImpl(IRP, A) {}
1460
1461 /// Deal with an access and signal if it was handled successfully.
1462 bool handleAccess(Attributor &A, Instruction &I,
1463 std::optional<Value *> Content, AccessKind Kind,
1464 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1465 Type &Ty) {
1466 using namespace AA::PointerInfo;
1468 const DataLayout &DL = A.getDataLayout();
1469 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1470 if (!AccessSize.isScalable())
1471 Size = AccessSize.getFixedValue();
1472
1473 // Make a strictly ascending list of offsets as required by addAccess()
1474 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1475 llvm::sort(OffsetsSorted);
1476
1478 if (!VT || VT->getElementCount().isScalable() ||
1479 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1480 (*Content)->getType() != VT ||
1481 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1482 Changed =
1483 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1484 } else {
1485 // Handle vector stores with constant content element-wise.
1486 // TODO: We could look for the elements or create instructions
1487 // representing them.
1488 // TODO: We need to push the Content into the range abstraction
1489 // (AA::RangeTy) to allow different content values for different
1490 // ranges. ranges. Hence, support vectors storing different values.
1491 Type *ElementType = VT->getElementType();
1492 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1493 auto *ConstContent = cast<Constant>(*Content);
1494 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1495 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1496
1497 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1498 Value *ElementContent = ConstantExpr::getExtractElement(
1499 ConstContent, ConstantInt::get(Int32Ty, i));
1500
1501 // Add the element access.
1502 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1503 ElementContent, Kind, ElementType);
1504
1505 // Advance the offsets for the next element.
1506 for (auto &ElementOffset : ElementOffsets)
1507 ElementOffset += ElementSize;
1508 }
1509 }
1510 return true;
1511 };
1512
1513 /// See AbstractAttribute::updateImpl(...).
1514 ChangeStatus updateImpl(Attributor &A) override;
1515
1516 /// If the indices to \p GEP can be traced to constants, incorporate all
1517 /// of these into \p UsrOI.
1518 ///
1519 /// \return true iff \p UsrOI is updated.
1520 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1521 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1522 const GEPOperator *GEP);
1523
1524 /// See AbstractAttribute::trackStatistics()
1525 void trackStatistics() const override {
1526 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1527 }
1528};
1529
1530bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1531 const DataLayout &DL,
1532 OffsetInfo &UsrOI,
1533 const OffsetInfo &PtrOI,
1534 const GEPOperator *GEP) {
1535 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1536 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1537 APInt ConstantOffset(BitWidth, 0);
1538
1539 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1540 "Don't look for constant values if the offset has already been "
1541 "determined to be unknown.");
1542
1543 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1544 UsrOI.setUnknown();
1545 return true;
1546 }
1547
1548 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1549 << (VariableOffsets.empty() ? "" : "not") << " constant "
1550 << *GEP << "\n");
1551
1552 auto Union = PtrOI;
1553 Union.addToAll(ConstantOffset.getSExtValue());
1554
1555 // Each VI in VariableOffsets has a set of potential constant values. Every
1556 // combination of elements, picked one each from these sets, is separately
1557 // added to the original set of offsets, thus resulting in more offsets.
1558 for (const auto &VI : VariableOffsets) {
1559 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1560 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1561 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1562 UsrOI.setUnknown();
1563 return true;
1564 }
1565
1566 // UndefValue is treated as a zero, which leaves Union as is.
1567 if (PotentialConstantsAA->undefIsContained())
1568 continue;
1569
1570 // We need at least one constant in every set to compute an actual offset.
1571 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1572 // don't actually exist. In other words, the absence of constant values
1573 // implies that the operation can be assumed dead for now.
1574 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1575 if (AssumedSet.empty())
1576 return false;
1577
1578 OffsetInfo Product;
1579 for (const auto &ConstOffset : AssumedSet) {
1580 auto CopyPerOffset = Union;
1581 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1582 VI.second.getZExtValue());
1583 Product.merge(CopyPerOffset);
1584 }
1585 Union = Product;
1586 }
1587
1588 UsrOI = std::move(Union);
1589 return true;
1590}
1591
1592ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1593 using namespace AA::PointerInfo;
1595 const DataLayout &DL = A.getDataLayout();
1596 Value &AssociatedValue = getAssociatedValue();
1597
1598 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1599 OffsetInfoMap[&AssociatedValue].insert(0);
1600
1601 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1602 // One does not simply walk into a map and assign a reference to a possibly
1603 // new location. That can cause an invalidation before the assignment
1604 // happens, like so:
1605 //
1606 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1607 //
1608 // The RHS is a reference that may be invalidated by an insertion caused by
1609 // the LHS. So we ensure that the side-effect of the LHS happens first.
1610
1611 assert(OffsetInfoMap.contains(CurPtr) &&
1612 "CurPtr does not exist in the map!");
1613
1614 auto &UsrOI = OffsetInfoMap[Usr];
1615 auto &PtrOI = OffsetInfoMap[CurPtr];
1616 assert(!PtrOI.isUnassigned() &&
1617 "Cannot pass through if the input Ptr was not visited!");
1618 UsrOI.merge(PtrOI);
1619 Follow = true;
1620 return true;
1621 };
1622
1623 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1624 Value *CurPtr = U.get();
1625 User *Usr = U.getUser();
1626 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1627 << "\n");
1628 assert(OffsetInfoMap.count(CurPtr) &&
1629 "The current pointer offset should have been seeded!");
1630 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1631 "Current pointer should be assigned");
1632
1633 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1634 if (CE->isCast())
1635 return HandlePassthroughUser(Usr, CurPtr, Follow);
1636 if (!isa<GEPOperator>(CE)) {
1637 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1638 << "\n");
1639 return false;
1640 }
1641 }
1642 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1643 // Note the order here, the Usr access might change the map, CurPtr is
1644 // already in it though.
1645 auto &UsrOI = OffsetInfoMap[Usr];
1646 auto &PtrOI = OffsetInfoMap[CurPtr];
1647
1648 if (UsrOI.isUnknown())
1649 return true;
1650
1651 if (PtrOI.isUnknown()) {
1652 Follow = true;
1653 UsrOI.setUnknown();
1654 return true;
1655 }
1656
1657 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1658 return true;
1659 }
1660 if (isa<PtrToIntInst>(Usr))
1661 return false;
1662 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1663 return HandlePassthroughUser(Usr, CurPtr, Follow);
1664 // Returns are allowed if they are in the associated functions. Users can
1665 // then check the call site return. Returns from other functions can't be
1666 // tracked and are cause for invalidation.
1667 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1668 if (RI->getFunction() == getAssociatedFunction()) {
1669 auto &PtrOI = OffsetInfoMap[CurPtr];
1670 Changed |= setReachesReturn(PtrOI);
1671 return true;
1672 }
1673 return false;
1674 }
1675
1676 // For PHIs we need to take care of the recurrence explicitly as the value
1677 // might change while we iterate through a loop. For now, we give up if
1678 // the PHI is not invariant.
1679 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1680 // Note the order here, the Usr access might change the map, CurPtr is
1681 // already in it though.
1682 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1683 auto &UsrOI = PhiIt->second;
1684 auto &PtrOI = OffsetInfoMap[CurPtr];
1685
1686 // Check if the PHI operand has already an unknown offset as we can't
1687 // improve on that anymore.
1688 if (PtrOI.isUnknown()) {
1689 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1690 << *CurPtr << " in " << *PHI << "\n");
1691 Follow = !UsrOI.isUnknown();
1692 UsrOI.setUnknown();
1693 return true;
1694 }
1695
1696 // Check if the PHI is invariant (so far).
1697 if (UsrOI == PtrOI) {
1698 assert(!PtrOI.isUnassigned() &&
1699 "Cannot assign if the current Ptr was not visited!");
1700 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1701 return true;
1702 }
1703
1704 // Check if the PHI operand can be traced back to AssociatedValue.
1705 APInt Offset(
1706 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1707 0);
1708 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1709 DL, Offset, /* AllowNonInbounds */ true);
1710 auto It = OffsetInfoMap.find(CurPtrBase);
1711 if (It == OffsetInfoMap.end()) {
1712 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1713 << *CurPtr << " in " << *PHI
1714 << " (base: " << *CurPtrBase << ")\n");
1715 UsrOI.setUnknown();
1716 Follow = true;
1717 return true;
1718 }
1719
1720 // Check if the PHI operand is not dependent on the PHI itself. Every
1721 // recurrence is a cyclic net of PHIs in the data flow, and has an
1722 // equivalent Cycle in the control flow. One of those PHIs must be in the
1723 // header of that control flow Cycle. This is independent of the choice of
1724 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1725 // every Cycle header; if such a node is marked unknown, this will
1726 // eventually propagate through the whole net of PHIs in the recurrence.
1727 const auto *CI =
1728 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1729 *PHI->getFunction());
1730 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1731 auto BaseOI = It->getSecond();
1732 BaseOI.addToAll(Offset.getZExtValue());
1733 if (IsFirstPHIUser || BaseOI == UsrOI) {
1734 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1735 << " in " << *Usr << "\n");
1736 return HandlePassthroughUser(Usr, CurPtr, Follow);
1737 }
1738
1739 LLVM_DEBUG(
1740 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1741 << *CurPtr << " in " << *PHI << "\n");
1742 UsrOI.setUnknown();
1743 Follow = true;
1744 return true;
1745 }
1746
1747 UsrOI.merge(PtrOI);
1748 Follow = true;
1749 return true;
1750 }
1751
1752 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1753 // If the access is to a pointer that may or may not be the associated
1754 // value, e.g. due to a PHI, we cannot assume it will be read.
1755 AccessKind AK = AccessKind::AK_R;
1756 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1757 AK = AccessKind(AK | AccessKind::AK_MUST);
1758 else
1759 AK = AccessKind(AK | AccessKind::AK_MAY);
1760 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1761 OffsetInfoMap[CurPtr].Offsets, Changed,
1762 *LoadI->getType()))
1763 return false;
1764
1765 auto IsAssumption = [](Instruction &I) {
1766 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1767 return II->isAssumeLikeIntrinsic();
1768 return false;
1769 };
1770
1771 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1772 // Check if the assumption and the load are executed together without
1773 // memory modification.
1774 do {
1775 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1776 return true;
1777 FromI = FromI->getNextNode();
1778 } while (FromI && FromI != ToI);
1779 return false;
1780 };
1781
1782 BasicBlock *BB = LoadI->getParent();
1783 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1784 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1785 return false;
1786 BasicBlock *IntrBB = IntrI.getParent();
1787 if (IntrI.getParent() == BB) {
1788 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1789 return false;
1790 } else {
1791 auto PredIt = pred_begin(IntrBB);
1792 if (PredIt == pred_end(IntrBB))
1793 return false;
1794 if ((*PredIt) != BB)
1795 return false;
1796 if (++PredIt != pred_end(IntrBB))
1797 return false;
1798 for (auto *SuccBB : successors(BB)) {
1799 if (SuccBB == IntrBB)
1800 continue;
1801 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1802 continue;
1803 return false;
1804 }
1805 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1806 return false;
1807 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1808 return false;
1809 }
1810 return true;
1811 };
1812
1813 std::pair<Value *, IntrinsicInst *> Assumption;
1814 for (const Use &LoadU : LoadI->uses()) {
1815 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1816 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1817 continue;
1818 for (const Use &CmpU : CmpI->uses()) {
1819 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1820 if (!IsValidAssume(*IntrI))
1821 continue;
1822 int Idx = CmpI->getOperandUse(0) == LoadU;
1823 Assumption = {CmpI->getOperand(Idx), IntrI};
1824 break;
1825 }
1826 }
1827 }
1828 if (Assumption.first)
1829 break;
1830 }
1831
1832 // Check if we found an assumption associated with this load.
1833 if (!Assumption.first || !Assumption.second)
1834 return true;
1835
1836 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1837 << *Assumption.second << ": " << *LoadI
1838 << " == " << *Assumption.first << "\n");
1839 bool UsedAssumedInformation = false;
1840 std::optional<Value *> Content = nullptr;
1841 if (Assumption.first)
1842 Content =
1843 A.getAssumedSimplified(*Assumption.first, *this,
1844 UsedAssumedInformation, AA::Interprocedural);
1845 return handleAccess(
1846 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1847 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1848 }
1849
1850 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1851 ArrayRef<Value *> OtherOps, AccessKind AK) {
1852 for (auto *OtherOp : OtherOps) {
1853 if (OtherOp == CurPtr) {
1854 LLVM_DEBUG(
1855 dbgs()
1856 << "[AAPointerInfo] Escaping use in store like instruction " << I
1857 << "\n");
1858 return false;
1859 }
1860 }
1861
1862 // If the access is to a pointer that may or may not be the associated
1863 // value, e.g. due to a PHI, we cannot assume it will be written.
1864 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1865 AK = AccessKind(AK | AccessKind::AK_MUST);
1866 else
1867 AK = AccessKind(AK | AccessKind::AK_MAY);
1868 bool UsedAssumedInformation = false;
1869 std::optional<Value *> Content = nullptr;
1870 if (ValueOp)
1871 Content = A.getAssumedSimplified(
1872 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1873 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1874 Changed, ValueTy);
1875 };
1876
1877 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1878 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1879 *StoreI->getValueOperand()->getType(),
1880 {StoreI->getValueOperand()}, AccessKind::AK_W);
1881 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1882 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1883 {RMWI->getValOperand()}, AccessKind::AK_RW);
1884 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1885 return HandleStoreLike(
1886 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1887 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1888 AccessKind::AK_RW);
1889
1890 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1891 if (CB->isLifetimeStartOrEnd())
1892 return true;
1893 const auto *TLI =
1894 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1895 if (getFreedOperand(CB, TLI) == U)
1896 return true;
1897 if (CB->isArgOperand(&U)) {
1898 unsigned ArgNo = CB->getArgOperandNo(&U);
1899 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1900 *this, IRPosition::callsite_argument(*CB, ArgNo),
1902 if (!CSArgPI)
1903 return false;
1904 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1905 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1906 IsArgMustAcc) |
1907 Changed;
1908 if (!CSArgPI->reachesReturn())
1909 return isValidState();
1910
1912 if (!Callee || Callee->arg_size() <= ArgNo)
1913 return false;
1914 bool UsedAssumedInformation = false;
1915 auto ReturnedValue = A.getAssumedSimplified(
1916 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1918 auto *ReturnedArg =
1919 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1920 auto *Arg = Callee->getArg(ArgNo);
1921 if (ReturnedArg && Arg != ReturnedArg)
1922 return true;
1923 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1924 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1926 if (!CSRetPI)
1927 return false;
1928 OffsetInfo OI = OffsetInfoMap[CurPtr];
1929 CSArgPI->addReturnedOffsetsTo(OI);
1930 Changed =
1931 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1932 return isValidState();
1933 }
1934 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1935 << "\n");
1936 return false;
1937 }
1938
1939 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1940 return false;
1941 };
1942 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1943 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1944 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1945 if (OffsetInfoMap.count(NewU)) {
1946 LLVM_DEBUG({
1947 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1948 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1949 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1950 << "\n";
1951 }
1952 });
1953 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1954 }
1955 bool Unused;
1956 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1957 };
1958 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1959 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1960 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1961 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1962 return indicatePessimisticFixpoint();
1963 }
1964
1965 LLVM_DEBUG({
1966 dbgs() << "Accesses by bin after update:\n";
1967 dumpState(dbgs());
1968 });
1969
1970 return Changed;
1971}
1972
1973struct AAPointerInfoReturned final : AAPointerInfoImpl {
1974 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1975 : AAPointerInfoImpl(IRP, A) {}
1976
1977 /// See AbstractAttribute::updateImpl(...).
1978 ChangeStatus updateImpl(Attributor &A) override {
1979 return indicatePessimisticFixpoint();
1980 }
1981
1982 /// See AbstractAttribute::trackStatistics()
1983 void trackStatistics() const override {
1984 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1985 }
1986};
1987
1988struct AAPointerInfoArgument final : AAPointerInfoFloating {
1989 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1990 : AAPointerInfoFloating(IRP, A) {}
1991
1992 /// See AbstractAttribute::trackStatistics()
1993 void trackStatistics() const override {
1994 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1995 }
1996};
1997
1998struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1999 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
2000 : AAPointerInfoFloating(IRP, A) {}
2001
2002 /// See AbstractAttribute::updateImpl(...).
2003 ChangeStatus updateImpl(Attributor &A) override {
2004 using namespace AA::PointerInfo;
2005 // We handle memory intrinsics explicitly, at least the first (=
2006 // destination) and second (=source) arguments as we know how they are
2007 // accessed.
2008 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2009 int64_t LengthVal = AA::RangeTy::Unknown;
2010 if (auto Length = MI->getLengthInBytes())
2011 LengthVal = Length->getSExtValue();
2012 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2013 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2014 if (ArgNo > 1) {
2015 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2016 << *MI << "\n");
2017 return indicatePessimisticFixpoint();
2018 } else {
2019 auto Kind =
2020 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2021 Changed =
2022 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2023 }
2024 LLVM_DEBUG({
2025 dbgs() << "Accesses by bin after update:\n";
2026 dumpState(dbgs());
2027 });
2028
2029 return Changed;
2030 }
2031
2032 // TODO: Once we have call site specific value information we can provide
2033 // call site specific liveness information and then it makes
2034 // sense to specialize attributes for call sites arguments instead of
2035 // redirecting requests to the callee argument.
2036 Argument *Arg = getAssociatedArgument();
2037 if (Arg) {
2038 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2039 auto *ArgAA =
2040 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2041 if (ArgAA && ArgAA->getState().isValidState())
2042 return translateAndAddStateFromCallee(A, *ArgAA,
2043 *cast<CallBase>(getCtxI()));
2044 if (!Arg->getParent()->isDeclaration())
2045 return indicatePessimisticFixpoint();
2046 }
2047
2048 bool IsKnownNoCapture;
2050 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2051 return indicatePessimisticFixpoint();
2052
2053 bool IsKnown = false;
2054 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2055 return ChangeStatus::UNCHANGED;
2056 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2057 auto Kind =
2058 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2059 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2060 nullptr);
2061 }
2062
2063 /// See AbstractAttribute::trackStatistics()
2064 void trackStatistics() const override {
2065 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2066 }
2067};
2068
2069struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2070 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2071 : AAPointerInfoFloating(IRP, A) {}
2072
2073 /// See AbstractAttribute::trackStatistics()
2074 void trackStatistics() const override {
2075 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2076 }
2077};
2078} // namespace
2079
2080/// -----------------------NoUnwind Function Attribute--------------------------
2081
2082namespace {
2083struct AANoUnwindImpl : AANoUnwind {
2084 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2085
2086 /// See AbstractAttribute::initialize(...).
2087 void initialize(Attributor &A) override {
2088 bool IsKnown;
2090 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2091 (void)IsKnown;
2092 }
2093
2094 const std::string getAsStr(Attributor *A) const override {
2095 return getAssumed() ? "nounwind" : "may-unwind";
2096 }
2097
2098 /// See AbstractAttribute::updateImpl(...).
2099 ChangeStatus updateImpl(Attributor &A) override {
2100 auto Opcodes = {
2101 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2102 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2103 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2104
2105 auto CheckForNoUnwind = [&](Instruction &I) {
2106 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2107 return true;
2108
2109 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2110 bool IsKnownNoUnwind;
2112 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2113 IsKnownNoUnwind);
2114 }
2115 return false;
2116 };
2117
2118 bool UsedAssumedInformation = false;
2119 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2120 UsedAssumedInformation))
2121 return indicatePessimisticFixpoint();
2122
2123 return ChangeStatus::UNCHANGED;
2124 }
2125};
2126
2127struct AANoUnwindFunction final : public AANoUnwindImpl {
2128 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2129 : AANoUnwindImpl(IRP, A) {}
2130
2131 /// See AbstractAttribute::trackStatistics()
2132 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2133};
2134
2135/// NoUnwind attribute deduction for a call sites.
2136struct AANoUnwindCallSite final
2137 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2138 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2139 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2140
2141 /// See AbstractAttribute::trackStatistics()
2142 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2143};
2144} // namespace
2145
2146/// ------------------------ NoSync Function Attribute -------------------------
2147
2148bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2149 switch (CB.getIntrinsicID()) {
2150 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2151 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2152 case Intrinsic::nvvm_barrier0_and:
2153 case Intrinsic::nvvm_barrier0_or:
2154 case Intrinsic::nvvm_barrier0_popc:
2155 return true;
2156 case Intrinsic::amdgcn_s_barrier:
2157 if (ExecutedAligned)
2158 return true;
2159 break;
2160 default:
2161 break;
2162 }
2163 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2164}
2165
2167 if (!I->isAtomic())
2168 return false;
2169
2170 if (auto *FI = dyn_cast<FenceInst>(I))
2171 // All legal orderings for fence are stronger than monotonic.
2172 return FI->getSyncScopeID() != SyncScope::SingleThread;
2173 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2174 // Unordered is not a legal ordering for cmpxchg.
2175 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2176 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2177 }
2178
2179 AtomicOrdering Ordering;
2180 switch (I->getOpcode()) {
2181 case Instruction::AtomicRMW:
2182 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2183 break;
2184 case Instruction::Store:
2185 Ordering = cast<StoreInst>(I)->getOrdering();
2186 break;
2187 case Instruction::Load:
2188 Ordering = cast<LoadInst>(I)->getOrdering();
2189 break;
2190 default:
2192 "New atomic operations need to be known in the attributor.");
2193 }
2194
2195 return (Ordering != AtomicOrdering::Unordered &&
2196 Ordering != AtomicOrdering::Monotonic);
2197}
2198
2199/// Return true if this intrinsic is nosync. This is only used for intrinsics
2200/// which would be nosync except that they have a volatile flag. All other
2201/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2203 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2204 return !MI->isVolatile();
2205 return false;
2206}
2207
2208namespace {
2209struct AANoSyncImpl : AANoSync {
2210 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2211
2212 /// See AbstractAttribute::initialize(...).
2213 void initialize(Attributor &A) override {
2214 bool IsKnown;
2215 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2216 DepClassTy::NONE, IsKnown));
2217 (void)IsKnown;
2218 }
2219
2220 const std::string getAsStr(Attributor *A) const override {
2221 return getAssumed() ? "nosync" : "may-sync";
2222 }
2223
2224 /// See AbstractAttribute::updateImpl(...).
2225 ChangeStatus updateImpl(Attributor &A) override;
2226};
2227
2228ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2229
2230 auto CheckRWInstForNoSync = [&](Instruction &I) {
2231 return AA::isNoSyncInst(A, I, *this);
2232 };
2233
2234 auto CheckForNoSync = [&](Instruction &I) {
2235 // At this point we handled all read/write effects and they are all
2236 // nosync, so they can be skipped.
2237 if (I.mayReadOrWriteMemory())
2238 return true;
2239
2240 bool IsKnown;
2241 CallBase &CB = cast<CallBase>(I);
2244 IsKnown))
2245 return true;
2246
2247 // non-convergent and readnone imply nosync.
2248 return !CB.isConvergent();
2249 };
2250
2251 bool UsedAssumedInformation = false;
2252 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2253 UsedAssumedInformation) ||
2254 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2255 UsedAssumedInformation))
2256 return indicatePessimisticFixpoint();
2257
2259}
2260
2261struct AANoSyncFunction final : public AANoSyncImpl {
2262 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2263 : AANoSyncImpl(IRP, A) {}
2264
2265 /// See AbstractAttribute::trackStatistics()
2266 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2267};
2268
2269/// NoSync attribute deduction for a call sites.
2270struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2271 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2272 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2273
2274 /// See AbstractAttribute::trackStatistics()
2275 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2276};
2277} // namespace
2278
2279/// ------------------------ No-Free Attributes ----------------------------
2280
2281namespace {
2282struct AANoFreeImpl : public AANoFree {
2283 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2284
2285 /// See AbstractAttribute::initialize(...).
2286 void initialize(Attributor &A) override {
2287 bool IsKnown;
2288 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2289 DepClassTy::NONE, IsKnown));
2290 (void)IsKnown;
2291 }
2292
2293 /// See AbstractAttribute::updateImpl(...).
2294 ChangeStatus updateImpl(Attributor &A) override {
2295 auto CheckForNoFree = [&](Instruction &I) {
2296 bool IsKnown;
2299 DepClassTy::REQUIRED, IsKnown);
2300 };
2301
2302 bool UsedAssumedInformation = false;
2303 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2304 UsedAssumedInformation))
2305 return indicatePessimisticFixpoint();
2306 return ChangeStatus::UNCHANGED;
2307 }
2308
2309 /// See AbstractAttribute::getAsStr().
2310 const std::string getAsStr(Attributor *A) const override {
2311 return getAssumed() ? "nofree" : "may-free";
2312 }
2313};
2314
2315struct AANoFreeFunction final : public AANoFreeImpl {
2316 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2317 : AANoFreeImpl(IRP, A) {}
2318
2319 /// See AbstractAttribute::trackStatistics()
2320 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2321};
2322
2323/// NoFree attribute deduction for a call sites.
2324struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2325 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2326 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2327
2328 /// See AbstractAttribute::trackStatistics()
2329 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2330};
2331
2332/// NoFree attribute for floating values.
2333struct AANoFreeFloating : AANoFreeImpl {
2334 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2335 : AANoFreeImpl(IRP, A) {}
2336
2337 /// See AbstractAttribute::trackStatistics()
2338 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2339
2340 /// See Abstract Attribute::updateImpl(...).
2341 ChangeStatus updateImpl(Attributor &A) override {
2342 const IRPosition &IRP = getIRPosition();
2343
2344 bool IsKnown;
2347 DepClassTy::OPTIONAL, IsKnown))
2348 return ChangeStatus::UNCHANGED;
2349
2350 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2351 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2352 Instruction *UserI = cast<Instruction>(U.getUser());
2353 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2354 if (CB->isBundleOperand(&U))
2355 return false;
2356 if (!CB->isArgOperand(&U))
2357 return true;
2358 unsigned ArgNo = CB->getArgOperandNo(&U);
2359
2360 bool IsKnown;
2362 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2363 DepClassTy::REQUIRED, IsKnown);
2364 }
2365
2366 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2367 isa<SelectInst>(UserI)) {
2368 Follow = true;
2369 return true;
2370 }
2371 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2372 return true;
2373
2374 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2375 return true;
2376
2377 // Unknown user.
2378 return false;
2379 };
2380 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2381 return indicatePessimisticFixpoint();
2382
2383 return ChangeStatus::UNCHANGED;
2384 }
2385};
2386
2387/// NoFree attribute for a call site argument.
2388struct AANoFreeArgument final : AANoFreeFloating {
2389 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2390 : AANoFreeFloating(IRP, A) {}
2391
2392 /// See AbstractAttribute::trackStatistics()
2393 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2394};
2395
2396/// NoFree attribute for call site arguments.
2397struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2398 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2399 : AANoFreeFloating(IRP, A) {}
2400
2401 /// See AbstractAttribute::updateImpl(...).
2402 ChangeStatus updateImpl(Attributor &A) override {
2403 // TODO: Once we have call site specific value information we can provide
2404 // call site specific liveness information and then it makes
2405 // sense to specialize attributes for call sites arguments instead of
2406 // redirecting requests to the callee argument.
2407 Argument *Arg = getAssociatedArgument();
2408 if (!Arg)
2409 return indicatePessimisticFixpoint();
2410 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2411 bool IsKnown;
2413 DepClassTy::REQUIRED, IsKnown))
2414 return ChangeStatus::UNCHANGED;
2415 return indicatePessimisticFixpoint();
2416 }
2417
2418 /// See AbstractAttribute::trackStatistics()
2419 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2420};
2421
2422/// NoFree attribute for function return value.
2423struct AANoFreeReturned final : AANoFreeFloating {
2424 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2425 : AANoFreeFloating(IRP, A) {
2426 llvm_unreachable("NoFree is not applicable to function returns!");
2427 }
2428
2429 /// See AbstractAttribute::initialize(...).
2430 void initialize(Attributor &A) override {
2431 llvm_unreachable("NoFree is not applicable to function returns!");
2432 }
2433
2434 /// See AbstractAttribute::updateImpl(...).
2435 ChangeStatus updateImpl(Attributor &A) override {
2436 llvm_unreachable("NoFree is not applicable to function returns!");
2437 }
2438
2439 /// See AbstractAttribute::trackStatistics()
2440 void trackStatistics() const override {}
2441};
2442
2443/// NoFree attribute deduction for a call site return value.
2444struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2445 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2446 : AANoFreeFloating(IRP, A) {}
2447
2448 ChangeStatus manifest(Attributor &A) override {
2449 return ChangeStatus::UNCHANGED;
2450 }
2451 /// See AbstractAttribute::trackStatistics()
2452 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2453};
2454} // namespace
2455
2456/// ------------------------ NonNull Argument Attribute ------------------------
2457
2459 Attribute::AttrKind ImpliedAttributeKind,
2460 bool IgnoreSubsumingPositions) {
2462 AttrKinds.push_back(Attribute::NonNull);
2465 AttrKinds.push_back(Attribute::Dereferenceable);
2466 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2467 return true;
2468
2469 DominatorTree *DT = nullptr;
2470 AssumptionCache *AC = nullptr;
2471 InformationCache &InfoCache = A.getInfoCache();
2472 if (const Function *Fn = IRP.getAnchorScope()) {
2473 if (!Fn->isDeclaration()) {
2476 }
2477 }
2478
2480 if (IRP.getPositionKind() != IRP_RETURNED) {
2481 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2482 } else {
2483 bool UsedAssumedInformation = false;
2484 if (!A.checkForAllInstructions(
2485 [&](Instruction &I) {
2486 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2487 return true;
2488 },
2489 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2490 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2491 return false;
2492 }
2493
2494 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2495 return !isKnownNonZero(
2496 VAC.getValue(),
2497 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2498 }))
2499 return false;
2500
2501 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2502 Attribute::NonNull)});
2503 return true;
2504}
2505
2506namespace {
2507static int64_t getKnownNonNullAndDerefBytesForUse(
2508 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2509 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2510 TrackUse = false;
2511
2512 const Value *UseV = U->get();
2513 if (!UseV->getType()->isPointerTy())
2514 return 0;
2515
2516 // We need to follow common pointer manipulation uses to the accesses they
2517 // feed into. We can try to be smart to avoid looking through things we do not
2518 // like for now, e.g., non-inbounds GEPs.
2519 if (isa<CastInst>(I)) {
2520 TrackUse = true;
2521 return 0;
2522 }
2523
2525 TrackUse = true;
2526 return 0;
2527 }
2528
2529 Type *PtrTy = UseV->getType();
2530 const Function *F = I->getFunction();
2533 const DataLayout &DL = A.getInfoCache().getDL();
2534 if (const auto *CB = dyn_cast<CallBase>(I)) {
2535 if (CB->isBundleOperand(U)) {
2536 if (RetainedKnowledge RK = getKnowledgeFromUse(
2537 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2538 IsNonNull |=
2539 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2540 return RK.ArgValue;
2541 }
2542 return 0;
2543 }
2544
2545 if (CB->isCallee(U)) {
2546 IsNonNull |= !NullPointerIsDefined;
2547 return 0;
2548 }
2549
2550 unsigned ArgNo = CB->getArgOperandNo(U);
2551 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2552 // As long as we only use known information there is no need to track
2553 // dependences here.
2554 bool IsKnownNonNull;
2556 DepClassTy::NONE, IsKnownNonNull);
2557 IsNonNull |= IsKnownNonNull;
2558 auto *DerefAA =
2559 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2560 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2561 }
2562
2563 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2564 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2565 Loc->Size.isScalable() || I->isVolatile())
2566 return 0;
2567
2568 int64_t Offset;
2569 const Value *Base =
2570 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2571 if (Base && Base == &AssociatedValue) {
2572 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2573 IsNonNull |= !NullPointerIsDefined;
2574 return std::max(int64_t(0), DerefBytes);
2575 }
2576
2577 /// Corner case when an offset is 0.
2579 /*AllowNonInbounds*/ true);
2580 if (Base && Base == &AssociatedValue && Offset == 0) {
2581 int64_t DerefBytes = Loc->Size.getValue();
2582 IsNonNull |= !NullPointerIsDefined;
2583 return std::max(int64_t(0), DerefBytes);
2584 }
2585
2586 return 0;
2587}
2588
2589struct AANonNullImpl : AANonNull {
2590 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2591
2592 /// See AbstractAttribute::initialize(...).
2593 void initialize(Attributor &A) override {
2594 Value &V = *getAssociatedValue().stripPointerCasts();
2595 if (isa<ConstantPointerNull>(V)) {
2596 indicatePessimisticFixpoint();
2597 return;
2598 }
2599
2600 if (Instruction *CtxI = getCtxI())
2601 followUsesInMBEC(*this, A, getState(), *CtxI);
2602 }
2603
2604 /// See followUsesInMBEC
2605 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2606 AANonNull::StateType &State) {
2607 bool IsNonNull = false;
2608 bool TrackUse = false;
2609 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2610 IsNonNull, TrackUse);
2611 State.setKnown(IsNonNull);
2612 return TrackUse;
2613 }
2614
2615 /// See AbstractAttribute::getAsStr().
2616 const std::string getAsStr(Attributor *A) const override {
2617 return getAssumed() ? "nonnull" : "may-null";
2618 }
2619};
2620
2621/// NonNull attribute for a floating value.
2622struct AANonNullFloating : public AANonNullImpl {
2623 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2624 : AANonNullImpl(IRP, A) {}
2625
2626 /// See AbstractAttribute::updateImpl(...).
2627 ChangeStatus updateImpl(Attributor &A) override {
2628 auto CheckIRP = [&](const IRPosition &IRP) {
2629 bool IsKnownNonNull;
2631 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2632 };
2633
2634 bool Stripped;
2635 bool UsedAssumedInformation = false;
2636 Value *AssociatedValue = &getAssociatedValue();
2638 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2639 AA::AnyScope, UsedAssumedInformation))
2640 Stripped = false;
2641 else
2642 Stripped =
2643 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2644
2645 if (!Stripped) {
2646 bool IsKnown;
2647 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2648 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2649 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2650 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2651 IsKnown);
2652 }))
2653 return ChangeStatus::UNCHANGED;
2654 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2656 A, this, IRPosition::value(*Select->getFalseValue()),
2657 DepClassTy::OPTIONAL, IsKnown) &&
2659 A, this, IRPosition::value(*Select->getTrueValue()),
2660 DepClassTy::OPTIONAL, IsKnown))
2661 return ChangeStatus::UNCHANGED;
2662
2663 // If we haven't stripped anything we might still be able to use a
2664 // different AA, but only if the IRP changes. Effectively when we
2665 // interpret this not as a call site value but as a floating/argument
2666 // value.
2667 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2668 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2669 return indicatePessimisticFixpoint();
2670 return ChangeStatus::UNCHANGED;
2671 }
2672
2673 for (const auto &VAC : Values)
2674 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2675 return indicatePessimisticFixpoint();
2676
2677 return ChangeStatus::UNCHANGED;
2678 }
2679
2680 /// See AbstractAttribute::trackStatistics()
2681 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2682};
2683
2684/// NonNull attribute for function return value.
2685struct AANonNullReturned final
2686 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2687 false, AANonNull::IRAttributeKind, false> {
2688 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2689 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2690 false, Attribute::NonNull, false>(IRP, A) {
2691 }
2692
2693 /// See AbstractAttribute::getAsStr().
2694 const std::string getAsStr(Attributor *A) const override {
2695 return getAssumed() ? "nonnull" : "may-null";
2696 }
2697
2698 /// See AbstractAttribute::trackStatistics()
2699 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2700};
2701
2702/// NonNull attribute for function argument.
2703struct AANonNullArgument final
2704 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2705 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2706 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2707
2708 /// See AbstractAttribute::trackStatistics()
2709 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2710};
2711
2712struct AANonNullCallSiteArgument final : AANonNullFloating {
2713 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2714 : AANonNullFloating(IRP, A) {}
2715
2716 /// See AbstractAttribute::trackStatistics()
2717 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2718};
2719
2720/// NonNull attribute for a call site return position.
2721struct AANonNullCallSiteReturned final
2722 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2723 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2724 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2725
2726 /// See AbstractAttribute::trackStatistics()
2727 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2728};
2729} // namespace
2730
2731/// ------------------------ Must-Progress Attributes --------------------------
2732namespace {
2733struct AAMustProgressImpl : public AAMustProgress {
2734 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2735 : AAMustProgress(IRP, A) {}
2736
2737 /// See AbstractAttribute::initialize(...).
2738 void initialize(Attributor &A) override {
2739 bool IsKnown;
2741 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2742 (void)IsKnown;
2743 }
2744
2745 /// See AbstractAttribute::getAsStr()
2746 const std::string getAsStr(Attributor *A) const override {
2747 return getAssumed() ? "mustprogress" : "may-not-progress";
2748 }
2749};
2750
2751struct AAMustProgressFunction final : AAMustProgressImpl {
2752 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2753 : AAMustProgressImpl(IRP, A) {}
2754
2755 /// See AbstractAttribute::updateImpl(...).
2756 ChangeStatus updateImpl(Attributor &A) override {
2757 bool IsKnown;
2759 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2760 if (IsKnown)
2761 return indicateOptimisticFixpoint();
2762 return ChangeStatus::UNCHANGED;
2763 }
2764
2765 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2766 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2767 bool IsKnownMustProgress;
2769 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2770 /* IgnoreSubsumingPositions */ true);
2771 };
2772
2773 bool AllCallSitesKnown = true;
2774 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2775 /* RequireAllCallSites */ true,
2776 AllCallSitesKnown))
2777 return indicatePessimisticFixpoint();
2778
2779 return ChangeStatus::UNCHANGED;
2780 }
2781
2782 /// See AbstractAttribute::trackStatistics()
2783 void trackStatistics() const override {
2784 STATS_DECLTRACK_FN_ATTR(mustprogress)
2785 }
2786};
2787
2788/// MustProgress attribute deduction for a call sites.
2789struct AAMustProgressCallSite final : AAMustProgressImpl {
2790 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2791 : AAMustProgressImpl(IRP, A) {}
2792
2793 /// See AbstractAttribute::updateImpl(...).
2794 ChangeStatus updateImpl(Attributor &A) override {
2795 // TODO: Once we have call site specific value information we can provide
2796 // call site specific liveness information and then it makes
2797 // sense to specialize attributes for call sites arguments instead of
2798 // redirecting requests to the callee argument.
2799 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2800 bool IsKnownMustProgress;
2802 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2803 return indicatePessimisticFixpoint();
2804 return ChangeStatus::UNCHANGED;
2805 }
2806
2807 /// See AbstractAttribute::trackStatistics()
2808 void trackStatistics() const override {
2809 STATS_DECLTRACK_CS_ATTR(mustprogress);
2810 }
2811};
2812} // namespace
2813
2814/// ------------------------ No-Recurse Attributes ----------------------------
2815
2816namespace {
2817struct AANoRecurseImpl : public AANoRecurse {
2818 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2819
2820 /// See AbstractAttribute::initialize(...).
2821 void initialize(Attributor &A) override {
2822 bool IsKnown;
2824 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2825 (void)IsKnown;
2826 }
2827
2828 /// See AbstractAttribute::getAsStr()
2829 const std::string getAsStr(Attributor *A) const override {
2830 return getAssumed() ? "norecurse" : "may-recurse";
2831 }
2832};
2833
2834struct AANoRecurseFunction final : AANoRecurseImpl {
2835 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2836 : AANoRecurseImpl(IRP, A) {}
2837
2838 /// See AbstractAttribute::updateImpl(...).
2839 ChangeStatus updateImpl(Attributor &A) override {
2840
2841 // If all live call sites are known to be no-recurse, we are as well.
2842 auto CallSitePred = [&](AbstractCallSite ACS) {
2843 bool IsKnownNoRecurse;
2845 A, this,
2846 IRPosition::function(*ACS.getInstruction()->getFunction()),
2847 DepClassTy::NONE, IsKnownNoRecurse))
2848 return false;
2849 return IsKnownNoRecurse;
2850 };
2851 bool UsedAssumedInformation = false;
2852 if (A.checkForAllCallSites(CallSitePred, *this, true,
2853 UsedAssumedInformation)) {
2854 // If we know all call sites and all are known no-recurse, we are done.
2855 // If all known call sites, which might not be all that exist, are known
2856 // to be no-recurse, we are not done but we can continue to assume
2857 // no-recurse. If one of the call sites we have not visited will become
2858 // live, another update is triggered.
2859 if (!UsedAssumedInformation)
2860 indicateOptimisticFixpoint();
2861 return ChangeStatus::UNCHANGED;
2862 }
2863
2864 const AAInterFnReachability *EdgeReachability =
2865 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2866 DepClassTy::REQUIRED);
2867 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2868 return indicatePessimisticFixpoint();
2869 return ChangeStatus::UNCHANGED;
2870 }
2871
2872 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2873};
2874
2875/// NoRecurse attribute deduction for a call sites.
2876struct AANoRecurseCallSite final
2877 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2878 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2879 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2880
2881 /// See AbstractAttribute::trackStatistics()
2882 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2883};
2884} // namespace
2885
2886/// ------------------------ No-Convergent Attribute --------------------------
2887
2888namespace {
2889struct AANonConvergentImpl : public AANonConvergent {
2890 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2891 : AANonConvergent(IRP, A) {}
2892
2893 /// See AbstractAttribute::getAsStr()
2894 const std::string getAsStr(Attributor *A) const override {
2895 return getAssumed() ? "non-convergent" : "may-be-convergent";
2896 }
2897};
2898
2899struct AANonConvergentFunction final : AANonConvergentImpl {
2900 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2901 : AANonConvergentImpl(IRP, A) {}
2902
2903 /// See AbstractAttribute::updateImpl(...).
2904 ChangeStatus updateImpl(Attributor &A) override {
2905 // If all function calls are known to not be convergent, we are not
2906 // convergent.
2907 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2908 CallBase &CB = cast<CallBase>(Inst);
2910 if (!Callee || Callee->isIntrinsic()) {
2911 return false;
2912 }
2913 if (Callee->isDeclaration()) {
2914 return !Callee->hasFnAttribute(Attribute::Convergent);
2915 }
2916 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2917 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2918 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2919 };
2920
2921 bool UsedAssumedInformation = false;
2922 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2923 UsedAssumedInformation)) {
2924 return indicatePessimisticFixpoint();
2925 }
2926 return ChangeStatus::UNCHANGED;
2927 }
2928
2929 ChangeStatus manifest(Attributor &A) override {
2930 if (isKnownNotConvergent() &&
2931 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2932 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2933 return ChangeStatus::CHANGED;
2934 }
2935 return ChangeStatus::UNCHANGED;
2936 }
2937
2938 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2939};
2940} // namespace
2941
2942/// -------------------- Undefined-Behavior Attributes ------------------------
2943
2944namespace {
2945struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2946 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2947 : AAUndefinedBehavior(IRP, A) {}
2948
2949 /// See AbstractAttribute::updateImpl(...).
2950 // through a pointer (i.e. also branches etc.)
2951 ChangeStatus updateImpl(Attributor &A) override {
2952 const size_t UBPrevSize = KnownUBInsts.size();
2953 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2954
2955 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2956 // Lang ref now states volatile store is not UB, let's skip them.
2957 if (I.isVolatile() && I.mayWriteToMemory())
2958 return true;
2959
2960 // Skip instructions that are already saved.
2961 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2962 return true;
2963
2964 // If we reach here, we know we have an instruction
2965 // that accesses memory through a pointer operand,
2966 // for which getPointerOperand() should give it to us.
2967 Value *PtrOp =
2968 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2969 assert(PtrOp &&
2970 "Expected pointer operand of memory accessing instruction");
2971
2972 // Either we stopped and the appropriate action was taken,
2973 // or we got back a simplified value to continue.
2974 std::optional<Value *> SimplifiedPtrOp =
2975 stopOnUndefOrAssumed(A, PtrOp, &I);
2976 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2977 return true;
2978 const Value *PtrOpVal = *SimplifiedPtrOp;
2979
2980 // A memory access through a pointer is considered UB
2981 // only if the pointer has constant null value.
2982 // TODO: Expand it to not only check constant values.
2983 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2984 AssumedNoUBInsts.insert(&I);
2985 return true;
2986 }
2987 const Type *PtrTy = PtrOpVal->getType();
2988
2989 // Because we only consider instructions inside functions,
2990 // assume that a parent function exists.
2991 const Function *F = I.getFunction();
2992
2993 // A memory access using constant null pointer is only considered UB
2994 // if null pointer is _not_ defined for the target platform.
2996 AssumedNoUBInsts.insert(&I);
2997 else
2998 KnownUBInsts.insert(&I);
2999 return true;
3000 };
3001
3002 auto InspectBrInstForUB = [&](Instruction &I) {
3003 // A conditional branch instruction is considered UB if it has `undef`
3004 // condition.
3005
3006 // Skip instructions that are already saved.
3007 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3008 return true;
3009
3010 // We know we have a branch instruction.
3011 auto *BrInst = cast<BranchInst>(&I);
3012
3013 // Unconditional branches are never considered UB.
3014 if (BrInst->isUnconditional())
3015 return true;
3016
3017 // Either we stopped and the appropriate action was taken,
3018 // or we got back a simplified value to continue.
3019 std::optional<Value *> SimplifiedCond =
3020 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3021 if (!SimplifiedCond || !*SimplifiedCond)
3022 return true;
3023 AssumedNoUBInsts.insert(&I);
3024 return true;
3025 };
3026
3027 auto InspectCallSiteForUB = [&](Instruction &I) {
3028 // Check whether a callsite always cause UB or not
3029
3030 // Skip instructions that are already saved.
3031 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3032 return true;
3033
3034 // Check nonnull and noundef argument attribute violation for each
3035 // callsite.
3036 CallBase &CB = cast<CallBase>(I);
3038 if (!Callee)
3039 return true;
3040 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3041 // If current argument is known to be simplified to null pointer and the
3042 // corresponding argument position is known to have nonnull attribute,
3043 // the argument is poison. Furthermore, if the argument is poison and
3044 // the position is known to have noundef attriubte, this callsite is
3045 // considered UB.
3046 if (idx >= Callee->arg_size())
3047 break;
3048 Value *ArgVal = CB.getArgOperand(idx);
3049 if (!ArgVal)
3050 continue;
3051 // Here, we handle three cases.
3052 // (1) Not having a value means it is dead. (we can replace the value
3053 // with undef)
3054 // (2) Simplified to undef. The argument violate noundef attriubte.
3055 // (3) Simplified to null pointer where known to be nonnull.
3056 // The argument is a poison value and violate noundef attribute.
3057 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3058 bool IsKnownNoUndef;
3060 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3061 if (!IsKnownNoUndef)
3062 continue;
3063 bool UsedAssumedInformation = false;
3064 std::optional<Value *> SimplifiedVal =
3065 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3066 UsedAssumedInformation, AA::Interprocedural);
3067 if (UsedAssumedInformation)
3068 continue;
3069 if (SimplifiedVal && !*SimplifiedVal)
3070 return true;
3071 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3072 KnownUBInsts.insert(&I);
3073 continue;
3074 }
3075 if (!ArgVal->getType()->isPointerTy() ||
3076 !isa<ConstantPointerNull>(**SimplifiedVal))
3077 continue;
3078 bool IsKnownNonNull;
3080 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3081 if (IsKnownNonNull)
3082 KnownUBInsts.insert(&I);
3083 }
3084 return true;
3085 };
3086
3087 auto InspectReturnInstForUB = [&](Instruction &I) {
3088 auto &RI = cast<ReturnInst>(I);
3089 // Either we stopped and the appropriate action was taken,
3090 // or we got back a simplified return value to continue.
3091 std::optional<Value *> SimplifiedRetValue =
3092 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3093 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3094 return true;
3095
3096 // Check if a return instruction always cause UB or not
3097 // Note: It is guaranteed that the returned position of the anchor
3098 // scope has noundef attribute when this is called.
3099 // We also ensure the return position is not "assumed dead"
3100 // because the returned value was then potentially simplified to
3101 // `undef` in AAReturnedValues without removing the `noundef`
3102 // attribute yet.
3103
3104 // When the returned position has noundef attriubte, UB occurs in the
3105 // following cases.
3106 // (1) Returned value is known to be undef.
3107 // (2) The value is known to be a null pointer and the returned
3108 // position has nonnull attribute (because the returned value is
3109 // poison).
3110 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3111 bool IsKnownNonNull;
3113 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3114 IsKnownNonNull);
3115 if (IsKnownNonNull)
3116 KnownUBInsts.insert(&I);
3117 }
3118
3119 return true;
3120 };
3121
3122 bool UsedAssumedInformation = false;
3123 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3124 {Instruction::Load, Instruction::Store,
3125 Instruction::AtomicCmpXchg,
3126 Instruction::AtomicRMW},
3127 UsedAssumedInformation,
3128 /* CheckBBLivenessOnly */ true);
3129 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3130 UsedAssumedInformation,
3131 /* CheckBBLivenessOnly */ true);
3132 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3133 UsedAssumedInformation);
3134
3135 // If the returned position of the anchor scope has noundef attriubte, check
3136 // all returned instructions.
3137 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3138 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3139 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3140 bool IsKnownNoUndef;
3142 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3143 if (IsKnownNoUndef)
3144 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3145 {Instruction::Ret}, UsedAssumedInformation,
3146 /* CheckBBLivenessOnly */ true);
3147 }
3148 }
3149
3150 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3151 UBPrevSize != KnownUBInsts.size())
3152 return ChangeStatus::CHANGED;
3153 return ChangeStatus::UNCHANGED;
3154 }
3155
3156 bool isKnownToCauseUB(Instruction *I) const override {
3157 return KnownUBInsts.count(I);
3158 }
3159
3160 bool isAssumedToCauseUB(Instruction *I) const override {
3161 // In simple words, if an instruction is not in the assumed to _not_
3162 // cause UB, then it is assumed UB (that includes those
3163 // in the KnownUBInsts set). The rest is boilerplate
3164 // is to ensure that it is one of the instructions we test
3165 // for UB.
3166
3167 switch (I->getOpcode()) {
3168 case Instruction::Load:
3169 case Instruction::Store:
3170 case Instruction::AtomicCmpXchg:
3171 case Instruction::AtomicRMW:
3172 return !AssumedNoUBInsts.count(I);
3173 case Instruction::Br: {
3174 auto *BrInst = cast<BranchInst>(I);
3175 if (BrInst->isUnconditional())
3176 return false;
3177 return !AssumedNoUBInsts.count(I);
3178 } break;
3179 default:
3180 return false;
3181 }
3182 return false;
3183 }
3184
3185 ChangeStatus manifest(Attributor &A) override {
3186 if (KnownUBInsts.empty())
3187 return ChangeStatus::UNCHANGED;
3188 for (Instruction *I : KnownUBInsts)
3189 A.changeToUnreachableAfterManifest(I);
3190 return ChangeStatus::CHANGED;
3191 }
3192
3193 /// See AbstractAttribute::getAsStr()
3194 const std::string getAsStr(Attributor *A) const override {
3195 return getAssumed() ? "undefined-behavior" : "no-ub";
3196 }
3197
3198 /// Note: The correctness of this analysis depends on the fact that the
3199 /// following 2 sets will stop changing after some point.
3200 /// "Change" here means that their size changes.
3201 /// The size of each set is monotonically increasing
3202 /// (we only add items to them) and it is upper bounded by the number of
3203 /// instructions in the processed function (we can never save more
3204 /// elements in either set than this number). Hence, at some point,
3205 /// they will stop increasing.
3206 /// Consequently, at some point, both sets will have stopped
3207 /// changing, effectively making the analysis reach a fixpoint.
3208
3209 /// Note: These 2 sets are disjoint and an instruction can be considered
3210 /// one of 3 things:
3211 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3212 /// the KnownUBInsts set.
3213 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3214 /// has a reason to assume it).
3215 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3216 /// could not find a reason to assume or prove that it can cause UB,
3217 /// hence it assumes it doesn't. We have a set for these instructions
3218 /// so that we don't reprocess them in every update.
3219 /// Note however that instructions in this set may cause UB.
3220
3221protected:
3222 /// A set of all live instructions _known_ to cause UB.
3223 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3224
3225private:
3226 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3227 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3228
3229 // Should be called on updates in which if we're processing an instruction
3230 // \p I that depends on a value \p V, one of the following has to happen:
3231 // - If the value is assumed, then stop.
3232 // - If the value is known but undef, then consider it UB.
3233 // - Otherwise, do specific processing with the simplified value.
3234 // We return std::nullopt in the first 2 cases to signify that an appropriate
3235 // action was taken and the caller should stop.
3236 // Otherwise, we return the simplified value that the caller should
3237 // use for specific processing.
3238 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3239 Instruction *I) {
3240 bool UsedAssumedInformation = false;
3241 std::optional<Value *> SimplifiedV =
3242 A.getAssumedSimplified(IRPosition::value(*V), *this,
3243 UsedAssumedInformation, AA::Interprocedural);
3244 if (!UsedAssumedInformation) {
3245 // Don't depend on assumed values.
3246 if (!SimplifiedV) {
3247 // If it is known (which we tested above) but it doesn't have a value,
3248 // then we can assume `undef` and hence the instruction is UB.
3249 KnownUBInsts.insert(I);
3250 return std::nullopt;
3251 }
3252 if (!*SimplifiedV)
3253 return nullptr;
3254 V = *SimplifiedV;
3255 }
3256 if (isa<UndefValue>(V)) {
3257 KnownUBInsts.insert(I);
3258 return std::nullopt;
3259 }
3260 return V;
3261 }
3262};
3263
3264struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3265 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3266 : AAUndefinedBehaviorImpl(IRP, A) {}
3267
3268 /// See AbstractAttribute::trackStatistics()
3269 void trackStatistics() const override {
3270 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3271 "Number of instructions known to have UB");
3272 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3273 KnownUBInsts.size();
3274 }
3275};
3276} // namespace
3277
3278/// ------------------------ Will-Return Attributes ----------------------------
3279
3280namespace {
3281// Helper function that checks whether a function has any cycle which we don't
3282// know if it is bounded or not.
3283// Loops with maximum trip count are considered bounded, any other cycle not.
3284static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3285 ScalarEvolution *SE =
3286 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3287 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3288 // If either SCEV or LoopInfo is not available for the function then we assume
3289 // any cycle to be unbounded cycle.
3290 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3291 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3292 if (!SE || !LI) {
3293 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3294 if (SCCI.hasCycle())
3295 return true;
3296 return false;
3297 }
3298
3299 // If there's irreducible control, the function may contain non-loop cycles.
3301 return true;
3302
3303 // Any loop that does not have a max trip count is considered unbounded cycle.
3304 for (auto *L : LI->getLoopsInPreorder()) {
3305 if (!SE->getSmallConstantMaxTripCount(L))
3306 return true;
3307 }
3308 return false;
3309}
3310
3311struct AAWillReturnImpl : public AAWillReturn {
3312 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3313 : AAWillReturn(IRP, A) {}
3314
3315 /// See AbstractAttribute::initialize(...).
3316 void initialize(Attributor &A) override {
3317 bool IsKnown;
3319 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3320 (void)IsKnown;
3321 }
3322
3323 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3324 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3325 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3326 return false;
3327
3328 bool IsKnown;
3329 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3330 return IsKnown || !KnownOnly;
3331 return false;
3332 }
3333
3334 /// See AbstractAttribute::updateImpl(...).
3335 ChangeStatus updateImpl(Attributor &A) override {
3336 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3337 return ChangeStatus::UNCHANGED;
3338
3339 auto CheckForWillReturn = [&](Instruction &I) {
3341 bool IsKnown;
3343 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3344 if (IsKnown)
3345 return true;
3346 } else {
3347 return false;
3348 }
3349 bool IsKnownNoRecurse;
3351 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3352 };
3353
3354 bool UsedAssumedInformation = false;
3355 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3356 UsedAssumedInformation))
3357 return indicatePessimisticFixpoint();
3358
3359 return ChangeStatus::UNCHANGED;
3360 }
3361
3362 /// See AbstractAttribute::getAsStr()
3363 const std::string getAsStr(Attributor *A) const override {
3364 return getAssumed() ? "willreturn" : "may-noreturn";
3365 }
3366};
3367
3368struct AAWillReturnFunction final : AAWillReturnImpl {
3369 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3370 : AAWillReturnImpl(IRP, A) {}
3371
3372 /// See AbstractAttribute::initialize(...).
3373 void initialize(Attributor &A) override {
3374 AAWillReturnImpl::initialize(A);
3375
3376 Function *F = getAnchorScope();
3377 assert(F && "Did expect an anchor function");
3378 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3379 indicatePessimisticFixpoint();
3380 }
3381
3382 /// See AbstractAttribute::trackStatistics()
3383 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3384};
3385
3386/// WillReturn attribute deduction for a call sites.
3387struct AAWillReturnCallSite final
3388 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3389 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3390 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3391
3392 /// See AbstractAttribute::updateImpl(...).
3393 ChangeStatus updateImpl(Attributor &A) override {
3394 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3395 return ChangeStatus::UNCHANGED;
3396
3397 return AACalleeToCallSite::updateImpl(A);
3398 }
3399
3400 /// See AbstractAttribute::trackStatistics()
3401 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3402};
3403} // namespace
3404
3405/// -------------------AAIntraFnReachability Attribute--------------------------
3406
3407/// All information associated with a reachability query. This boilerplate code
3408/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3409/// different \p ToTy values.
3410template <typename ToTy> struct ReachabilityQueryInfo {
3411 enum class Reachable {
3414 };
3415
3416 /// Start here,
3417 const Instruction *From = nullptr;
3418 /// reach this place,
3419 const ToTy *To = nullptr;
3420 /// without going through any of these instructions,
3422 /// and remember if it worked:
3424
3425 /// Precomputed hash for this RQI.
3426 unsigned Hash = 0;
3427
3428 unsigned computeHashValue() const {
3429 assert(Hash == 0 && "Computed hash twice!");
3432 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3433 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3434 InstSetDMI::getHashValue(ExclusionSet));
3435 }
3436
3438 : From(From), To(To) {}
3439
3440 /// Constructor replacement to ensure unique and stable sets are used for the
3441 /// cache.
3443 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3444 : From(&From), To(&To), ExclusionSet(ES) {
3445
3446 if (!ES || ES->empty()) {
3447 ExclusionSet = nullptr;
3448 } else if (MakeUnique) {
3449 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3450 }
3451 }
3452
3455};
3456
3457namespace llvm {
3458template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3461
3464
3467 return &TombstoneKey;
3468 }
3469 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3470 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3471 }
3472 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3473 const ReachabilityQueryInfo<ToTy> *RHS) {
3474 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3475 return false;
3476 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3477 }
3478};
3479
3480#define DefineKeys(ToTy) \
3481 template <> \
3482 ReachabilityQueryInfo<ToTy> \
3483 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3484 ReachabilityQueryInfo<ToTy>( \
3485 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3486 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3487 template <> \
3488 ReachabilityQueryInfo<ToTy> \
3489 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3490 ReachabilityQueryInfo<ToTy>( \
3491 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3492 DenseMapInfo<const ToTy *>::getTombstoneKey());
3493
3495#undef DefineKeys
3496
3497} // namespace llvm
3498
3499namespace {
3500
3501template <typename BaseTy, typename ToTy>
3502struct CachedReachabilityAA : public BaseTy {
3503 using RQITy = ReachabilityQueryInfo<ToTy>;
3504
3505 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3506
3507 /// See AbstractAttribute::isQueryAA.
3508 bool isQueryAA() const override { return true; }
3509
3510 /// See AbstractAttribute::updateImpl(...).
3511 ChangeStatus updateImpl(Attributor &A) override {
3512 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3513 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3514 RQITy *RQI = QueryVector[u];
3515 if (RQI->Result == RQITy::Reachable::No &&
3516 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3517 Changed = ChangeStatus::CHANGED;
3518 }
3519 return Changed;
3520 }
3521
3522 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3523 bool IsTemporaryRQI) = 0;
3524
3525 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3526 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3527 RQI.Result = Result;
3528
3529 // Remove the temporary RQI from the cache.
3530 if (IsTemporaryRQI)
3531 QueryCache.erase(&RQI);
3532
3533 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3534 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3535 // this query. 2) We did not use the exclusion set, potentially because
3536 // there is none.
3537 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3538 RQITy PlainRQI(RQI.From, RQI.To);
3539 if (!QueryCache.count(&PlainRQI)) {
3540 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3541 RQIPtr->Result = Result;
3542 QueryVector.push_back(RQIPtr);
3543 QueryCache.insert(RQIPtr);
3544 }
3545 }
3546
3547 // Check if we need to insert a new permanent RQI with the exclusion set.
3548 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3549 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3550 "Did not expect empty set!");
3551 RQITy *RQIPtr = new (A.Allocator)
3552 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3553 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3554 RQIPtr->Result = Result;
3555 assert(!QueryCache.count(RQIPtr));
3556 QueryVector.push_back(RQIPtr);
3557 QueryCache.insert(RQIPtr);
3558 }
3559
3560 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3561 A.registerForUpdate(*this);
3562 return Result == RQITy::Reachable::Yes;
3563 }
3564
3565 const std::string getAsStr(Attributor *A) const override {
3566 // TODO: Return the number of reachable queries.
3567 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3568 }
3569
3570 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3571 typename RQITy::Reachable &Result) {
3572 if (!this->getState().isValidState()) {
3573 Result = RQITy::Reachable::Yes;
3574 return true;
3575 }
3576
3577 // If we have an exclusion set we might be able to find our answer by
3578 // ignoring it first.
3579 if (StackRQI.ExclusionSet) {
3580 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3581 auto It = QueryCache.find(&PlainRQI);
3582 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3583 Result = RQITy::Reachable::No;
3584 return true;
3585 }
3586 }
3587
3588 auto It = QueryCache.find(&StackRQI);
3589 if (It != QueryCache.end()) {
3590 Result = (*It)->Result;
3591 return true;
3592 }
3593
3594 // Insert a temporary for recursive queries. We will replace it with a
3595 // permanent entry later.
3596 QueryCache.insert(&StackRQI);
3597 return false;
3598 }
3599
3600private:
3601 SmallVector<RQITy *> QueryVector;
3602 DenseSet<RQITy *> QueryCache;
3603};
3604
3605struct AAIntraFnReachabilityFunction final
3606 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3607 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3608 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3609 : Base(IRP, A) {
3610 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3611 *IRP.getAssociatedFunction());
3612 }
3613
3614 bool isAssumedReachable(
3615 Attributor &A, const Instruction &From, const Instruction &To,
3616 const AA::InstExclusionSetTy *ExclusionSet) const override {
3617 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3618 if (&From == &To)
3619 return true;
3620
3621 RQITy StackRQI(A, From, To, ExclusionSet, false);
3622 RQITy::Reachable Result;
3623 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3624 return NonConstThis->isReachableImpl(A, StackRQI,
3625 /*IsTemporaryRQI=*/true);
3626 return Result == RQITy::Reachable::Yes;
3627 }
3628
3629 ChangeStatus updateImpl(Attributor &A) override {
3630 // We only depend on liveness. DeadEdges is all we care about, check if any
3631 // of them changed.
3632 auto *LivenessAA =
3633 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3634 if (LivenessAA &&
3635 llvm::all_of(DeadEdges,
3636 [&](const auto &DeadEdge) {
3637 return LivenessAA->isEdgeDead(DeadEdge.first,
3638 DeadEdge.second);
3639 }) &&
3640 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3641 return LivenessAA->isAssumedDead(BB);
3642 })) {
3643 return ChangeStatus::UNCHANGED;
3644 }
3645 DeadEdges.clear();
3646 DeadBlocks.clear();
3647 return Base::updateImpl(A);
3648 }
3649
3650 bool isReachableImpl(Attributor &A, RQITy &RQI,
3651 bool IsTemporaryRQI) override {
3652 const Instruction *Origin = RQI.From;
3653 bool UsedExclusionSet = false;
3654
3655 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3656 const AA::InstExclusionSetTy *ExclusionSet) {
3657 const Instruction *IP = &From;
3658 while (IP && IP != &To) {
3659 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3660 UsedExclusionSet = true;
3661 break;
3662 }
3663 IP = IP->getNextNode();
3664 }
3665 return IP == &To;
3666 };
3667
3668 const BasicBlock *FromBB = RQI.From->getParent();
3669 const BasicBlock *ToBB = RQI.To->getParent();
3670 assert(FromBB->getParent() == ToBB->getParent() &&
3671 "Not an intra-procedural query!");
3672
3673 // Check intra-block reachability, however, other reaching paths are still
3674 // possible.
3675 if (FromBB == ToBB &&
3676 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3677 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3678 IsTemporaryRQI);
3679
3680 // Check if reaching the ToBB block is sufficient or if even that would not
3681 // ensure reaching the target. In the latter case we are done.
3682 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3683 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3684 IsTemporaryRQI);
3685
3686 const Function *Fn = FromBB->getParent();
3687 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3688 if (RQI.ExclusionSet)
3689 for (auto *I : *RQI.ExclusionSet)
3690 if (I->getFunction() == Fn)
3691 ExclusionBlocks.insert(I->getParent());
3692
3693 // Check if we make it out of the FromBB block at all.
3694 if (ExclusionBlocks.count(FromBB) &&
3695 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3696 RQI.ExclusionSet))
3697 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3698
3699 auto *LivenessAA =
3700 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3701 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3702 DeadBlocks.insert(ToBB);
3703 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3704 IsTemporaryRQI);
3705 }
3706
3707 SmallPtrSet<const BasicBlock *, 16> Visited;
3709 Worklist.push_back(FromBB);
3710
3711 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3712 while (!Worklist.empty()) {
3713 const BasicBlock *BB = Worklist.pop_back_val();
3714 if (!Visited.insert(BB).second)
3715 continue;
3716 for (const BasicBlock *SuccBB : successors(BB)) {
3717 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3718 LocalDeadEdges.insert({BB, SuccBB});
3719 continue;
3720 }
3721 // We checked before if we just need to reach the ToBB block.
3722 if (SuccBB == ToBB)
3723 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3724 IsTemporaryRQI);
3725 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3726 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3727 IsTemporaryRQI);
3728
3729 if (ExclusionBlocks.count(SuccBB)) {
3730 UsedExclusionSet = true;
3731 continue;
3732 }
3733 Worklist.push_back(SuccBB);
3734 }
3735 }
3736
3737 DeadEdges.insert_range(LocalDeadEdges);
3738 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3739 IsTemporaryRQI);
3740 }
3741
3742 /// See AbstractAttribute::trackStatistics()
3743 void trackStatistics() const override {}
3744
3745private:
3746 // Set of assumed dead blocks we used in the last query. If any changes we
3747 // update the state.
3748 DenseSet<const BasicBlock *> DeadBlocks;
3749
3750 // Set of assumed dead edges we used in the last query. If any changes we
3751 // update the state.
3752 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3753
3754 /// The dominator tree of the function to short-circuit reasoning.
3755 const DominatorTree *DT = nullptr;
3756};
3757} // namespace
3758
3759/// ------------------------ NoAlias Argument Attribute ------------------------
3760
3762 Attribute::AttrKind ImpliedAttributeKind,
3763 bool IgnoreSubsumingPositions) {
3764 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3765 "Unexpected attribute kind");
3766 Value *Val = &IRP.getAssociatedValue();
3768 if (isa<AllocaInst>(Val))
3769 return true;
3770 } else {
3771 IgnoreSubsumingPositions = true;
3772 }
3773
3774 if (isa<UndefValue>(Val))
3775 return true;
3776
3777 if (isa<ConstantPointerNull>(Val) &&
3780 return true;
3781
3782 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3783 IgnoreSubsumingPositions, Attribute::NoAlias))
3784 return true;
3785
3786 return false;
3787}
3788
3789namespace {
3790struct AANoAliasImpl : AANoAlias {
3791 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3792 assert(getAssociatedType()->isPointerTy() &&
3793 "Noalias is a pointer attribute");
3794 }
3795
3796 const std::string getAsStr(Attributor *A) const override {
3797 return getAssumed() ? "noalias" : "may-alias";
3798 }
3799};
3800
3801/// NoAlias attribute for a floating value.
3802struct AANoAliasFloating final : AANoAliasImpl {
3803 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3804 : AANoAliasImpl(IRP, A) {}
3805
3806 /// See AbstractAttribute::updateImpl(...).
3807 ChangeStatus updateImpl(Attributor &A) override {
3808 // TODO: Implement this.
3809 return indicatePessimisticFixpoint();
3810 }
3811
3812 /// See AbstractAttribute::trackStatistics()
3813 void trackStatistics() const override {
3815 }
3816};
3817
3818/// NoAlias attribute for an argument.
3819struct AANoAliasArgument final
3820 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3821 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3822 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3823
3824 /// See AbstractAttribute::update(...).
3825 ChangeStatus updateImpl(Attributor &A) override {
3826 // We have to make sure no-alias on the argument does not break
3827 // synchronization when this is a callback argument, see also [1] below.
3828 // If synchronization cannot be affected, we delegate to the base updateImpl
3829 // function, otherwise we give up for now.
3830
3831 // If the function is no-sync, no-alias cannot break synchronization.
3832 bool IsKnownNoSycn;
3834 A, this, IRPosition::function_scope(getIRPosition()),
3835 DepClassTy::OPTIONAL, IsKnownNoSycn))
3836 return Base::updateImpl(A);
3837
3838 // If the argument is read-only, no-alias cannot break synchronization.
3839 bool IsKnown;
3840 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3841 return Base::updateImpl(A);
3842
3843 // If the argument is never passed through callbacks, no-alias cannot break
3844 // synchronization.
3845 bool UsedAssumedInformation = false;
3846 if (A.checkForAllCallSites(
3847 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3848 true, UsedAssumedInformation))
3849 return Base::updateImpl(A);
3850
3851 // TODO: add no-alias but make sure it doesn't break synchronization by
3852 // introducing fake uses. See:
3853 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3854 // International Workshop on OpenMP 2018,
3855 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3856
3857 return indicatePessimisticFixpoint();
3858 }
3859
3860 /// See AbstractAttribute::trackStatistics()
3861 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3862};
3863
3864struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3865 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3866 : AANoAliasImpl(IRP, A) {}
3867
3868 /// Determine if the underlying value may alias with the call site argument
3869 /// \p OtherArgNo of \p ICS (= the underlying call site).
3870 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3871 const AAMemoryBehavior &MemBehaviorAA,
3872 const CallBase &CB, unsigned OtherArgNo) {
3873 // We do not need to worry about aliasing with the underlying IRP.
3874 if (this->getCalleeArgNo() == (int)OtherArgNo)
3875 return false;
3876
3877 // If it is not a pointer or pointer vector we do not alias.
3878 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3879 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3880 return false;
3881
3882 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3883 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3884
3885 // If the argument is readnone, there is no read-write aliasing.
3886 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3887 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3888 return false;
3889 }
3890
3891 // If the argument is readonly and the underlying value is readonly, there
3892 // is no read-write aliasing.
3893 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3894 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3895 IsReadOnly) {
3896 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3897 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3898 return false;
3899 }
3900
3901 // We have to utilize actual alias analysis queries so we need the object.
3902 if (!AAR)
3903 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3904 *getAnchorScope());
3905
3906 // Try to rule it out at the call site.
3907 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3908 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3909 "callsite arguments: "
3910 << getAssociatedValue() << " " << *ArgOp << " => "
3911 << (IsAliasing ? "" : "no-") << "alias \n");
3912
3913 return IsAliasing;
3914 }
3915
3916 bool isKnownNoAliasDueToNoAliasPreservation(
3917 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3918 // We can deduce "noalias" if the following conditions hold.
3919 // (i) Associated value is assumed to be noalias in the definition.
3920 // (ii) Associated value is assumed to be no-capture in all the uses
3921 // possibly executed before this callsite.
3922 // (iii) There is no other pointer argument which could alias with the
3923 // value.
3924
3925 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3926 const Function *ScopeFn = VIRP.getAnchorScope();
3927 // Check whether the value is captured in the scope using AANoCapture.
3928 // Look at CFG and check only uses possibly executed before this
3929 // callsite.
3930 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3931 Instruction *UserI = cast<Instruction>(U.getUser());
3932
3933 // If UserI is the curr instruction and there is a single potential use of
3934 // the value in UserI we allow the use.
3935 // TODO: We should inspect the operands and allow those that cannot alias
3936 // with the value.
3937 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3938 return true;
3939
3940 if (ScopeFn) {
3941 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3942 if (CB->isArgOperand(&U)) {
3943
3944 unsigned ArgNo = CB->getArgOperandNo(&U);
3945
3946 bool IsKnownNoCapture;
3948 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3949 DepClassTy::OPTIONAL, IsKnownNoCapture))
3950 return true;
3951 }
3952 }
3953
3955 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3956 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3957 return true;
3958 }
3959
3960 // TODO: We should track the capturing uses in AANoCapture but the problem
3961 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3962 // a value in the module slice.
3963 // TODO(captures): Make this more precise.
3964 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3965 if (capturesNothing(CI))
3966 return true;
3967 if (CI.isPassthrough()) {
3968 Follow = true;
3969 return true;
3970 }
3971 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3972 return false;
3973 };
3974
3975 bool IsKnownNoCapture;
3976 const AANoCapture *NoCaptureAA = nullptr;
3977 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3978 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3979 if (!IsAssumedNoCapture &&
3980 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3981 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3982 LLVM_DEBUG(
3983 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3984 << " cannot be noalias as it is potentially captured\n");
3985 return false;
3986 }
3987 }
3988 if (NoCaptureAA)
3989 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3990
3991 // Check there is no other pointer argument which could alias with the
3992 // value passed at this call site.
3993 // TODO: AbstractCallSite
3994 const auto &CB = cast<CallBase>(getAnchorValue());
3995 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3996 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3997 return false;
3998
3999 return true;
4000 }
4001
4002 /// See AbstractAttribute::updateImpl(...).
4003 ChangeStatus updateImpl(Attributor &A) override {
4004 // If the argument is readnone we are done as there are no accesses via the
4005 // argument.
4006 auto *MemBehaviorAA =
4007 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4008 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4009 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4010 return ChangeStatus::UNCHANGED;
4011 }
4012
4013 bool IsKnownNoAlias;
4014 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4016 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4017 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4018 << " is not no-alias at the definition\n");
4019 return indicatePessimisticFixpoint();
4020 }
4021
4022 AAResults *AAR = nullptr;
4023 if (MemBehaviorAA &&
4024 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4025 LLVM_DEBUG(
4026 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4027 return ChangeStatus::UNCHANGED;
4028 }
4029
4030 return indicatePessimisticFixpoint();
4031 }
4032
4033 /// See AbstractAttribute::trackStatistics()
4034 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4035};
4036
4037/// NoAlias attribute for function return value.
4038struct AANoAliasReturned final : AANoAliasImpl {
4039 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4040 : AANoAliasImpl(IRP, A) {}
4041
4042 /// See AbstractAttribute::updateImpl(...).
4043 ChangeStatus updateImpl(Attributor &A) override {
4044
4045 auto CheckReturnValue = [&](Value &RV) -> bool {
4046 if (Constant *C = dyn_cast<Constant>(&RV))
4047 if (C->isNullValue() || isa<UndefValue>(C))
4048 return true;
4049
4050 /// For now, we can only deduce noalias if we have call sites.
4051 /// FIXME: add more support.
4052 if (!isa<CallBase>(&RV))
4053 return false;
4054
4055 const IRPosition &RVPos = IRPosition::value(RV);
4056 bool IsKnownNoAlias;
4058 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4059 return false;
4060
4061 bool IsKnownNoCapture;
4062 const AANoCapture *NoCaptureAA = nullptr;
4063 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4064 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4065 &NoCaptureAA);
4066 return IsAssumedNoCapture ||
4067 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4068 };
4069
4070 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4071 return indicatePessimisticFixpoint();
4072
4073 return ChangeStatus::UNCHANGED;
4074 }
4075
4076 /// See AbstractAttribute::trackStatistics()
4077 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4078};
4079
4080/// NoAlias attribute deduction for a call site return value.
4081struct AANoAliasCallSiteReturned final
4082 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4083 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4084 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4085
4086 /// See AbstractAttribute::trackStatistics()
4087 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4088};
4089} // namespace
4090
4091/// -------------------AAIsDead Function Attribute-----------------------
4092
4093namespace {
4094struct AAIsDeadValueImpl : public AAIsDead {
4095 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4096
4097 /// See AAIsDead::isAssumedDead().
4098 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4099
4100 /// See AAIsDead::isKnownDead().
4101 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4102
4103 /// See AAIsDead::isAssumedDead(BasicBlock *).
4104 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4105
4106 /// See AAIsDead::isKnownDead(BasicBlock *).
4107 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4108
4109 /// See AAIsDead::isAssumedDead(Instruction *I).
4110 bool isAssumedDead(const Instruction *I) const override {
4111 return I == getCtxI() && isAssumedDead();
4112 }
4113
4114 /// See AAIsDead::isKnownDead(Instruction *I).
4115 bool isKnownDead(const Instruction *I) const override {
4116 return isAssumedDead(I) && isKnownDead();
4117 }
4118
4119 /// See AbstractAttribute::getAsStr().
4120 const std::string getAsStr(Attributor *A) const override {
4121 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4122 }
4123
4124 /// Check if all uses are assumed dead.
4125 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4126 // Callers might not check the type, void has no uses.
4127 if (V.getType()->isVoidTy() || V.use_empty())
4128 return true;
4129
4130 // If we replace a value with a constant there are no uses left afterwards.
4131 if (!isa<Constant>(V)) {
4132 if (auto *I = dyn_cast<Instruction>(&V))
4133 if (!A.isRunOn(*I->getFunction()))
4134 return false;
4135 bool UsedAssumedInformation = false;
4136 std::optional<Constant *> C =
4137 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4138 if (!C || *C)
4139 return true;
4140 }
4141
4142 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4143 // Explicitly set the dependence class to required because we want a long
4144 // chain of N dependent instructions to be considered live as soon as one is
4145 // without going through N update cycles. This is not required for
4146 // correctness.
4147 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4148 DepClassTy::REQUIRED,
4149 /* IgnoreDroppableUses */ false);
4150 }
4151
4152 /// Determine if \p I is assumed to be side-effect free.
4153 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4155 return true;
4156
4157 auto *CB = dyn_cast<CallBase>(I);
4158 if (!CB || isa<IntrinsicInst>(CB))
4159 return false;
4160
4161 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4162
4163 bool IsKnownNoUnwind;
4165 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4166 return false;
4167
4168 bool IsKnown;
4169 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4170 }
4171};
4172
4173struct AAIsDeadFloating : public AAIsDeadValueImpl {
4174 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4175 : AAIsDeadValueImpl(IRP, A) {}
4176
4177 /// See AbstractAttribute::initialize(...).
4178 void initialize(Attributor &A) override {
4179 AAIsDeadValueImpl::initialize(A);
4180
4181 if (isa<UndefValue>(getAssociatedValue())) {
4182 indicatePessimisticFixpoint();
4183 return;
4184 }
4185
4186 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4187 if (!isAssumedSideEffectFree(A, I)) {
4189 indicatePessimisticFixpoint();
4190 else
4191 removeAssumedBits(HAS_NO_EFFECT);
4192 }
4193 }
4194
4195 bool isDeadFence(Attributor &A, FenceInst &FI) {
4196 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4197 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4198 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4199 return false;
4200 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4201 return true;
4202 }
4203
4204 bool isDeadStore(Attributor &A, StoreInst &SI,
4205 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4206 // Lang ref now states volatile store is not UB/dead, let's skip them.
4207 if (SI.isVolatile())
4208 return false;
4209
4210 // If we are collecting assumes to be deleted we are in the manifest stage.
4211 // It's problematic to collect the potential copies again now so we use the
4212 // cached ones.
4213 bool UsedAssumedInformation = false;
4214 if (!AssumeOnlyInst) {
4215 PotentialCopies.clear();
4216 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4217 UsedAssumedInformation)) {
4218 LLVM_DEBUG(
4219 dbgs()
4220 << "[AAIsDead] Could not determine potential copies of store!\n");
4221 return false;
4222 }
4223 }
4224 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4225 << " potential copies.\n");
4226
4227 InformationCache &InfoCache = A.getInfoCache();
4228 return llvm::all_of(PotentialCopies, [&](Value *V) {
4229 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4230 UsedAssumedInformation))
4231 return true;
4232 if (auto *LI = dyn_cast<LoadInst>(V)) {
4233 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4234 auto &UserI = cast<Instruction>(*U.getUser());
4235 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4236 if (AssumeOnlyInst)
4237 AssumeOnlyInst->insert(&UserI);
4238 return true;
4239 }
4240 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4241 })) {
4242 return true;
4243 }
4244 }
4245 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4246 << " is assumed live!\n");
4247 return false;
4248 });
4249 }
4250
4251 /// See AbstractAttribute::getAsStr().
4252 const std::string getAsStr(Attributor *A) const override {
4253 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4255 if (isValidState())
4256 return "assumed-dead-store";
4258 if (isValidState())
4259 return "assumed-dead-fence";
4260 return AAIsDeadValueImpl::getAsStr(A);
4261 }
4262
4263 /// See AbstractAttribute::updateImpl(...).
4264 ChangeStatus updateImpl(Attributor &A) override {
4265 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4266 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4267 if (!isDeadStore(A, *SI))
4268 return indicatePessimisticFixpoint();
4269 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4270 if (!isDeadFence(A, *FI))
4271 return indicatePessimisticFixpoint();
4272 } else {
4273 if (!isAssumedSideEffectFree(A, I))
4274 return indicatePessimisticFixpoint();
4275 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4276 return indicatePessimisticFixpoint();
4277 }
4279 }
4280
4281 bool isRemovableStore() const override {
4282 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4283 }
4284
4285 /// See AbstractAttribute::manifest(...).
4286 ChangeStatus manifest(Attributor &A) override {
4287 Value &V = getAssociatedValue();
4288 if (auto *I = dyn_cast<Instruction>(&V)) {
4289 // If we get here we basically know the users are all dead. We check if
4290 // isAssumedSideEffectFree returns true here again because it might not be
4291 // the case and only the users are dead but the instruction (=call) is
4292 // still needed.
4293 if (auto *SI = dyn_cast<StoreInst>(I)) {
4294 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4295 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4296 (void)IsDead;
4297 assert(IsDead && "Store was assumed to be dead!");
4298 A.deleteAfterManifest(*I);
4299 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4300 Instruction *AOI = AssumeOnlyInst[i];
4301 for (auto *Usr : AOI->users())
4302 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4303 A.deleteAfterManifest(*AOI);
4304 }
4305 return ChangeStatus::CHANGED;
4306 }
4307 if (auto *FI = dyn_cast<FenceInst>(I)) {
4308 assert(isDeadFence(A, *FI));
4309 A.deleteAfterManifest(*FI);
4310 return ChangeStatus::CHANGED;
4311 }
4312 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4313 A.deleteAfterManifest(*I);
4314 return ChangeStatus::CHANGED;
4315 }
4316 }
4318 }
4319
4320 /// See AbstractAttribute::trackStatistics()
4321 void trackStatistics() const override {
4323 }
4324
4325private:
4326 // The potential copies of a dead store, used for deletion during manifest.
4327 SmallSetVector<Value *, 4> PotentialCopies;
4328};
4329
4330struct AAIsDeadArgument : public AAIsDeadFloating {
4331 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4332 : AAIsDeadFloating(IRP, A) {}
4333
4334 /// See AbstractAttribute::manifest(...).
4335 ChangeStatus manifest(Attributor &A) override {
4336 Argument &Arg = *getAssociatedArgument();
4337 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4338 if (A.registerFunctionSignatureRewrite(
4339 Arg, /* ReplacementTypes */ {},
4342 return ChangeStatus::CHANGED;
4343 }
4344 return ChangeStatus::UNCHANGED;
4345 }
4346
4347 /// See AbstractAttribute::trackStatistics()
4348 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4349};
4350
4351struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4352 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4353 : AAIsDeadValueImpl(IRP, A) {}
4354
4355 /// See AbstractAttribute::initialize(...).
4356 void initialize(Attributor &A) override {
4357 AAIsDeadValueImpl::initialize(A);
4358 if (isa<UndefValue>(getAssociatedValue()))
4359 indicatePessimisticFixpoint();
4360 }
4361
4362 /// See AbstractAttribute::updateImpl(...).
4363 ChangeStatus updateImpl(Attributor &A) override {
4364 // TODO: Once we have call site specific value information we can provide
4365 // call site specific liveness information and then it makes
4366 // sense to specialize attributes for call sites arguments instead of
4367 // redirecting requests to the callee argument.
4368 Argument *Arg = getAssociatedArgument();
4369 if (!Arg)
4370 return indicatePessimisticFixpoint();
4371 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4372 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4373 if (!ArgAA)
4374 return indicatePessimisticFixpoint();
4375 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4376 }
4377
4378 /// See AbstractAttribute::manifest(...).
4379 ChangeStatus manifest(Attributor &A) override {
4380 CallBase &CB = cast<CallBase>(getAnchorValue());
4381 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4382 assert(!isa<UndefValue>(U.get()) &&
4383 "Expected undef values to be filtered out!");
4384 UndefValue &UV = *UndefValue::get(U->getType());
4385 if (A.changeUseAfterManifest(U, UV))
4386 return ChangeStatus::CHANGED;
4387 return ChangeStatus::UNCHANGED;
4388 }
4389
4390 /// See AbstractAttribute::trackStatistics()
4391 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4392};
4393
4394struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4395 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4396 : AAIsDeadFloating(IRP, A) {}
4397
4398 /// See AAIsDead::isAssumedDead().
4399 bool isAssumedDead() const override {
4400 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4401 }
4402
4403 /// See AbstractAttribute::initialize(...).
4404 void initialize(Attributor &A) override {
4405 AAIsDeadFloating::initialize(A);
4406 if (isa<UndefValue>(getAssociatedValue())) {
4407 indicatePessimisticFixpoint();
4408 return;
4409 }
4410
4411 // We track this separately as a secondary state.
4412 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4413 }
4414
4415 /// See AbstractAttribute::updateImpl(...).
4416 ChangeStatus updateImpl(Attributor &A) override {
4417 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4418 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4419 IsAssumedSideEffectFree = false;
4420 Changed = ChangeStatus::CHANGED;
4421 }
4422 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4423 return indicatePessimisticFixpoint();
4424 return Changed;
4425 }
4426
4427 /// See AbstractAttribute::trackStatistics()
4428 void trackStatistics() const override {
4429 if (IsAssumedSideEffectFree)
4431 else
4432 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4433 }
4434
4435 /// See AbstractAttribute::getAsStr().
4436 const std::string getAsStr(Attributor *A) const override {
4437 return isAssumedDead()
4438 ? "assumed-dead"
4439 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4440 }
4441
4442private:
4443 bool IsAssumedSideEffectFree = true;
4444};
4445
4446struct AAIsDeadReturned : public AAIsDeadValueImpl {
4447 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4448 : AAIsDeadValueImpl(IRP, A) {}
4449
4450 /// See AbstractAttribute::updateImpl(...).
4451 ChangeStatus updateImpl(Attributor &A) override {
4452
4453 bool UsedAssumedInformation = false;
4454 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4455 {Instruction::Ret}, UsedAssumedInformation);
4456
4457 auto PredForCallSite = [&](AbstractCallSite ACS) {
4458 if (ACS.isCallbackCall() || !ACS.getInstruction())
4459 return false;
4460 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4461 };
4462
4463 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4464 UsedAssumedInformation))
4465 return indicatePessimisticFixpoint();
4466
4467 return ChangeStatus::UNCHANGED;
4468 }
4469
4470 /// See AbstractAttribute::manifest(...).
4471 ChangeStatus manifest(Attributor &A) override {
4472 // TODO: Rewrite the signature to return void?
4473 bool AnyChange = false;
4474 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4475 auto RetInstPred = [&](Instruction &I) {
4476 ReturnInst &RI = cast<ReturnInst>(I);
4478 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4479 return true;
4480 };
4481 bool UsedAssumedInformation = false;
4482 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4483 UsedAssumedInformation);
4484 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4485 }
4486
4487 /// See AbstractAttribute::trackStatistics()
4488 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4489};
4490
4491struct AAIsDeadFunction : public AAIsDead {
4492 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4493
4494 /// See AbstractAttribute::initialize(...).
4495 void initialize(Attributor &A) override {
4496 Function *F = getAnchorScope();
4497 assert(F && "Did expect an anchor function");
4498 if (!isAssumedDeadInternalFunction(A)) {
4499 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4500 assumeLive(A, F->getEntryBlock());
4501 }
4502 }
4503
4504 bool isAssumedDeadInternalFunction(Attributor &A) {
4505 if (!getAnchorScope()->hasLocalLinkage())
4506 return false;
4507 bool UsedAssumedInformation = false;
4508 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4509 true, UsedAssumedInformation);
4510 }
4511
4512 /// See AbstractAttribute::getAsStr().
4513 const std::string getAsStr(Attributor *A) const override {
4514 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4515 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4516 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4517 std::to_string(KnownDeadEnds.size()) + "]";
4518 }
4519
4520 /// See AbstractAttribute::manifest(...).
4521 ChangeStatus manifest(Attributor &A) override {
4522 assert(getState().isValidState() &&
4523 "Attempted to manifest an invalid state!");
4524
4525 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4526 Function &F = *getAnchorScope();
4527
4528 if (AssumedLiveBlocks.empty()) {
4529 A.deleteAfterManifest(F);
4530 return ChangeStatus::CHANGED;
4531 }
4532
4533 // Flag to determine if we can change an invoke to a call assuming the
4534 // callee is nounwind. This is not possible if the personality of the
4535 // function allows to catch asynchronous exceptions.
4536 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4537
4538 KnownDeadEnds.set_union(ToBeExploredFrom);
4539 for (const Instruction *DeadEndI : KnownDeadEnds) {
4540 auto *CB = dyn_cast<CallBase>(DeadEndI);
4541 if (!CB)
4542 continue;
4543 bool IsKnownNoReturn;
4545 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4546 IsKnownNoReturn);
4547 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4548 continue;
4549
4550 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4551 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4552 else
4553 A.changeToUnreachableAfterManifest(
4554 const_cast<Instruction *>(DeadEndI->getNextNode()));
4555 HasChanged = ChangeStatus::CHANGED;
4556 }
4557
4558 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4559 for (BasicBlock &BB : F)
4560 if (!AssumedLiveBlocks.count(&BB)) {
4561 A.deleteAfterManifest(BB);
4562 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4563 HasChanged = ChangeStatus::CHANGED;
4564 }
4565
4566 return HasChanged;
4567 }
4568
4569 /// See AbstractAttribute::updateImpl(...).
4570 ChangeStatus updateImpl(Attributor &A) override;
4571
4572 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4573 assert(From->getParent() == getAnchorScope() &&
4574 To->getParent() == getAnchorScope() &&
4575 "Used AAIsDead of the wrong function");
4576 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4577 }
4578
4579 /// See AbstractAttribute::trackStatistics()
4580 void trackStatistics() const override {}
4581
4582 /// Returns true if the function is assumed dead.
4583 bool isAssumedDead() const override { return false; }
4584
4585 /// See AAIsDead::isKnownDead().
4586 bool isKnownDead() const override { return false; }
4587
4588 /// See AAIsDead::isAssumedDead(BasicBlock *).
4589 bool isAssumedDead(const BasicBlock *BB) const override {
4590 assert(BB->getParent() == getAnchorScope() &&
4591 "BB must be in the same anchor scope function.");
4592
4593 if (!getAssumed())
4594 return false;
4595 return !AssumedLiveBlocks.count(BB);
4596 }
4597
4598 /// See AAIsDead::isKnownDead(BasicBlock *).
4599 bool isKnownDead(const BasicBlock *BB) const override {
4600 return getKnown() && isAssumedDead(BB);
4601 }
4602
4603 /// See AAIsDead::isAssumed(Instruction *I).
4604 bool isAssumedDead(const Instruction *I) const override {
4605 assert(I->getParent()->getParent() == getAnchorScope() &&
4606 "Instruction must be in the same anchor scope function.");
4607
4608 if (!getAssumed())
4609 return false;
4610
4611 // If it is not in AssumedLiveBlocks then it for sure dead.
4612 // Otherwise, it can still be after noreturn call in a live block.
4613 if (!AssumedLiveBlocks.count(I->getParent()))
4614 return true;
4615
4616 // If it is not after a liveness barrier it is live.
4617 const Instruction *PrevI = I->getPrevNode();
4618 while (PrevI) {
4619 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4620 return true;
4621 PrevI = PrevI->getPrevNode();
4622 }
4623 return false;
4624 }
4625
4626 /// See AAIsDead::isKnownDead(Instruction *I).
4627 bool isKnownDead(const Instruction *I) const override {
4628 return getKnown() && isAssumedDead(I);
4629 }
4630
4631 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4632 /// that internal function called from \p BB should now be looked at.
4633 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4634 if (!AssumedLiveBlocks.insert(&BB).second)
4635 return false;
4636
4637 // We assume that all of BB is (probably) live now and if there are calls to
4638 // internal functions we will assume that those are now live as well. This
4639 // is a performance optimization for blocks with calls to a lot of internal
4640 // functions. It can however cause dead functions to be treated as live.
4641 for (const Instruction &I : BB)
4642 if (const auto *CB = dyn_cast<CallBase>(&I))
4644 if (F->hasLocalLinkage())
4645 A.markLiveInternalFunction(*F);
4646 return true;
4647 }
4648
4649 /// Collection of instructions that need to be explored again, e.g., we
4650 /// did assume they do not transfer control to (one of their) successors.
4651 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4652
4653 /// Collection of instructions that are known to not transfer control.
4654 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4655
4656 /// Collection of all assumed live edges
4657 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4658
4659 /// Collection of all assumed live BasicBlocks.
4660 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4661};
4662
4663static bool
4664identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4665 AbstractAttribute &AA,
4666 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4667 const IRPosition &IPos = IRPosition::callsite_function(CB);
4668
4669 bool IsKnownNoReturn;
4671 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4672 return !IsKnownNoReturn;
4673 if (CB.isTerminator())
4674 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4675 else
4676 AliveSuccessors.push_back(CB.getNextNode());
4677 return false;
4678}
4679
4680static bool
4681identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4682 AbstractAttribute &AA,
4683 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4684 bool UsedAssumedInformation =
4685 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4686
4687 // First, determine if we can change an invoke to a call assuming the
4688 // callee is nounwind. This is not possible if the personality of the
4689 // function allows to catch asynchronous exceptions.
4690 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4691 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4692 } else {
4693 const IRPosition &IPos = IRPosition::callsite_function(II);
4694
4695 bool IsKnownNoUnwind;
4697 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4698 UsedAssumedInformation |= !IsKnownNoUnwind;
4699 } else {
4700 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4701 }
4702 }
4703 return UsedAssumedInformation;
4704}
4705
4706static bool
4707identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4708 AbstractAttribute &AA,
4709 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4710 bool UsedAssumedInformation = false;
4711 if (BI.getNumSuccessors() == 1) {
4712 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4713 } else {
4714 std::optional<Constant *> C =
4715 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4716 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4717 // No value yet, assume both edges are dead.
4718 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4719 const BasicBlock *SuccBB =
4720 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4721 AliveSuccessors.push_back(&SuccBB->front());
4722 } else {
4723 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4724 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4725 UsedAssumedInformation = false;
4726 }
4727 }
4728 return UsedAssumedInformation;
4729}
4730
4731static bool
4732identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4733 AbstractAttribute &AA,
4734 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4735 bool UsedAssumedInformation = false;
4737 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4738 Values, AA::AnyScope,
4739 UsedAssumedInformation)) {
4740 // Something went wrong, assume all successors are live.
4741 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4742 AliveSuccessors.push_back(&SuccBB->front());
4743 return false;
4744 }
4745
4746 if (Values.empty() ||
4747 (Values.size() == 1 &&
4748 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4749 // No valid value yet, assume all edges are dead.
4750 return UsedAssumedInformation;
4751 }
4752
4753 Type &Ty = *SI.getCondition()->getType();
4754 SmallPtrSet<ConstantInt *, 8> Constants;
4755 auto CheckForConstantInt = [&](Value *V) {
4756 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4757 Constants.insert(CI);
4758 return true;
4759 }
4760 return false;
4761 };
4762
4763 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4764 return CheckForConstantInt(VAC.getValue());
4765 })) {
4766 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4767 AliveSuccessors.push_back(&SuccBB->front());
4768 return UsedAssumedInformation;
4769 }
4770
4771 unsigned MatchedCases = 0;
4772 for (const auto &CaseIt : SI.cases()) {
4773 if (Constants.count(CaseIt.getCaseValue())) {
4774 ++MatchedCases;
4775 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4776 }
4777 }
4778
4779 // If all potential values have been matched, we will not visit the default
4780 // case.
4781 if (MatchedCases < Constants.size())
4782 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4783 return UsedAssumedInformation;
4784}
4785
4786ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4788
4789 if (AssumedLiveBlocks.empty()) {
4790 if (isAssumedDeadInternalFunction(A))
4792
4793 Function *F = getAnchorScope();
4794 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4795 assumeLive(A, F->getEntryBlock());
4796 Change = ChangeStatus::CHANGED;
4797 }
4798
4799 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4800 << getAnchorScope()->size() << "] BBs and "
4801 << ToBeExploredFrom.size() << " exploration points and "
4802 << KnownDeadEnds.size() << " known dead ends\n");
4803
4804 // Copy and clear the list of instructions we need to explore from. It is
4805 // refilled with instructions the next update has to look at.
4806 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4807 ToBeExploredFrom.end());
4808 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4809
4811 while (!Worklist.empty()) {
4812 const Instruction *I = Worklist.pop_back_val();
4813 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4814
4815 // Fast forward for uninteresting instructions. We could look for UB here
4816 // though.
4817 while (!I->isTerminator() && !isa<CallBase>(I))
4818 I = I->getNextNode();
4819
4820 AliveSuccessors.clear();
4821
4822 bool UsedAssumedInformation = false;
4823 switch (I->getOpcode()) {
4824 // TODO: look for (assumed) UB to backwards propagate "deadness".
4825 default:
4826 assert(I->isTerminator() &&
4827 "Expected non-terminators to be handled already!");
4828 for (const BasicBlock *SuccBB : successors(I->getParent()))
4829 AliveSuccessors.push_back(&SuccBB->front());
4830 break;
4831 case Instruction::Call:
4832 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4833 *this, AliveSuccessors);
4834 break;
4835 case Instruction::Invoke:
4836 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4837 *this, AliveSuccessors);
4838 break;
4839 case Instruction::Br:
4840 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4841 *this, AliveSuccessors);
4842 break;
4843 case Instruction::Switch:
4844 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4845 *this, AliveSuccessors);
4846 break;
4847 }
4848
4849 if (UsedAssumedInformation) {
4850 NewToBeExploredFrom.insert(I);
4851 } else if (AliveSuccessors.empty() ||
4852 (I->isTerminator() &&
4853 AliveSuccessors.size() < I->getNumSuccessors())) {
4854 if (KnownDeadEnds.insert(I))
4855 Change = ChangeStatus::CHANGED;
4856 }
4857
4858 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4859 << AliveSuccessors.size() << " UsedAssumedInformation: "
4860 << UsedAssumedInformation << "\n");
4861
4862 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4863 if (!I->isTerminator()) {
4864 assert(AliveSuccessors.size() == 1 &&
4865 "Non-terminator expected to have a single successor!");
4866 Worklist.push_back(AliveSuccessor);
4867 } else {
4868 // record the assumed live edge
4869 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4870 if (AssumedLiveEdges.insert(Edge).second)
4871 Change = ChangeStatus::CHANGED;
4872 if (assumeLive(A, *AliveSuccessor->getParent()))
4873 Worklist.push_back(AliveSuccessor);
4874 }
4875 }
4876 }
4877
4878 // Check if the content of ToBeExploredFrom changed, ignore the order.
4879 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4880 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4881 return !ToBeExploredFrom.count(I);
4882 })) {
4883 Change = ChangeStatus::CHANGED;
4884 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4885 }
4886
4887 // If we know everything is live there is no need to query for liveness.
4888 // Instead, indicating a pessimistic fixpoint will cause the state to be
4889 // "invalid" and all queries to be answered conservatively without lookups.
4890 // To be in this state we have to (1) finished the exploration and (3) not
4891 // discovered any non-trivial dead end and (2) not ruled unreachable code
4892 // dead.
4893 if (ToBeExploredFrom.empty() &&
4894 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4895 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4896 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4897 }))
4898 return indicatePessimisticFixpoint();
4899 return Change;
4900}
4901
4902/// Liveness information for a call sites.
4903struct AAIsDeadCallSite final : AAIsDeadFunction {
4904 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4905 : AAIsDeadFunction(IRP, A) {}
4906
4907 /// See AbstractAttribute::initialize(...).
4908 void initialize(Attributor &A) override {
4909 // TODO: Once we have call site specific value information we can provide
4910 // call site specific liveness information and then it makes
4911 // sense to specialize attributes for call sites instead of
4912 // redirecting requests to the callee.
4913 llvm_unreachable("Abstract attributes for liveness are not "
4914 "supported for call sites yet!");
4915 }
4916
4917 /// See AbstractAttribute::updateImpl(...).
4918 ChangeStatus updateImpl(Attributor &A) override {
4919 return indicatePessimisticFixpoint();
4920 }
4921
4922 /// See AbstractAttribute::trackStatistics()
4923 void trackStatistics() const override {}
4924};
4925} // namespace
4926
4927/// -------------------- Dereferenceable Argument Attribute --------------------
4928
4929namespace {
4930struct AADereferenceableImpl : AADereferenceable {
4931 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4932 : AADereferenceable(IRP, A) {}
4933 using StateType = DerefState;
4934
4935 /// See AbstractAttribute::initialize(...).
4936 void initialize(Attributor &A) override {
4937 Value &V = *getAssociatedValue().stripPointerCasts();
4939 A.getAttrs(getIRPosition(),
4940 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4941 Attrs, /* IgnoreSubsumingPositions */ false);
4942 for (const Attribute &Attr : Attrs)
4943 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4944
4945 // Ensure we initialize the non-null AA (if necessary).
4946 bool IsKnownNonNull;
4948 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4949
4950 bool CanBeNull, CanBeFreed;
4951 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4952 A.getDataLayout(), CanBeNull, CanBeFreed));
4953
4954 if (Instruction *CtxI = getCtxI())
4955 followUsesInMBEC(*this, A, getState(), *CtxI);
4956 }
4957
4958 /// See AbstractAttribute::getState()
4959 /// {
4960 StateType &getState() override { return *this; }
4961 const StateType &getState() const override { return *this; }
4962 /// }
4963
4964 /// Helper function for collecting accessed bytes in must-be-executed-context
4965 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4966 DerefState &State) {
4967 const Value *UseV = U->get();
4968 if (!UseV->getType()->isPointerTy())
4969 return;
4970
4971 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4972 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4973 return;
4974
4975 int64_t Offset;
4977 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4978 if (Base && Base == &getAssociatedValue())
4979 State.addAccessedBytes(Offset, Loc->Size.getValue());
4980 }
4981
4982 /// See followUsesInMBEC
4983 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4984 AADereferenceable::StateType &State) {
4985 bool IsNonNull = false;
4986 bool TrackUse = false;
4987 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4988 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4989 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4990 << " for instruction " << *I << "\n");
4991
4992 addAccessedBytesForUse(A, U, I, State);
4993 State.takeKnownDerefBytesMaximum(DerefBytes);
4994 return TrackUse;
4995 }
4996
4997 /// See AbstractAttribute::manifest(...).
4998 ChangeStatus manifest(Attributor &A) override {
4999 ChangeStatus Change = AADereferenceable::manifest(A);
5000 bool IsKnownNonNull;
5001 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5002 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5003 if (IsAssumedNonNull &&
5004 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5005 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5006 return ChangeStatus::CHANGED;
5007 }
5008 return Change;
5009 }
5010
5011 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5012 SmallVectorImpl<Attribute> &Attrs) const override {
5013 // TODO: Add *_globally support
5014 bool IsKnownNonNull;
5015 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5016 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5017 if (IsAssumedNonNull)
5018 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5019 Ctx, getAssumedDereferenceableBytes()));
5020 else
5021 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5022 Ctx, getAssumedDereferenceableBytes()));
5023 }
5024
5025 /// See AbstractAttribute::getAsStr().
5026 const std::string getAsStr(Attributor *A) const override {
5027 if (!getAssumedDereferenceableBytes())
5028 return "unknown-dereferenceable";
5029 bool IsKnownNonNull;
5030 bool IsAssumedNonNull = false;
5031 if (A)
5033 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5034 return std::string("dereferenceable") +
5035 (IsAssumedNonNull ? "" : "_or_null") +
5036 (isAssumedGlobal() ? "_globally" : "") + "<" +
5037 std::to_string(getKnownDereferenceableBytes()) + "-" +
5038 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5039 (!A ? " [non-null is unknown]" : "");
5040 }
5041};
5042
5043/// Dereferenceable attribute for a floating value.
5044struct AADereferenceableFloating : AADereferenceableImpl {
5045 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5046 : AADereferenceableImpl(IRP, A) {}
5047
5048 /// See AbstractAttribute::updateImpl(...).
5049 ChangeStatus updateImpl(Attributor &A) override {
5050 bool Stripped;
5051 bool UsedAssumedInformation = false;
5053 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5054 AA::AnyScope, UsedAssumedInformation)) {
5055 Values.push_back({getAssociatedValue(), getCtxI()});
5056 Stripped = false;
5057 } else {
5058 Stripped = Values.size() != 1 ||
5059 Values.front().getValue() != &getAssociatedValue();
5060 }
5061
5062 const DataLayout &DL = A.getDataLayout();
5063 DerefState T;
5064
5065 auto VisitValueCB = [&](const Value &V) -> bool {
5066 unsigned IdxWidth =
5067 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5068 APInt Offset(IdxWidth, 0);
5070 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5071 /* AllowNonInbounds */ true);
5072
5073 const auto *AA = A.getAAFor<AADereferenceable>(
5074 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5075 int64_t DerefBytes = 0;
5076 if (!AA || (!Stripped && this == AA)) {
5077 // Use IR information if we did not strip anything.
5078 // TODO: track globally.
5079 bool CanBeNull, CanBeFreed;
5080 DerefBytes =
5081 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5082 T.GlobalState.indicatePessimisticFixpoint();
5083 } else {
5084 const DerefState &DS = AA->getState();
5085 DerefBytes = DS.DerefBytesState.getAssumed();
5086 T.GlobalState &= DS.GlobalState;
5087 }
5088
5089 // For now we do not try to "increase" dereferenceability due to negative
5090 // indices as we first have to come up with code to deal with loops and
5091 // for overflows of the dereferenceable bytes.
5092 int64_t OffsetSExt = Offset.getSExtValue();
5093 if (OffsetSExt < 0)
5094 OffsetSExt = 0;
5095
5096 T.takeAssumedDerefBytesMinimum(
5097 std::max(int64_t(0), DerefBytes - OffsetSExt));
5098
5099 if (this == AA) {
5100 if (!Stripped) {
5101 // If nothing was stripped IR information is all we got.
5102 T.takeKnownDerefBytesMaximum(
5103 std::max(int64_t(0), DerefBytes - OffsetSExt));
5104 T.indicatePessimisticFixpoint();
5105 } else if (OffsetSExt > 0) {
5106 // If something was stripped but there is circular reasoning we look
5107 // for the offset. If it is positive we basically decrease the
5108 // dereferenceable bytes in a circular loop now, which will simply
5109 // drive them down to the known value in a very slow way which we
5110 // can accelerate.
5111 T.indicatePessimisticFixpoint();
5112 }
5113 }
5114
5115 return T.isValidState();
5116 };
5117
5118 for (const auto &VAC : Values)
5119 if (!VisitValueCB(*VAC.getValue()))
5120 return indicatePessimisticFixpoint();
5121
5122 return clampStateAndIndicateChange(getState(), T);
5123 }
5124
5125 /// See AbstractAttribute::trackStatistics()
5126 void trackStatistics() const override {
5127 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5128 }
5129};
5130
5131/// Dereferenceable attribute for a return value.
5132struct AADereferenceableReturned final
5133 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5134 using Base =
5135 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5136 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5137 : Base(IRP, A) {}
5138
5139 /// See AbstractAttribute::trackStatistics()
5140 void trackStatistics() const override {
5141 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5142 }
5143};
5144
5145/// Dereferenceable attribute for an argument
5146struct AADereferenceableArgument final
5147 : AAArgumentFromCallSiteArguments<AADereferenceable,
5148 AADereferenceableImpl> {
5149 using Base =
5150 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5151 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5152 : Base(IRP, A) {}
5153
5154 /// See AbstractAttribute::trackStatistics()
5155 void trackStatistics() const override {
5156 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5157 }
5158};
5159
5160/// Dereferenceable attribute for a call site argument.
5161struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5162 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5163 : AADereferenceableFloating(IRP, A) {}
5164
5165 /// See AbstractAttribute::trackStatistics()
5166 void trackStatistics() const override {
5167 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5168 }
5169};
5170
5171/// Dereferenceable attribute deduction for a call site return value.
5172struct AADereferenceableCallSiteReturned final
5173 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5174 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5175 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5176 : Base(IRP, A) {}
5177
5178 /// See AbstractAttribute::trackStatistics()
5179 void trackStatistics() const override {
5180 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5181 }
5182};
5183} // namespace
5184
5185// ------------------------ Align Argument Attribute ------------------------
5186
5187namespace {
5188
5189static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5190 Value &AssociatedValue, const Use *U,
5191 const Instruction *I, bool &TrackUse) {
5192 // We need to follow common pointer manipulation uses to the accesses they
5193 // feed into.
5194 if (isa<CastInst>(I)) {
5195 // Follow all but ptr2int casts.
5196 TrackUse = !isa<PtrToIntInst>(I);
5197 return 0;
5198 }
5199 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5200 if (GEP->hasAllConstantIndices())
5201 TrackUse = true;
5202 return 0;
5203 }
5204 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5205 switch (II->getIntrinsicID()) {
5206 case Intrinsic::ptrmask: {
5207 // Is it appropriate to pull attribute in initialization?
5208 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5209 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5210 const auto *AlignAA = A.getAAFor<AAAlign>(
5211 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5212 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5213 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5215 Align ConstAlign(UINT64_C(1) << ShiftValue);
5216 if (ConstAlign >= AlignAA->getKnownAlign())
5217 return Align(1).value();
5218 }
5219 if (AlignAA)
5220 return AlignAA->getKnownAlign().value();
5221 break;
5222 }
5223 default:
5224 break;
5225 }
5226
5227 MaybeAlign MA;
5228 if (const auto *CB = dyn_cast<CallBase>(I)) {
5229 if (CB->isBundleOperand(U) || CB->isCallee(U))
5230 return 0;
5231
5232 unsigned ArgNo = CB->getArgOperandNo(U);
5233 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5234 // As long as we only use known information there is no need to track
5235 // dependences here.
5236 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5237 if (AlignAA)
5238 MA = MaybeAlign(AlignAA->getKnownAlign());
5239 }
5240
5241 const DataLayout &DL = A.getDataLayout();
5242 const Value *UseV = U->get();
5243 if (auto *SI = dyn_cast<StoreInst>(I)) {
5244 if (SI->getPointerOperand() == UseV)
5245 MA = SI->getAlign();
5246 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5247 if (LI->getPointerOperand() == UseV)
5248 MA = LI->getAlign();
5249 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5250 if (AI->getPointerOperand() == UseV)
5251 MA = AI->getAlign();
5252 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5253 if (AI->getPointerOperand() == UseV)
5254 MA = AI->getAlign();
5255 }
5256
5257 if (!MA || *MA <= QueryingAA.getKnownAlign())
5258 return 0;
5259
5260 unsigned Alignment = MA->value();
5261 int64_t Offset;
5262
5263 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5264 if (Base == &AssociatedValue) {
5265 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5266 // So we can say that the maximum power of two which is a divisor of
5267 // gcd(Offset, Alignment) is an alignment.
5268
5269 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5270 Alignment = llvm::bit_floor(gcd);
5271 }
5272 }
5273
5274 return Alignment;
5275}
5276
5277struct AAAlignImpl : AAAlign {
5278 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5279
5280 /// See AbstractAttribute::initialize(...).
5281 void initialize(Attributor &A) override {
5283 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5284 for (const Attribute &Attr : Attrs)
5285 takeKnownMaximum(Attr.getValueAsInt());
5286
5287 Value &V = *getAssociatedValue().stripPointerCasts();
5288 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5289
5290 if (Instruction *CtxI = getCtxI())
5291 followUsesInMBEC(*this, A, getState(), *CtxI);
5292 }
5293
5294 /// See AbstractAttribute::manifest(...).
5295 ChangeStatus manifest(Attributor &A) override {
5296 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5297
5298 // Check for users that allow alignment annotations.
5299 Value &AssociatedValue = getAssociatedValue();
5300 if (isa<ConstantData>(AssociatedValue))
5301 return ChangeStatus::UNCHANGED;
5302
5303 for (const Use &U : AssociatedValue.uses()) {
5304 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5305 if (SI->getPointerOperand() == &AssociatedValue)
5306 if (SI->getAlign() < getAssumedAlign()) {
5307 STATS_DECLTRACK(AAAlign, Store,
5308 "Number of times alignment added to a store");
5309 SI->setAlignment(getAssumedAlign());
5310 InstrChanged = ChangeStatus::CHANGED;
5311 }
5312 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5313 if (LI->getPointerOperand() == &AssociatedValue)
5314 if (LI->getAlign() < getAssumedAlign()) {
5315 LI->setAlignment(getAssumedAlign());
5316 STATS_DECLTRACK(AAAlign, Load,
5317 "Number of times alignment added to a load");
5318 InstrChanged = ChangeStatus::CHANGED;
5319 }
5320 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5321 if (RMW->getPointerOperand() == &AssociatedValue) {
5322 if (RMW->getAlign() < getAssumedAlign()) {
5323 STATS_DECLTRACK(AAAlign, AtomicRMW,
5324 "Number of times alignment added to atomicrmw");
5325
5326 RMW->setAlignment(getAssumedAlign());
5327 InstrChanged = ChangeStatus::CHANGED;
5328 }
5329 }
5330 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5331 if (CAS->getPointerOperand() == &AssociatedValue) {
5332 if (CAS->getAlign() < getAssumedAlign()) {
5333 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5334 "Number of times alignment added to cmpxchg");
5335 CAS->setAlignment(getAssumedAlign());
5336 InstrChanged = ChangeStatus::CHANGED;
5337 }
5338 }
5339 }
5340 }
5341
5342 ChangeStatus Changed = AAAlign::manifest(A);
5343
5344 Align InheritAlign =
5345 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5346 if (InheritAlign >= getAssumedAlign())
5347 return InstrChanged;
5348 return Changed | InstrChanged;
5349 }
5350
5351 // TODO: Provide a helper to determine the implied ABI alignment and check in
5352 // the existing manifest method and a new one for AAAlignImpl that value
5353 // to avoid making the alignment explicit if it did not improve.
5354
5355 /// See AbstractAttribute::getDeducedAttributes
5356 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5357 SmallVectorImpl<Attribute> &Attrs) const override {
5358 if (getAssumedAlign() > 1)
5359 Attrs.emplace_back(
5360 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5361 }
5362
5363 /// See followUsesInMBEC
5364 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5365 AAAlign::StateType &State) {
5366 bool TrackUse = false;
5367
5368 unsigned int KnownAlign =
5369 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5370 State.takeKnownMaximum(KnownAlign);
5371
5372 return TrackUse;
5373 }
5374
5375 /// See AbstractAttribute::getAsStr().
5376 const std::string getAsStr(Attributor *A) const override {
5377 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5378 std::to_string(getAssumedAlign().value()) + ">";
5379 }
5380};
5381
5382/// Align attribute for a floating value.
5383struct AAAlignFloating : AAAlignImpl {
5384 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5385
5386 /// See AbstractAttribute::updateImpl(...).
5387 ChangeStatus updateImpl(Attributor &A) override {
5388 const DataLayout &DL = A.getDataLayout();
5389
5390 bool Stripped;
5391 bool UsedAssumedInformation = false;
5393 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5394 AA::AnyScope, UsedAssumedInformation)) {
5395 Values.push_back({getAssociatedValue(), getCtxI()});
5396 Stripped = false;
5397 } else {
5398 Stripped = Values.size() != 1 ||
5399 Values.front().getValue() != &getAssociatedValue();
5400 }
5401
5402 StateType T;
5403 auto VisitValueCB = [&](Value &V) -> bool {
5405 return true;
5406 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5407 DepClassTy::REQUIRED);
5408 if (!AA || (!Stripped && this == AA)) {
5409 int64_t Offset;
5410 unsigned Alignment = 1;
5411 if (const Value *Base =
5413 // TODO: Use AAAlign for the base too.
5414 Align PA = Base->getPointerAlignment(DL);
5415 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5416 // So we can say that the maximum power of two which is a divisor of
5417 // gcd(Offset, Alignment) is an alignment.
5418
5419 uint32_t gcd =
5420 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5421 Alignment = llvm::bit_floor(gcd);
5422 } else {
5423 Alignment = V.getPointerAlignment(DL).value();
5424 }
5425 // Use only IR information if we did not strip anything.
5426 T.takeKnownMaximum(Alignment);
5427 T.indicatePessimisticFixpoint();
5428 } else {
5429 // Use abstract attribute information.
5430 const AAAlign::StateType &DS = AA->getState();
5431 T ^= DS;
5432 }
5433 return T.isValidState();
5434 };
5435
5436 for (const auto &VAC : Values) {
5437 if (!VisitValueCB(*VAC.getValue()))
5438 return indicatePessimisticFixpoint();
5439 }
5440
5441 // TODO: If we know we visited all incoming values, thus no are assumed
5442 // dead, we can take the known information from the state T.
5443 return clampStateAndIndicateChange(getState(), T);
5444 }
5445
5446 /// See AbstractAttribute::trackStatistics()
5447 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5448};
5449
5450/// Align attribute for function return value.
5451struct AAAlignReturned final
5452 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5453 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5454 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5455
5456 /// See AbstractAttribute::trackStatistics()
5457 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5458};
5459
5460/// Align attribute for function argument.
5461struct AAAlignArgument final
5462 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5463 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5464 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5465
5466 /// See AbstractAttribute::manifest(...).
5467 ChangeStatus manifest(Attributor &A) override {
5468 // If the associated argument is involved in a must-tail call we give up
5469 // because we would need to keep the argument alignments of caller and
5470 // callee in-sync. Just does not seem worth the trouble right now.
5471 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5472 return ChangeStatus::UNCHANGED;
5473 return Base::manifest(A);
5474 }
5475
5476 /// See AbstractAttribute::trackStatistics()
5477 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5478};
5479
5480struct AAAlignCallSiteArgument final : AAAlignFloating {
5481 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5482 : AAAlignFloating(IRP, A) {}
5483
5484 /// See AbstractAttribute::manifest(...).
5485 ChangeStatus manifest(Attributor &A) override {
5486 // If the associated argument is involved in a must-tail call we give up
5487 // because we would need to keep the argument alignments of caller and
5488 // callee in-sync. Just does not seem worth the trouble right now.
5489 if (Argument *Arg = getAssociatedArgument())
5490 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5491 return ChangeStatus::UNCHANGED;
5492 ChangeStatus Changed = AAAlignImpl::manifest(A);
5493 Align InheritAlign =
5494 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5495 if (InheritAlign >= getAssumedAlign())
5496 Changed = ChangeStatus::UNCHANGED;
5497 return Changed;
5498 }
5499
5500 /// See AbstractAttribute::updateImpl(Attributor &A).
5501 ChangeStatus updateImpl(Attributor &A) override {
5502 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5503 if (Argument *Arg = getAssociatedArgument()) {
5504 // We only take known information from the argument
5505 // so we do not need to track a dependence.
5506 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5507 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5508 if (ArgAlignAA)
5509 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5510 }
5511 return Changed;
5512 }
5513
5514 /// See AbstractAttribute::trackStatistics()
5515 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5516};
5517
5518/// Align attribute deduction for a call site return value.
5519struct AAAlignCallSiteReturned final
5520 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5521 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5522 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5523 : Base(IRP, A) {}
5524
5525 ChangeStatus updateImpl(Attributor &A) override {
5526 Instruction *I = getIRPosition().getCtxI();
5527 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5528 switch (II->getIntrinsicID()) {
5529 case Intrinsic::ptrmask: {
5530 Align Alignment;
5531 bool Valid = false;
5532
5533 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5534 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5535 if (ConstVals && ConstVals->isValidState()) {
5536 unsigned ShiftValue =
5537 std::min(ConstVals->getAssumedMinTrailingZeros(),
5538 Value::MaxAlignmentExponent);
5539 Alignment = Align(UINT64_C(1) << ShiftValue);
5540 Valid = true;
5541 }
5542
5543 const auto *AlignAA =
5544 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5545 DepClassTy::REQUIRED);
5546 if (AlignAA && AlignAA->isValidState()) {
5547 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5548 Valid = true;
5549 }
5550
5551 if (Valid)
5553 this->getState(),
5554 std::min(this->getAssumedAlign(), Alignment).value());
5555 break;
5556 }
5557 default:
5558 break;
5559 }
5560 }
5561 return Base::updateImpl(A);
5562 };
5563 /// See AbstractAttribute::trackStatistics()
5564 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5565};
5566} // namespace
5567
5568/// ------------------ Function No-Return Attribute ----------------------------
5569namespace {
5570struct AANoReturnImpl : public AANoReturn {
5571 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5572
5573 /// See AbstractAttribute::initialize(...).
5574 void initialize(Attributor &A) override {
5575 bool IsKnown;
5577 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5578 (void)IsKnown;
5579 }
5580
5581 /// See AbstractAttribute::getAsStr().
5582 const std::string getAsStr(Attributor *A) const override {
5583 return getAssumed() ? "noreturn" : "may-return";
5584 }
5585
5586 /// See AbstractAttribute::updateImpl(Attributor &A).
5587 ChangeStatus updateImpl(Attributor &A) override {
5588 auto CheckForNoReturn = [](Instruction &) { return false; };
5589 bool UsedAssumedInformation = false;
5590 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5591 {(unsigned)Instruction::Ret},
5592 UsedAssumedInformation))
5593 return indicatePessimisticFixpoint();
5594 return ChangeStatus::UNCHANGED;
5595 }
5596};
5597
5598struct AANoReturnFunction final : AANoReturnImpl {
5599 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5600 : AANoReturnImpl(IRP, A) {}
5601
5602 /// See AbstractAttribute::trackStatistics()
5603 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5604};
5605
5606/// NoReturn attribute deduction for a call sites.
5607struct AANoReturnCallSite final
5608 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5609 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5610 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5611
5612 /// See AbstractAttribute::trackStatistics()
5613 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5614};
5615} // namespace
5616
5617/// ----------------------- Instance Info ---------------------------------
5618
5619namespace {
5620/// A class to hold the state of for no-capture attributes.
5621struct AAInstanceInfoImpl : public AAInstanceInfo {
5622 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5623 : AAInstanceInfo(IRP, A) {}
5624
5625 /// See AbstractAttribute::initialize(...).
5626 void initialize(Attributor &A) override {
5627 Value &V = getAssociatedValue();
5628 if (auto *C = dyn_cast<Constant>(&V)) {
5629 if (C->isThreadDependent())
5630 indicatePessimisticFixpoint();
5631 else
5632 indicateOptimisticFixpoint();
5633 return;
5634 }
5635 if (auto *CB = dyn_cast<CallBase>(&V))
5636 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5637 !CB->mayReadFromMemory()) {
5638 indicateOptimisticFixpoint();
5639 return;
5640 }
5641 if (auto *I = dyn_cast<Instruction>(&V)) {
5642 const auto *CI =
5643 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5644 *I->getFunction());
5645 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5646 indicatePessimisticFixpoint();
5647 return;
5648 }
5649 }
5650 }
5651
5652 /// See AbstractAttribute::updateImpl(...).
5653 ChangeStatus updateImpl(Attributor &A) override {
5654 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5655
5656 Value &V = getAssociatedValue();
5657 const Function *Scope = nullptr;
5658 if (auto *I = dyn_cast<Instruction>(&V))
5659 Scope = I->getFunction();
5660 if (auto *A = dyn_cast<Argument>(&V)) {
5661 Scope = A->getParent();
5662 if (!Scope->hasLocalLinkage())
5663 return Changed;
5664 }
5665 if (!Scope)
5666 return indicateOptimisticFixpoint();
5667
5668 bool IsKnownNoRecurse;
5670 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5671 IsKnownNoRecurse))
5672 return Changed;
5673
5674 auto UsePred = [&](const Use &U, bool &Follow) {
5675 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5676 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5677 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5678 Follow = true;
5679 return true;
5680 }
5681 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5682 (isa<StoreInst>(UserI) &&
5683 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5684 return true;
5685 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5686 // This check is not guaranteeing uniqueness but for now that we cannot
5687 // end up with two versions of \p U thinking it was one.
5689 if (!Callee || !Callee->hasLocalLinkage())
5690 return true;
5691 if (!CB->isArgOperand(&U))
5692 return false;
5693 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5695 DepClassTy::OPTIONAL);
5696 if (!ArgInstanceInfoAA ||
5697 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5698 return false;
5699 // If this call base might reach the scope again we might forward the
5700 // argument back here. This is very conservative.
5702 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5703 [Scope](const Function &Fn) { return &Fn != Scope; }))
5704 return false;
5705 return true;
5706 }
5707 return false;
5708 };
5709
5710 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5711 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5712 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5713 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5714 AA::isDynamicallyUnique(A, *this, *Ptr))
5715 return true;
5716 }
5717 return false;
5718 };
5719
5720 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5721 DepClassTy::OPTIONAL,
5722 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5723 return indicatePessimisticFixpoint();
5724
5725 return Changed;
5726 }
5727
5728 /// See AbstractState::getAsStr().
5729 const std::string getAsStr(Attributor *A) const override {
5730 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5731 }
5732
5733 /// See AbstractAttribute::trackStatistics()
5734 void trackStatistics() const override {}
5735};
5736
5737/// InstanceInfo attribute for floating values.
5738struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5739 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5740 : AAInstanceInfoImpl(IRP, A) {}
5741};
5742
5743/// NoCapture attribute for function arguments.
5744struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5745 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5746 : AAInstanceInfoFloating(IRP, A) {}
5747};
5748
5749/// InstanceInfo attribute for call site arguments.
5750struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5751 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5752 : AAInstanceInfoImpl(IRP, A) {}
5753
5754 /// See AbstractAttribute::updateImpl(...).
5755 ChangeStatus updateImpl(Attributor &A) override {
5756 // TODO: Once we have call site specific value information we can provide
5757 // call site specific liveness information and then it makes
5758 // sense to specialize attributes for call sites arguments instead of
5759 // redirecting requests to the callee argument.
5760 Argument *Arg = getAssociatedArgument();
5761 if (!Arg)
5762 return indicatePessimisticFixpoint();
5763 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5764 auto *ArgAA =
5765 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5766 if (!ArgAA)
5767 return indicatePessimisticFixpoint();
5768 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5769 }
5770};
5771
5772/// InstanceInfo attribute for function return value.
5773struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5774 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5775 : AAInstanceInfoImpl(IRP, A) {
5776 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5777 }
5778
5779 /// See AbstractAttribute::initialize(...).
5780 void initialize(Attributor &A) override {
5781 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5782 }
5783
5784 /// See AbstractAttribute::updateImpl(...).
5785 ChangeStatus updateImpl(Attributor &A) override {
5786 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5787 }
5788};
5789
5790/// InstanceInfo attribute deduction for a call site return value.
5791struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5792 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5793 : AAInstanceInfoFloating(IRP, A) {}
5794};
5795} // namespace
5796
5797/// ----------------------- Variable Capturing ---------------------------------
5799 Attribute::AttrKind ImpliedAttributeKind,
5800 bool IgnoreSubsumingPositions) {
5801 assert(ImpliedAttributeKind == Attribute::Captures &&
5802 "Unexpected attribute kind");
5803 Value &V = IRP.getAssociatedValue();
5804 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5805 return V.use_empty();
5806
5807 // You cannot "capture" null in the default address space.
5808 //
5809 // FIXME: This should use NullPointerIsDefined to account for the function
5810 // attribute.
5812 V.getType()->getPointerAddressSpace() == 0)) {
5813 return true;
5814 }
5815
5817 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5818 /* IgnoreSubsumingPositions */ true);
5819 for (const Attribute &Attr : Attrs)
5820 if (capturesNothing(Attr.getCaptureInfo()))
5821 return true;
5822
5824 if (Argument *Arg = IRP.getAssociatedArgument()) {
5826 A.getAttrs(IRPosition::argument(*Arg),
5827 {Attribute::Captures, Attribute::ByVal}, Attrs,
5828 /* IgnoreSubsumingPositions */ true);
5829 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5830 return Attr.getKindAsEnum() == Attribute::ByVal ||
5832 });
5833 if (ArgNoCapture) {
5834 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5835 V.getContext(), CaptureInfo::none()));
5836 return true;
5837 }
5838 }
5839
5840 if (const Function *F = IRP.getAssociatedFunction()) {
5841 // Check what state the associated function can actually capture.
5844 if (State.isKnown(NO_CAPTURE)) {
5845 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5847 return true;
5848 }
5849 }
5850
5851 return false;
5852}
5853
5854/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5855/// depending on the ability of the function associated with \p IRP to capture
5856/// state in memory and through "returning/throwing", respectively.
5858 const Function &F,
5859 BitIntegerState &State) {
5860 // TODO: Once we have memory behavior attributes we should use them here.
5861
5862 // If we know we cannot communicate or write to memory, we do not care about
5863 // ptr2int anymore.
5864 bool ReadOnly = F.onlyReadsMemory();
5865 bool NoThrow = F.doesNotThrow();
5866 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5867 if (ReadOnly && NoThrow && IsVoidReturn) {
5868 State.addKnownBits(NO_CAPTURE);
5869 return;
5870 }
5871
5872 // A function cannot capture state in memory if it only reads memory, it can
5873 // however return/throw state and the state might be influenced by the
5874 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5875 if (ReadOnly)
5876 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5877
5878 // A function cannot communicate state back if it does not through
5879 // exceptions and doesn not return values.
5880 if (NoThrow && IsVoidReturn)
5881 State.addKnownBits(NOT_CAPTURED_IN_RET);
5882
5883 // Check existing "returned" attributes.
5884 int ArgNo = IRP.getCalleeArgNo();
5885 if (!NoThrow || ArgNo < 0 ||
5886 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5887 return;
5888
5889 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5890 if (F.hasParamAttribute(U, Attribute::Returned)) {
5891 if (U == unsigned(ArgNo))
5892 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5893 else if (ReadOnly)
5894 State.addKnownBits(NO_CAPTURE);
5895 else
5896 State.addKnownBits(NOT_CAPTURED_IN_RET);
5897 break;
5898 }
5899}
5900
5901namespace {
5902/// A class to hold the state of for no-capture attributes.
5903struct AANoCaptureImpl : public AANoCapture {
5904 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5905
5906 /// See AbstractAttribute::initialize(...).
5907 void initialize(Attributor &A) override {
5908 bool IsKnown;
5910 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5911 (void)IsKnown;
5912 }
5913
5914 /// See AbstractAttribute::updateImpl(...).
5915 ChangeStatus updateImpl(Attributor &A) override;
5916
5917 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5918 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5919 SmallVectorImpl<Attribute> &Attrs) const override {
5920 if (!isAssumedNoCaptureMaybeReturned())
5921 return;
5922
5923 if (isArgumentPosition()) {
5924 if (isAssumedNoCapture())
5925 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5926 else if (ManifestInternal)
5927 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5928 }
5929 }
5930
5931 /// See AbstractState::getAsStr().
5932 const std::string getAsStr(Attributor *A) const override {
5933 if (isKnownNoCapture())
5934 return "known not-captured";
5935 if (isAssumedNoCapture())
5936 return "assumed not-captured";
5937 if (isKnownNoCaptureMaybeReturned())
5938 return "known not-captured-maybe-returned";
5939 if (isAssumedNoCaptureMaybeReturned())
5940 return "assumed not-captured-maybe-returned";
5941 return "assumed-captured";
5942 }
5943
5944 /// Check the use \p U and update \p State accordingly. Return true if we
5945 /// should continue to update the state.
5946 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5947 bool &Follow) {
5948 Instruction *UInst = cast<Instruction>(U.getUser());
5949 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5950 << *UInst << "\n");
5951
5952 // Deal with ptr2int by following uses.
5953 if (isa<PtrToIntInst>(UInst)) {
5954 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5955 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5956 /* Return */ true);
5957 }
5958
5959 // For stores we already checked if we can follow them, if they make it
5960 // here we give up.
5961 if (isa<StoreInst>(UInst))
5962 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5963 /* Return */ true);
5964
5965 // Explicitly catch return instructions.
5966 if (isa<ReturnInst>(UInst)) {
5967 if (UInst->getFunction() == getAnchorScope())
5968 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5969 /* Return */ true);
5970 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5971 /* Return */ true);
5972 }
5973
5974 // For now we only use special logic for call sites. However, the tracker
5975 // itself knows about a lot of other non-capturing cases already.
5976 auto *CB = dyn_cast<CallBase>(UInst);
5977 if (!CB || !CB->isArgOperand(&U))
5978 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5979 /* Return */ true);
5980
5981 unsigned ArgNo = CB->getArgOperandNo(&U);
5982 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5983 // If we have a abstract no-capture attribute for the argument we can use
5984 // it to justify a non-capture attribute here. This allows recursion!
5985 bool IsKnownNoCapture;
5986 const AANoCapture *ArgNoCaptureAA = nullptr;
5987 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
5988 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5989 &ArgNoCaptureAA);
5990 if (IsAssumedNoCapture)
5991 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5992 /* Return */ false);
5993 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5994 Follow = true;
5995 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5996 /* Return */ false);
5997 }
5998
5999 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6000 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6001 /* Return */ true);
6002 }
6003
6004 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6005 /// \p CapturedInRet, then return true if we should continue updating the
6006 /// state.
6007 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6008 bool CapturedInInt, bool CapturedInRet) {
6009 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6010 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6011 if (CapturedInMem)
6012 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6013 if (CapturedInInt)
6014 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6015 if (CapturedInRet)
6016 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6017 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6018 }
6019};
6020
6021ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6022 const IRPosition &IRP = getIRPosition();
6023 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6024 : &IRP.getAssociatedValue();
6025 if (!V)
6026 return indicatePessimisticFixpoint();
6027
6028 const Function *F =
6029 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6030
6031 // TODO: Is the checkForAllUses below useful for constants?
6032 if (!F)
6033 return indicatePessimisticFixpoint();
6034
6036 const IRPosition &FnPos = IRPosition::function(*F);
6037
6038 // Readonly means we cannot capture through memory.
6039 bool IsKnown;
6040 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6041 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6042 if (IsKnown)
6043 addKnownBits(NOT_CAPTURED_IN_MEM);
6044 }
6045
6046 // Make sure all returned values are different than the underlying value.
6047 // TODO: we could do this in a more sophisticated way inside
6048 // AAReturnedValues, e.g., track all values that escape through returns
6049 // directly somehow.
6050 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6052 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6054 UsedAssumedInformation))
6055 return false;
6056 bool SeenConstant = false;
6057 for (const AA::ValueAndContext &VAC : Values) {
6058 if (isa<Constant>(VAC.getValue())) {
6059 if (SeenConstant)
6060 return false;
6061 SeenConstant = true;
6062 } else if (!isa<Argument>(VAC.getValue()) ||
6063 VAC.getValue() == getAssociatedArgument())
6064 return false;
6065 }
6066 return true;
6067 };
6068
6069 bool IsKnownNoUnwind;
6071 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6072 bool IsVoidTy = F->getReturnType()->isVoidTy();
6073 bool UsedAssumedInformation = false;
6074 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6075 T.addKnownBits(NOT_CAPTURED_IN_RET);
6076 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6078 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6079 addKnownBits(NOT_CAPTURED_IN_RET);
6080 if (isKnown(NOT_CAPTURED_IN_MEM))
6081 return indicateOptimisticFixpoint();
6082 }
6083 }
6084 }
6085
6086 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6087 // TODO(captures): Make this more precise.
6088 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6089 if (capturesNothing(CI))
6090 return true;
6091 if (CI.isPassthrough()) {
6092 Follow = true;
6093 return true;
6094 }
6095 return checkUse(A, T, U, Follow);
6096 };
6097
6098 if (!A.checkForAllUses(UseCheck, *this, *V))
6099 return indicatePessimisticFixpoint();
6100
6101 AANoCapture::StateType &S = getState();
6102 auto Assumed = S.getAssumed();
6103 S.intersectAssumedBits(T.getAssumed());
6104 if (!isAssumedNoCaptureMaybeReturned())
6105 return indicatePessimisticFixpoint();
6106 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6108}
6109
6110/// NoCapture attribute for function arguments.
6111struct AANoCaptureArgument final : AANoCaptureImpl {
6112 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6113 : AANoCaptureImpl(IRP, A) {}
6114
6115 /// See AbstractAttribute::trackStatistics()
6116 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6117};
6118
6119/// NoCapture attribute for call site arguments.
6120struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6121 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6122 : AANoCaptureImpl(IRP, A) {}
6123
6124 /// See AbstractAttribute::updateImpl(...).
6125 ChangeStatus updateImpl(Attributor &A) override {
6126 // TODO: Once we have call site specific value information we can provide
6127 // call site specific liveness information and then it makes
6128 // sense to specialize attributes for call sites arguments instead of
6129 // redirecting requests to the callee argument.
6130 Argument *Arg = getAssociatedArgument();
6131 if (!Arg)
6132 return indicatePessimisticFixpoint();
6133 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6134 bool IsKnownNoCapture;
6135 const AANoCapture *ArgAA = nullptr;
6137 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6138 &ArgAA))
6139 return ChangeStatus::UNCHANGED;
6140 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6141 return indicatePessimisticFixpoint();
6142 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6143 }
6144
6145 /// See AbstractAttribute::trackStatistics()
6146 void trackStatistics() const override {
6148 };
6149};
6150
6151/// NoCapture attribute for floating values.
6152struct AANoCaptureFloating final : AANoCaptureImpl {
6153 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6154 : AANoCaptureImpl(IRP, A) {}
6155
6156 /// See AbstractAttribute::trackStatistics()
6157 void trackStatistics() const override {
6159 }
6160};
6161
6162/// NoCapture attribute for function return value.
6163struct AANoCaptureReturned final : AANoCaptureImpl {
6164 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6165 : AANoCaptureImpl(IRP, A) {
6166 llvm_unreachable("NoCapture is not applicable to function returns!");
6167 }
6168
6169 /// See AbstractAttribute::initialize(...).
6170 void initialize(Attributor &A) override {
6171 llvm_unreachable("NoCapture is not applicable to function returns!");
6172 }
6173
6174 /// See AbstractAttribute::updateImpl(...).
6175 ChangeStatus updateImpl(Attributor &A) override {
6176 llvm_unreachable("NoCapture is not applicable to function returns!");
6177 }
6178
6179 /// See AbstractAttribute::trackStatistics()
6180 void trackStatistics() const override {}
6181};
6182
6183/// NoCapture attribute deduction for a call site return value.
6184struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6185 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6186 : AANoCaptureImpl(IRP, A) {}
6187
6188 /// See AbstractAttribute::initialize(...).
6189 void initialize(Attributor &A) override {
6190 const Function *F = getAnchorScope();
6191 // Check what state the associated function can actually capture.
6192 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6193 }
6194
6195 /// See AbstractAttribute::trackStatistics()
6196 void trackStatistics() const override {
6198 }
6199};
6200} // namespace
6201
6202/// ------------------ Value Simplify Attribute ----------------------------
6203
6204bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6205 // FIXME: Add a typecast support.
6208 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6209 return false;
6210
6211 LLVM_DEBUG({
6213 dbgs() << "[ValueSimplify] is assumed to be "
6214 << **SimplifiedAssociatedValue << "\n";
6215 else
6216 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6217 });
6218 return true;
6219}
6220
6221namespace {
6222struct AAValueSimplifyImpl : AAValueSimplify {
6223 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6224 : AAValueSimplify(IRP, A) {}
6225
6226 /// See AbstractAttribute::initialize(...).
6227 void initialize(Attributor &A) override {
6228 if (getAssociatedValue().getType()->isVoidTy())
6229 indicatePessimisticFixpoint();
6230 if (A.hasSimplificationCallback(getIRPosition()))
6231 indicatePessimisticFixpoint();
6232 }
6233
6234 /// See AbstractAttribute::getAsStr().
6235 const std::string getAsStr(Attributor *A) const override {
6236 LLVM_DEBUG({
6237 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6238 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6239 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6240 });
6241 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6242 : "not-simple";
6243 }
6244
6245 /// See AbstractAttribute::trackStatistics()
6246 void trackStatistics() const override {}
6247
6248 /// See AAValueSimplify::getAssumedSimplifiedValue()
6249 std::optional<Value *>
6250 getAssumedSimplifiedValue(Attributor &A) const override {
6251 return SimplifiedAssociatedValue;
6252 }
6253
6254 /// Ensure the return value is \p V with type \p Ty, if not possible return
6255 /// nullptr. If \p Check is true we will only verify such an operation would
6256 /// suceed and return a non-nullptr value if that is the case. No IR is
6257 /// generated or modified.
6258 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6259 bool Check) {
6260 if (auto *TypedV = AA::getWithType(V, Ty))
6261 return TypedV;
6262 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6263 return Check ? &V
6264 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6265 &V, &Ty, "", CtxI->getIterator());
6266 return nullptr;
6267 }
6268
6269 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6270 /// If \p Check is true we will only verify such an operation would suceed and
6271 /// return a non-nullptr value if that is the case. No IR is generated or
6272 /// modified.
6273 static Value *reproduceInst(Attributor &A,
6274 const AbstractAttribute &QueryingAA,
6275 Instruction &I, Type &Ty, Instruction *CtxI,
6276 bool Check, ValueToValueMapTy &VMap) {
6277 assert(CtxI && "Cannot reproduce an instruction without context!");
6278 if (Check && (I.mayReadFromMemory() ||
6279 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6280 /* TLI */ nullptr)))
6281 return nullptr;
6282 for (Value *Op : I.operands()) {
6283 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6284 if (!NewOp) {
6285 assert(Check && "Manifest of new value unexpectedly failed!");
6286 return nullptr;
6287 }
6288 if (!Check)
6289 VMap[Op] = NewOp;
6290 }
6291 if (Check)
6292 return &I;
6293
6294 Instruction *CloneI = I.clone();
6295 // TODO: Try to salvage debug information here.
6296 CloneI->setDebugLoc(DebugLoc());
6297 VMap[&I] = CloneI;
6298 CloneI->insertBefore(CtxI->getIterator());
6299 RemapInstruction(CloneI, VMap);
6300 return CloneI;
6301 }
6302
6303 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6304 /// If \p Check is true we will only verify such an operation would suceed and
6305 /// return a non-nullptr value if that is the case. No IR is generated or
6306 /// modified.
6307 static Value *reproduceValue(Attributor &A,
6308 const AbstractAttribute &QueryingAA, Value &V,
6309 Type &Ty, Instruction *CtxI, bool Check,
6310 ValueToValueMapTy &VMap) {
6311 if (const auto &NewV = VMap.lookup(&V))
6312 return NewV;
6313 bool UsedAssumedInformation = false;
6314 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6315 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6316 if (!SimpleV.has_value())
6317 return PoisonValue::get(&Ty);
6318 Value *EffectiveV = &V;
6319 if (*SimpleV)
6320 EffectiveV = *SimpleV;
6321 if (auto *C = dyn_cast<Constant>(EffectiveV))
6322 return C;
6323 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6324 A.getInfoCache()))
6325 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6326 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6327 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6328 return ensureType(A, *NewV, Ty, CtxI, Check);
6329 return nullptr;
6330 }
6331
6332 /// Return a value we can use as replacement for the associated one, or
6333 /// nullptr if we don't have one that makes sense.
6334 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6335 Value *NewV = SimplifiedAssociatedValue
6336 ? *SimplifiedAssociatedValue
6337 : UndefValue::get(getAssociatedType());
6338 if (NewV && NewV != &getAssociatedValue()) {
6339 ValueToValueMapTy VMap;
6340 // First verify we can reprduce the value with the required type at the
6341 // context location before we actually start modifying the IR.
6342 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6343 /* CheckOnly */ true, VMap))
6344 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6345 /* CheckOnly */ false, VMap);
6346 }
6347 return nullptr;
6348 }
6349
6350 /// Helper function for querying AAValueSimplify and updating candidate.
6351 /// \param IRP The value position we are trying to unify with SimplifiedValue
6352 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6353 const IRPosition &IRP, bool Simplify = true) {
6354 bool UsedAssumedInformation = false;
6355 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6356 if (Simplify)
6357 QueryingValueSimplified = A.getAssumedSimplified(
6358 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6359 return unionAssumed(QueryingValueSimplified);
6360 }
6361
6362 /// Returns a candidate is found or not
6363 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6364 if (!getAssociatedValue().getType()->isIntegerTy())
6365 return false;
6366
6367 // This will also pass the call base context.
6368 const auto *AA =
6369 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6370 if (!AA)
6371 return false;
6372
6373 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6374
6375 if (!COpt) {
6376 SimplifiedAssociatedValue = std::nullopt;
6377 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6378 return true;
6379 }
6380 if (auto *C = *COpt) {
6381 SimplifiedAssociatedValue = C;
6382 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6383 return true;
6384 }
6385 return false;
6386 }
6387
6388 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6389 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6390 return true;
6391 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6392 return true;
6393 return false;
6394 }
6395
6396 /// See AbstractAttribute::manifest(...).
6397 ChangeStatus manifest(Attributor &A) override {
6398 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6399 for (auto &U : getAssociatedValue().uses()) {
6400 // Check if we need to adjust the insertion point to make sure the IR is
6401 // valid.
6402 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6403 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6404 IP = PHI->getIncomingBlock(U)->getTerminator();
6405 if (auto *NewV = manifestReplacementValue(A, IP)) {
6406 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6407 << " -> " << *NewV << " :: " << *this << "\n");
6408 if (A.changeUseAfterManifest(U, *NewV))
6409 Changed = ChangeStatus::CHANGED;
6410 }
6411 }
6412
6413 return Changed | AAValueSimplify::manifest(A);
6414 }
6415
6416 /// See AbstractState::indicatePessimisticFixpoint(...).
6417 ChangeStatus indicatePessimisticFixpoint() override {
6418 SimplifiedAssociatedValue = &getAssociatedValue();
6419 return AAValueSimplify::indicatePessimisticFixpoint();
6420 }
6421};
6422
6423struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6424 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6425 : AAValueSimplifyImpl(IRP, A) {}
6426
6427 void initialize(Attributor &A) override {
6428 AAValueSimplifyImpl::initialize(A);
6429 if (A.hasAttr(getIRPosition(),
6430 {Attribute::InAlloca, Attribute::Preallocated,
6431 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6432 /* IgnoreSubsumingPositions */ true))
6433 indicatePessimisticFixpoint();
6434 }
6435
6436 /// See AbstractAttribute::updateImpl(...).
6437 ChangeStatus updateImpl(Attributor &A) override {
6438 // Byval is only replacable if it is readonly otherwise we would write into
6439 // the replaced value and not the copy that byval creates implicitly.
6440 Argument *Arg = getAssociatedArgument();
6441 if (Arg->hasByValAttr()) {
6442 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6443 // there is no race by not copying a constant byval.
6444 bool IsKnown;
6445 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6446 return indicatePessimisticFixpoint();
6447 }
6448
6449 auto Before = SimplifiedAssociatedValue;
6450
6451 auto PredForCallSite = [&](AbstractCallSite ACS) {
6452 const IRPosition &ACSArgPos =
6453 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6454 // Check if a coresponding argument was found or if it is on not
6455 // associated (which can happen for callback calls).
6456 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6457 return false;
6458
6459 // Simplify the argument operand explicitly and check if the result is
6460 // valid in the current scope. This avoids refering to simplified values
6461 // in other functions, e.g., we don't want to say a an argument in a
6462 // static function is actually an argument in a different function.
6463 bool UsedAssumedInformation = false;
6464 std::optional<Constant *> SimpleArgOp =
6465 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6466 if (!SimpleArgOp)
6467 return true;
6468 if (!*SimpleArgOp)
6469 return false;
6470 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6471 return false;
6472 return unionAssumed(*SimpleArgOp);
6473 };
6474
6475 // Generate a answer specific to a call site context.
6476 bool Success;
6477 bool UsedAssumedInformation = false;
6478 if (hasCallBaseContext() &&
6479 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6480 Success = PredForCallSite(
6481 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6482 else
6483 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6484 UsedAssumedInformation);
6485
6486 if (!Success)
6487 if (!askSimplifiedValueForOtherAAs(A))
6488 return indicatePessimisticFixpoint();
6489
6490 // If a candidate was found in this update, return CHANGED.
6491 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6492 : ChangeStatus ::CHANGED;
6493 }
6494
6495 /// See AbstractAttribute::trackStatistics()
6496 void trackStatistics() const override {
6497 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6498 }
6499};
6500
6501struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6502 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6503 : AAValueSimplifyImpl(IRP, A) {}
6504
6505 /// See AAValueSimplify::getAssumedSimplifiedValue()
6506 std::optional<Value *>
6507 getAssumedSimplifiedValue(Attributor &A) const override {
6508 if (!isValidState())
6509 return nullptr;
6510 return SimplifiedAssociatedValue;
6511 }
6512
6513 /// See AbstractAttribute::updateImpl(...).
6514 ChangeStatus updateImpl(Attributor &A) override {
6515 auto Before = SimplifiedAssociatedValue;
6516
6517 auto ReturnInstCB = [&](Instruction &I) {
6518 auto &RI = cast<ReturnInst>(I);
6519 return checkAndUpdate(
6520 A, *this,
6521 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6522 };
6523
6524 bool UsedAssumedInformation = false;
6525 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6526 UsedAssumedInformation))
6527 if (!askSimplifiedValueForOtherAAs(A))
6528 return indicatePessimisticFixpoint();
6529
6530 // If a candidate was found in this update, return CHANGED.
6531 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6532 : ChangeStatus ::CHANGED;
6533 }
6534
6535 ChangeStatus manifest(Attributor &A) override {
6536 // We queried AAValueSimplify for the returned values so they will be
6537 // replaced if a simplified form was found. Nothing to do here.
6538 return ChangeStatus::UNCHANGED;
6539 }
6540
6541 /// See AbstractAttribute::trackStatistics()
6542 void trackStatistics() const override {
6543 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6544 }
6545};
6546
6547struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6548 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6549 : AAValueSimplifyImpl(IRP, A) {}
6550
6551 /// See AbstractAttribute::initialize(...).
6552 void initialize(Attributor &A) override {
6553 AAValueSimplifyImpl::initialize(A);
6554 Value &V = getAnchorValue();
6555
6556 // TODO: add other stuffs
6557 if (isa<Constant>(V))
6558 indicatePessimisticFixpoint();
6559 }
6560
6561 /// See AbstractAttribute::updateImpl(...).
6562 ChangeStatus updateImpl(Attributor &A) override {
6563 auto Before = SimplifiedAssociatedValue;
6564 if (!askSimplifiedValueForOtherAAs(A))
6565 return indicatePessimisticFixpoint();
6566
6567 // If a candidate was found in this update, return CHANGED.
6568 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6569 : ChangeStatus ::CHANGED;
6570 }
6571
6572 /// See AbstractAttribute::trackStatistics()
6573 void trackStatistics() const override {
6574 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6575 }
6576};
6577
6578struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6579 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6580 : AAValueSimplifyImpl(IRP, A) {}
6581
6582 /// See AbstractAttribute::initialize(...).
6583 void initialize(Attributor &A) override {
6584 SimplifiedAssociatedValue = nullptr;
6585 indicateOptimisticFixpoint();
6586 }
6587 /// See AbstractAttribute::initialize(...).
6588 ChangeStatus updateImpl(Attributor &A) override {
6590 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6591 }
6592 /// See AbstractAttribute::trackStatistics()
6593 void trackStatistics() const override {
6594 STATS_DECLTRACK_FN_ATTR(value_simplify)
6595 }
6596};
6597
6598struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6599 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6600 : AAValueSimplifyFunction(IRP, A) {}
6601 /// See AbstractAttribute::trackStatistics()
6602 void trackStatistics() const override {
6603 STATS_DECLTRACK_CS_ATTR(value_simplify)
6604 }
6605};
6606
6607struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6608 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6609 : AAValueSimplifyImpl(IRP, A) {}
6610
6611 void initialize(Attributor &A) override {
6612 AAValueSimplifyImpl::initialize(A);
6613 Function *Fn = getAssociatedFunction();
6614 assert(Fn && "Did expect an associted function");
6615 for (Argument &Arg : Fn->args()) {
6616 if (Arg.hasReturnedAttr()) {
6617 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6618 Arg.getArgNo());
6620 checkAndUpdate(A, *this, IRP))
6621 indicateOptimisticFixpoint();
6622 else
6623 indicatePessimisticFixpoint();
6624 return;
6625 }
6626 }
6627 }
6628
6629 /// See AbstractAttribute::updateImpl(...).
6630 ChangeStatus updateImpl(Attributor &A) override {
6631 return indicatePessimisticFixpoint();
6632 }
6633
6634 void trackStatistics() const override {
6635 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6636 }
6637};
6638
6639struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6640 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6641 : AAValueSimplifyFloating(IRP, A) {}
6642
6643 /// See AbstractAttribute::manifest(...).
6644 ChangeStatus manifest(Attributor &A) override {
6645 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6646 // TODO: We should avoid simplification duplication to begin with.
6647 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6648 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6649 if (FloatAA && FloatAA->getState().isValidState())
6650 return Changed;
6651
6652 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6653 Use &U = cast<CallBase>(&getAnchorValue())
6654 ->getArgOperandUse(getCallSiteArgNo());
6655 if (A.changeUseAfterManifest(U, *NewV))
6656 Changed = ChangeStatus::CHANGED;
6657 }
6658
6659 return Changed | AAValueSimplify::manifest(A);
6660 }
6661
6662 void trackStatistics() const override {
6663 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6664 }
6665};
6666} // namespace
6667
6668/// ----------------------- Heap-To-Stack Conversion ---------------------------
6669namespace {
6670struct AAHeapToStackFunction final : public AAHeapToStack {
6671
6672 struct AllocationInfo {
6673 /// The call that allocates the memory.
6674 CallBase *const CB;
6675
6676 /// The library function id for the allocation.
6677 LibFunc LibraryFunctionId = NotLibFunc;
6678
6679 /// The status wrt. a rewrite.
6680 enum {
6681 STACK_DUE_TO_USE,
6682 STACK_DUE_TO_FREE,
6683 INVALID,
6684 } Status = STACK_DUE_TO_USE;
6685
6686 /// Flag to indicate if we encountered a use that might free this allocation
6687 /// but which is not in the deallocation infos.
6688 bool HasPotentiallyFreeingUnknownUses = false;
6689
6690 /// Flag to indicate that we should place the new alloca in the function
6691 /// entry block rather than where the call site (CB) is.
6692 bool MoveAllocaIntoEntry = true;
6693
6694 /// The set of free calls that use this allocation.
6695 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6696 };
6697
6698 struct DeallocationInfo {
6699 /// The call that deallocates the memory.
6700 CallBase *const CB;
6701 /// The value freed by the call.
6702 Value *FreedOp;
6703
6704 /// Flag to indicate if we don't know all objects this deallocation might
6705 /// free.
6706 bool MightFreeUnknownObjects = false;
6707
6708 /// The set of allocation calls that are potentially freed.
6709 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6710 };
6711
6712 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6713 : AAHeapToStack(IRP, A) {}
6714
6715 ~AAHeapToStackFunction() override {
6716 // Ensure we call the destructor so we release any memory allocated in the
6717 // sets.
6718 for (auto &It : AllocationInfos)
6719 It.second->~AllocationInfo();
6720 for (auto &It : DeallocationInfos)
6721 It.second->~DeallocationInfo();
6722 }
6723
6724 void initialize(Attributor &A) override {
6725 AAHeapToStack::initialize(A);
6726
6727 const Function *F = getAnchorScope();
6728 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6729
6730 auto AllocationIdentifierCB = [&](Instruction &I) {
6731 CallBase *CB = dyn_cast<CallBase>(&I);
6732 if (!CB)
6733 return true;
6734 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6735 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6736 return true;
6737 }
6738 // To do heap to stack, we need to know that the allocation itself is
6739 // removable once uses are rewritten, and that we can initialize the
6740 // alloca to the same pattern as the original allocation result.
6741 if (isRemovableAlloc(CB, TLI)) {
6742 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6743 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6744 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6745 AllocationInfos[CB] = AI;
6746 if (TLI)
6747 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6748 }
6749 }
6750 return true;
6751 };
6752
6753 bool UsedAssumedInformation = false;
6754 bool Success = A.checkForAllCallLikeInstructions(
6755 AllocationIdentifierCB, *this, UsedAssumedInformation,
6756 /* CheckBBLivenessOnly */ false,
6757 /* CheckPotentiallyDead */ true);
6758 (void)Success;
6759 assert(Success && "Did not expect the call base visit callback to fail!");
6760
6762 [](const IRPosition &, const AbstractAttribute *,
6763 bool &) -> std::optional<Value *> { return nullptr; };
6764 for (const auto &It : AllocationInfos)
6765 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6766 SCB);
6767 for (const auto &It : DeallocationInfos)
6768 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6769 SCB);
6770 }
6771
6772 const std::string getAsStr(Attributor *A) const override {
6773 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6774 for (const auto &It : AllocationInfos) {
6775 if (It.second->Status == AllocationInfo::INVALID)
6776 ++NumInvalidMallocs;
6777 else
6778 ++NumH2SMallocs;
6779 }
6780 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6781 std::to_string(NumInvalidMallocs);
6782 }
6783
6784 /// See AbstractAttribute::trackStatistics().
6785 void trackStatistics() const override {
6786 STATS_DECL(
6787 MallocCalls, Function,
6788 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6789 for (const auto &It : AllocationInfos)
6790 if (It.second->Status != AllocationInfo::INVALID)
6791 ++BUILD_STAT_NAME(MallocCalls, Function);
6792 }
6793
6794 bool isAssumedHeapToStack(const CallBase &CB) const override {
6795 if (isValidState())
6796 if (AllocationInfo *AI =
6797 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6798 return AI->Status != AllocationInfo::INVALID;
6799 return false;
6800 }
6801
6802 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6803 if (!isValidState())
6804 return false;
6805
6806 for (const auto &It : AllocationInfos) {
6807 AllocationInfo &AI = *It.second;
6808 if (AI.Status == AllocationInfo::INVALID)
6809 continue;
6810
6811 if (AI.PotentialFreeCalls.count(&CB))
6812 return true;
6813 }
6814
6815 return false;
6816 }
6817
6818 ChangeStatus manifest(Attributor &A) override {
6819 assert(getState().isValidState() &&
6820 "Attempted to manifest an invalid state!");
6821
6822 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6823 Function *F = getAnchorScope();
6824 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6825
6826 for (auto &It : AllocationInfos) {
6827 AllocationInfo &AI = *It.second;
6828 if (AI.Status == AllocationInfo::INVALID)
6829 continue;
6830
6831 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6832 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6833 A.deleteAfterManifest(*FreeCall);
6834 HasChanged = ChangeStatus::CHANGED;
6835 }
6836
6837 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6838 << "\n");
6839
6840 auto Remark = [&](OptimizationRemark OR) {
6841 LibFunc IsAllocShared;
6842 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6843 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6844 return OR << "Moving globalized variable to the stack.";
6845 return OR << "Moving memory allocation from the heap to the stack.";
6846 };
6847 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6848 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6849 else
6850 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6851
6852 const DataLayout &DL = A.getInfoCache().getDL();
6853 Value *Size;
6854 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6855 if (SizeAPI) {
6856 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6857 } else {
6858 LLVMContext &Ctx = AI.CB->getContext();
6859 ObjectSizeOpts Opts;
6860 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6861 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6862 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6863 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6864 Size = SizeOffsetPair.Size;
6865 }
6866
6867 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6868 ? F->getEntryBlock().begin()
6869 : AI.CB->getIterator();
6870
6871 Align Alignment(1);
6872 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6873 Alignment = std::max(Alignment, *RetAlign);
6874 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6875 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6876 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6877 "Expected an alignment during manifest!");
6878 Alignment =
6879 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6880 }
6881
6882 // TODO: Hoist the alloca towards the function entry.
6883 unsigned AS = DL.getAllocaAddrSpace();
6884 Instruction *Alloca =
6885 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6886 AI.CB->getName() + ".h2s", IP);
6887
6888 if (Alloca->getType() != AI.CB->getType())
6889 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6890 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6891
6892 auto *I8Ty = Type::getInt8Ty(F->getContext());
6893 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6894 assert(InitVal &&
6895 "Must be able to materialize initial memory state of allocation");
6896
6897 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6898
6899 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6900 auto *NBB = II->getNormalDest();
6901 BranchInst::Create(NBB, AI.CB->getParent());
6902 A.deleteAfterManifest(*AI.CB);
6903 } else {
6904 A.deleteAfterManifest(*AI.CB);
6905 }
6906
6907 // Initialize the alloca with the same value as used by the allocation
6908 // function. We can skip undef as the initial value of an alloc is
6909 // undef, and the memset would simply end up being DSEd.
6910 if (!isa<UndefValue>(InitVal)) {
6911 IRBuilder<> Builder(Alloca->getNextNode());
6912 // TODO: Use alignment above if align!=1
6913 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6914 }
6915 HasChanged = ChangeStatus::CHANGED;
6916 }
6917
6918 return HasChanged;
6919 }
6920
6921 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6922 Value &V) {
6923 bool UsedAssumedInformation = false;
6924 std::optional<Constant *> SimpleV =
6925 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6926 if (!SimpleV)
6927 return APInt(64, 0);
6928 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6929 return CI->getValue();
6930 return std::nullopt;
6931 }
6932
6933 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6934 AllocationInfo &AI) {
6935 auto Mapper = [&](const Value *V) -> const Value * {
6936 bool UsedAssumedInformation = false;
6937 if (std::optional<Constant *> SimpleV =
6938 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6939 if (*SimpleV)
6940 return *SimpleV;
6941 return V;
6942 };
6943
6944 const Function *F = getAnchorScope();
6945 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6946 return getAllocSize(AI.CB, TLI, Mapper);
6947 }
6948
6949 /// Collection of all malloc-like calls in a function with associated
6950 /// information.
6951 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6952
6953 /// Collection of all free-like calls in a function with associated
6954 /// information.
6955 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6956
6957 ChangeStatus updateImpl(Attributor &A) override;
6958};
6959
6960ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6962 const Function *F = getAnchorScope();
6963 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6964
6965 const auto *LivenessAA =
6966 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6967
6968 MustBeExecutedContextExplorer *Explorer =
6969 A.getInfoCache().getMustBeExecutedContextExplorer();
6970
6971 bool StackIsAccessibleByOtherThreads =
6972 A.getInfoCache().stackIsAccessibleByOtherThreads();
6973
6974 LoopInfo *LI =
6975 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6976 std::optional<bool> MayContainIrreducibleControl;
6977 auto IsInLoop = [&](BasicBlock &BB) {
6978 if (&F->getEntryBlock() == &BB)
6979 return false;
6980 if (!MayContainIrreducibleControl.has_value())
6981 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6982 if (*MayContainIrreducibleControl)
6983 return true;
6984 if (!LI)
6985 return true;
6986 return LI->getLoopFor(&BB) != nullptr;
6987 };
6988
6989 // Flag to ensure we update our deallocation information at most once per
6990 // updateImpl call and only if we use the free check reasoning.
6991 bool HasUpdatedFrees = false;
6992
6993 auto UpdateFrees = [&]() {
6994 HasUpdatedFrees = true;
6995
6996 for (auto &It : DeallocationInfos) {
6997 DeallocationInfo &DI = *It.second;
6998 // For now we cannot use deallocations that have unknown inputs, skip
6999 // them.
7000 if (DI.MightFreeUnknownObjects)
7001 continue;
7002
7003 // No need to analyze dead calls, ignore them instead.
7004 bool UsedAssumedInformation = false;
7005 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7006 /* CheckBBLivenessOnly */ true))
7007 continue;
7008
7009 // Use the non-optimistic version to get the freed object.
7010 Value *Obj = getUnderlyingObject(DI.FreedOp);
7011 if (!Obj) {
7012 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7013 DI.MightFreeUnknownObjects = true;
7014 continue;
7015 }
7016
7017 // Free of null and undef can be ignored as no-ops (or UB in the latter
7018 // case).
7020 continue;
7021
7022 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7023 if (!ObjCB) {
7024 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7025 << "\n");
7026 DI.MightFreeUnknownObjects = true;
7027 continue;
7028 }
7029
7030 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7031 if (!AI) {
7032 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7033 << "\n");
7034 DI.MightFreeUnknownObjects = true;
7035 continue;
7036 }
7037
7038 DI.PotentialAllocationCalls.insert(ObjCB);
7039 }
7040 };
7041
7042 auto FreeCheck = [&](AllocationInfo &AI) {
7043 // If the stack is not accessible by other threads, the "must-free" logic
7044 // doesn't apply as the pointer could be shared and needs to be places in
7045 // "shareable" memory.
7046 if (!StackIsAccessibleByOtherThreads) {
7047 bool IsKnownNoSycn;
7049 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7050 LLVM_DEBUG(
7051 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7052 "other threads and function is not nosync:\n");
7053 return false;
7054 }
7055 }
7056 if (!HasUpdatedFrees)
7057 UpdateFrees();
7058
7059 // TODO: Allow multi exit functions that have different free calls.
7060 if (AI.PotentialFreeCalls.size() != 1) {
7061 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7062 << AI.PotentialFreeCalls.size() << "\n");
7063 return false;
7064 }
7065 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7066 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7067 if (!DI) {
7068 LLVM_DEBUG(
7069 dbgs() << "[H2S] unique free call was not known as deallocation call "
7070 << *UniqueFree << "\n");
7071 return false;
7072 }
7073 if (DI->MightFreeUnknownObjects) {
7074 LLVM_DEBUG(
7075 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7076 return false;
7077 }
7078 if (DI->PotentialAllocationCalls.empty())
7079 return true;
7080 if (DI->PotentialAllocationCalls.size() > 1) {
7081 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7082 << DI->PotentialAllocationCalls.size()
7083 << " different allocations\n");
7084 return false;
7085 }
7086 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7087 LLVM_DEBUG(
7088 dbgs()
7089 << "[H2S] unique free call not known to free this allocation but "
7090 << **DI->PotentialAllocationCalls.begin() << "\n");
7091 return false;
7092 }
7093
7094 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
7095 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
7096 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7097 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7098 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7099 "with the allocation "
7100 << *UniqueFree << "\n");
7101 return false;
7102 }
7103 }
7104 return true;
7105 };
7106
7107 auto UsesCheck = [&](AllocationInfo &AI) {
7108 bool ValidUsesOnly = true;
7109
7110 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7111 Instruction *UserI = cast<Instruction>(U.getUser());
7112 if (isa<LoadInst>(UserI))
7113 return true;
7114 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7115 if (SI->getValueOperand() == U.get()) {
7117 << "[H2S] escaping store to memory: " << *UserI << "\n");
7118 ValidUsesOnly = false;
7119 } else {
7120 // A store into the malloc'ed memory is fine.
7121 }
7122 return true;
7123 }
7124 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7125 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7126 return true;
7127 if (DeallocationInfos.count(CB)) {
7128 AI.PotentialFreeCalls.insert(CB);
7129 return true;
7130 }
7131
7132 unsigned ArgNo = CB->getArgOperandNo(&U);
7133 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7134
7135 bool IsKnownNoCapture;
7136 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7137 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7138
7139 // If a call site argument use is nofree, we are fine.
7140 bool IsKnownNoFree;
7141 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7142 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7143
7144 if (!IsAssumedNoCapture ||
7145 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7146 !IsAssumedNoFree)) {
7147 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7148
7149 // Emit a missed remark if this is missed OpenMP globalization.
7150 auto Remark = [&](OptimizationRemarkMissed ORM) {
7151 return ORM
7152 << "Could not move globalized variable to the stack. "
7153 "Variable is potentially captured in call. Mark "
7154 "parameter as `__attribute__((noescape))` to override.";
7155 };
7156
7157 if (ValidUsesOnly &&
7158 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7159 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7160
7161 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7162 ValidUsesOnly = false;
7163 }
7164 return true;
7165 }
7166
7167 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7168 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7169 Follow = true;
7170 return true;
7171 }
7172 // Unknown user for which we can not track uses further (in a way that
7173 // makes sense).
7174 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7175 ValidUsesOnly = false;
7176 return true;
7177 };
7178 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7179 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7180 [&](const Use &OldU, const Use &NewU) {
7181 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7182 return !SI || StackIsAccessibleByOtherThreads ||
7183 AA::isAssumedThreadLocalObject(
7184 A, *SI->getPointerOperand(), *this);
7185 }))
7186 return false;
7187 return ValidUsesOnly;
7188 };
7189
7190 // The actual update starts here. We look at all allocations and depending on
7191 // their status perform the appropriate check(s).
7192 for (auto &It : AllocationInfos) {
7193 AllocationInfo &AI = *It.second;
7194 if (AI.Status == AllocationInfo::INVALID)
7195 continue;
7196
7197 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7198 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7199 if (!APAlign) {
7200 // Can't generate an alloca which respects the required alignment
7201 // on the allocation.
7202 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7203 << "\n");
7204 AI.Status = AllocationInfo::INVALID;
7206 continue;
7207 }
7208 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7209 !APAlign->isPowerOf2()) {
7210 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7211 << "\n");
7212 AI.Status = AllocationInfo::INVALID;
7214 continue;
7215 }
7216 }
7217
7218 std::optional<APInt> Size = getSize(A, *this, AI);
7219 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7220 MaxHeapToStackSize != -1) {
7221 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7222 LLVM_DEBUG({
7223 if (!Size)
7224 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7225 else
7226 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7227 << MaxHeapToStackSize << "\n";
7228 });
7229
7230 AI.Status = AllocationInfo::INVALID;
7232 continue;
7233 }
7234 }
7235
7236 switch (AI.Status) {
7237 case AllocationInfo::STACK_DUE_TO_USE:
7238 if (UsesCheck(AI))
7239 break;
7240 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7241 [[fallthrough]];
7242 case AllocationInfo::STACK_DUE_TO_FREE:
7243 if (FreeCheck(AI))
7244 break;
7245 AI.Status = AllocationInfo::INVALID;
7247 break;
7248 case AllocationInfo::INVALID:
7249 llvm_unreachable("Invalid allocations should never reach this point!");
7250 };
7251
7252 // Check if we still think we can move it into the entry block. If the
7253 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7254 // ignore the potential compilations associated with loops.
7255 bool IsGlobalizedLocal =
7256 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7257 if (AI.MoveAllocaIntoEntry &&
7258 (!Size.has_value() ||
7259 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7260 AI.MoveAllocaIntoEntry = false;
7261 }
7262
7263 return Changed;
7264}
7265} // namespace
7266
7267/// ----------------------- Privatizable Pointers ------------------------------
7268namespace {
7269struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7270 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7271 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7272
7273 ChangeStatus indicatePessimisticFixpoint() override {
7274 AAPrivatizablePtr::indicatePessimisticFixpoint();
7275 PrivatizableType = nullptr;
7276 return ChangeStatus::CHANGED;
7277 }
7278
7279 /// Identify the type we can chose for a private copy of the underlying
7280 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7281 /// none.
7282 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7283
7284 /// Return a privatizable type that encloses both T0 and T1.
7285 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7286 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7287 std::optional<Type *> T1) {
7288 if (!T0)
7289 return T1;
7290 if (!T1)
7291 return T0;
7292 if (T0 == T1)
7293 return T0;
7294 return nullptr;
7295 }
7296
7297 std::optional<Type *> getPrivatizableType() const override {
7298 return PrivatizableType;
7299 }
7300
7301 const std::string getAsStr(Attributor *A) const override {
7302 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7303 }
7304
7305protected:
7306 std::optional<Type *> PrivatizableType;
7307};
7308
7309// TODO: Do this for call site arguments (probably also other values) as well.
7310
7311struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7312 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7313 : AAPrivatizablePtrImpl(IRP, A) {}
7314
7315 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7316 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7317 // If this is a byval argument and we know all the call sites (so we can
7318 // rewrite them), there is no need to check them explicitly.
7319 bool UsedAssumedInformation = false;
7321 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7322 /* IgnoreSubsumingPositions */ true);
7323 if (!Attrs.empty() &&
7324 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7325 true, UsedAssumedInformation))
7326 return Attrs[0].getValueAsType();
7327
7328 std::optional<Type *> Ty;
7329 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7330
7331 // Make sure the associated call site argument has the same type at all call
7332 // sites and it is an allocation we know is safe to privatize, for now that
7333 // means we only allow alloca instructions.
7334 // TODO: We can additionally analyze the accesses in the callee to create
7335 // the type from that information instead. That is a little more
7336 // involved and will be done in a follow up patch.
7337 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7338 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7339 // Check if a coresponding argument was found or if it is one not
7340 // associated (which can happen for callback calls).
7341 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7342 return false;
7343
7344 // Check that all call sites agree on a type.
7345 auto *PrivCSArgAA =
7346 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7347 if (!PrivCSArgAA)
7348 return false;
7349 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7350
7351 LLVM_DEBUG({
7352 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7353 if (CSTy && *CSTy)
7354 (*CSTy)->print(dbgs());
7355 else if (CSTy)
7356 dbgs() << "<nullptr>";
7357 else
7358 dbgs() << "<none>";
7359 });
7360
7361 Ty = combineTypes(Ty, CSTy);
7362
7363 LLVM_DEBUG({
7364 dbgs() << " : New Type: ";
7365 if (Ty && *Ty)
7366 (*Ty)->print(dbgs());
7367 else if (Ty)
7368 dbgs() << "<nullptr>";
7369 else
7370 dbgs() << "<none>";
7371 dbgs() << "\n";
7372 });
7373
7374 return !Ty || *Ty;
7375 };
7376
7377 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7378 UsedAssumedInformation))
7379 return nullptr;
7380 return Ty;
7381 }
7382
7383 /// See AbstractAttribute::updateImpl(...).
7384 ChangeStatus updateImpl(Attributor &A) override {
7385 PrivatizableType = identifyPrivatizableType(A);
7386 if (!PrivatizableType)
7387 return ChangeStatus::UNCHANGED;
7388 if (!*PrivatizableType)
7389 return indicatePessimisticFixpoint();
7390
7391 // The dependence is optional so we don't give up once we give up on the
7392 // alignment.
7393 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7394 DepClassTy::OPTIONAL);
7395
7396 // Avoid arguments with padding for now.
7397 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7398 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7399 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7400 return indicatePessimisticFixpoint();
7401 }
7402
7403 // Collect the types that will replace the privatizable type in the function
7404 // signature.
7405 SmallVector<Type *, 16> ReplacementTypes;
7406 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7407
7408 // Verify callee and caller agree on how the promoted argument would be
7409 // passed.
7410 Function &Fn = *getIRPosition().getAnchorScope();
7411 const auto *TTI =
7412 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7413 if (!TTI) {
7414 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7415 << Fn.getName() << "\n");
7416 return indicatePessimisticFixpoint();
7417 }
7418
7419 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7420 CallBase *CB = ACS.getInstruction();
7421 return TTI->areTypesABICompatible(
7422 CB->getCaller(),
7424 ReplacementTypes);
7425 };
7426 bool UsedAssumedInformation = false;
7427 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7428 UsedAssumedInformation)) {
7429 LLVM_DEBUG(
7430 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7431 << Fn.getName() << "\n");
7432 return indicatePessimisticFixpoint();
7433 }
7434
7435 // Register a rewrite of the argument.
7436 Argument *Arg = getAssociatedArgument();
7437 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7438 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7439 return indicatePessimisticFixpoint();
7440 }
7441
7442 unsigned ArgNo = Arg->getArgNo();
7443
7444 // Helper to check if for the given call site the associated argument is
7445 // passed to a callback where the privatization would be different.
7446 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7447 SmallVector<const Use *, 4> CallbackUses;
7448 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7449 for (const Use *U : CallbackUses) {
7450 AbstractCallSite CBACS(U);
7451 assert(CBACS && CBACS.isCallbackCall());
7452 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7453 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7454
7455 LLVM_DEBUG({
7456 dbgs()
7457 << "[AAPrivatizablePtr] Argument " << *Arg
7458 << "check if can be privatized in the context of its parent ("
7459 << Arg->getParent()->getName()
7460 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7461 "callback ("
7462 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7463 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7464 << CBACS.getCallArgOperand(CBArg) << " vs "
7465 << CB.getArgOperand(ArgNo) << "\n"
7466 << "[AAPrivatizablePtr] " << CBArg << " : "
7467 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7468 });
7469
7470 if (CBArgNo != int(ArgNo))
7471 continue;
7472 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7473 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7474 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7475 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7476 if (!CBArgPrivTy)
7477 continue;
7478 if (*CBArgPrivTy == PrivatizableType)
7479 continue;
7480 }
7481
7482 LLVM_DEBUG({
7483 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7484 << " cannot be privatized in the context of its parent ("
7485 << Arg->getParent()->getName()
7486 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7487 "callback ("
7488 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7489 << ").\n[AAPrivatizablePtr] for which the argument "
7490 "privatization is not compatible.\n";
7491 });
7492 return false;
7493 }
7494 }
7495 return true;
7496 };
7497
7498 // Helper to check if for the given call site the associated argument is
7499 // passed to a direct call where the privatization would be different.
7500 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7501 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7502 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7503 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7504 "Expected a direct call operand for callback call operand");
7505
7506 Function *DCCallee =
7508 LLVM_DEBUG({
7509 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7510 << " check if be privatized in the context of its parent ("
7511 << Arg->getParent()->getName()
7512 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7513 "direct call of ("
7514 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7515 });
7516
7517 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7518 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7519 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7520 DepClassTy::REQUIRED);
7521 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7522 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7523 if (!DCArgPrivTy)
7524 return true;
7525 if (*DCArgPrivTy == PrivatizableType)
7526 return true;
7527 }
7528 }
7529
7530 LLVM_DEBUG({
7531 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7532 << " cannot be privatized in the context of its parent ("
7533 << Arg->getParent()->getName()
7534 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7535 "direct call of ("
7537 << ").\n[AAPrivatizablePtr] for which the argument "
7538 "privatization is not compatible.\n";
7539 });
7540 return false;
7541 };
7542
7543 // Helper to check if the associated argument is used at the given abstract
7544 // call site in a way that is incompatible with the privatization assumed
7545 // here.
7546 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7547 if (ACS.isDirectCall())
7548 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7549 if (ACS.isCallbackCall())
7550 return IsCompatiblePrivArgOfDirectCS(ACS);
7551 return false;
7552 };
7553
7554 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7555 UsedAssumedInformation))
7556 return indicatePessimisticFixpoint();
7557
7558 return ChangeStatus::UNCHANGED;
7559 }
7560
7561 /// Given a type to private \p PrivType, collect the constituates (which are
7562 /// used) in \p ReplacementTypes.
7563 static void
7564 identifyReplacementTypes(Type *PrivType,
7565 SmallVectorImpl<Type *> &ReplacementTypes) {
7566 // TODO: For now we expand the privatization type to the fullest which can
7567 // lead to dead arguments that need to be removed later.
7568 assert(PrivType && "Expected privatizable type!");
7569
7570 // Traverse the type, extract constituate types on the outermost level.
7571 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7572 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7573 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7574 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7575 ReplacementTypes.append(PrivArrayType->getNumElements(),
7576 PrivArrayType->getElementType());
7577 } else {
7578 ReplacementTypes.push_back(PrivType);
7579 }
7580 }
7581
7582 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7583 /// The values needed are taken from the arguments of \p F starting at
7584 /// position \p ArgNo.
7585 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7586 unsigned ArgNo, BasicBlock::iterator IP) {
7587 assert(PrivType && "Expected privatizable type!");
7588
7589 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7590 const DataLayout &DL = F.getDataLayout();
7591
7592 // Traverse the type, build GEPs and stores.
7593 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7594 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7595 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7596 Value *Ptr =
7597 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7598 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7599 }
7600 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7601 Type *PointeeTy = PrivArrayType->getElementType();
7602 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7603 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7604 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7605 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7606 }
7607 } else {
7608 new StoreInst(F.getArg(ArgNo), &Base, IP);
7609 }
7610 }
7611
7612 /// Extract values from \p Base according to the type \p PrivType at the
7613 /// call position \p ACS. The values are appended to \p ReplacementValues.
7614 void createReplacementValues(Align Alignment, Type *PrivType,
7615 AbstractCallSite ACS, Value *Base,
7616 SmallVectorImpl<Value *> &ReplacementValues) {
7617 assert(Base && "Expected base value!");
7618 assert(PrivType && "Expected privatizable type!");
7619 Instruction *IP = ACS.getInstruction();
7620
7621 IRBuilder<NoFolder> IRB(IP);
7622 const DataLayout &DL = IP->getDataLayout();
7623
7624 // Traverse the type, build GEPs and loads.
7625 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7626 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7627 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7628 Type *PointeeTy = PrivStructType->getElementType(u);
7629 Value *Ptr =
7630 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7631 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7632 L->setAlignment(Alignment);
7633 ReplacementValues.push_back(L);
7634 }
7635 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7636 Type *PointeeTy = PrivArrayType->getElementType();
7637 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7638 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7639 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7640 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7641 L->setAlignment(Alignment);
7642 ReplacementValues.push_back(L);
7643 }
7644 } else {
7645 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7646 L->setAlignment(Alignment);
7647 ReplacementValues.push_back(L);
7648 }
7649 }
7650
7651 /// See AbstractAttribute::manifest(...)
7652 ChangeStatus manifest(Attributor &A) override {
7653 if (!PrivatizableType)
7654 return ChangeStatus::UNCHANGED;
7655 assert(*PrivatizableType && "Expected privatizable type!");
7656
7657 // Collect all tail calls in the function as we cannot allow new allocas to
7658 // escape into tail recursion.
7659 // TODO: Be smarter about new allocas escaping into tail calls.
7661 bool UsedAssumedInformation = false;
7662 if (!A.checkForAllInstructions(
7663 [&](Instruction &I) {
7664 CallInst &CI = cast<CallInst>(I);
7665 if (CI.isTailCall())
7666 TailCalls.push_back(&CI);
7667 return true;
7668 },
7669 *this, {Instruction::Call}, UsedAssumedInformation))
7670 return ChangeStatus::UNCHANGED;
7671
7672 Argument *Arg = getAssociatedArgument();
7673 // Query AAAlign attribute for alignment of associated argument to
7674 // determine the best alignment of loads.
7675 const auto *AlignAA =
7676 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7677
7678 // Callback to repair the associated function. A new alloca is placed at the
7679 // beginning and initialized with the values passed through arguments. The
7680 // new alloca replaces the use of the old pointer argument.
7682 [=](const Attributor::ArgumentReplacementInfo &ARI,
7683 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7684 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7686 const DataLayout &DL = IP->getDataLayout();
7687 unsigned AS = DL.getAllocaAddrSpace();
7688 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7689 Arg->getName() + ".priv", IP);
7690 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7691 ArgIt->getArgNo(), IP);
7692
7693 if (AI->getType() != Arg->getType())
7694 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7695 AI, Arg->getType(), "", IP);
7696 Arg->replaceAllUsesWith(AI);
7697
7698 for (CallInst *CI : TailCalls)
7699 CI->setTailCall(false);
7700 };
7701
7702 // Callback to repair a call site of the associated function. The elements
7703 // of the privatizable type are loaded prior to the call and passed to the
7704 // new function version.
7706 [=](const Attributor::ArgumentReplacementInfo &ARI,
7707 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7708 // When no alignment is specified for the load instruction,
7709 // natural alignment is assumed.
7710 createReplacementValues(
7711 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7712 *PrivatizableType, ACS,
7713 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7714 NewArgOperands);
7715 };
7716
7717 // Collect the types that will replace the privatizable type in the function
7718 // signature.
7719 SmallVector<Type *, 16> ReplacementTypes;
7720 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7721
7722 // Register a rewrite of the argument.
7723 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7724 std::move(FnRepairCB),
7725 std::move(ACSRepairCB)))
7726 return ChangeStatus::CHANGED;
7727 return ChangeStatus::UNCHANGED;
7728 }
7729
7730 /// See AbstractAttribute::trackStatistics()
7731 void trackStatistics() const override {
7732 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7733 }
7734};
7735
7736struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7737 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7738 : AAPrivatizablePtrImpl(IRP, A) {}
7739
7740 /// See AbstractAttribute::initialize(...).
7741 void initialize(Attributor &A) override {
7742 // TODO: We can privatize more than arguments.
7743 indicatePessimisticFixpoint();
7744 }
7745
7746 ChangeStatus updateImpl(Attributor &A) override {
7747 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7748 "updateImpl will not be called");
7749 }
7750
7751 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7752 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7753 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7754 if (!Obj) {
7755 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7756 return nullptr;
7757 }
7758
7759 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7760 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7761 if (CI->isOne())
7762 return AI->getAllocatedType();
7763 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7764 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7765 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7766 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7767 return PrivArgAA->getPrivatizableType();
7768 }
7769
7770 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7771 "alloca nor privatizable argument: "
7772 << *Obj << "!\n");
7773 return nullptr;
7774 }
7775
7776 /// See AbstractAttribute::trackStatistics()
7777 void trackStatistics() const override {
7778 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7779 }
7780};
7781
7782struct AAPrivatizablePtrCallSiteArgument final
7783 : public AAPrivatizablePtrFloating {
7784 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7785 : AAPrivatizablePtrFloating(IRP, A) {}
7786
7787 /// See AbstractAttribute::initialize(...).
7788 void initialize(Attributor &A) override {
7789 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7790 indicateOptimisticFixpoint();
7791 }
7792
7793 /// See AbstractAttribute::updateImpl(...).
7794 ChangeStatus updateImpl(Attributor &A) override {
7795 PrivatizableType = identifyPrivatizableType(A);
7796 if (!PrivatizableType)
7797 return ChangeStatus::UNCHANGED;
7798 if (!*PrivatizableType)
7799 return indicatePessimisticFixpoint();
7800
7801 const IRPosition &IRP = getIRPosition();
7802 bool IsKnownNoCapture;
7803 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7804 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7805 if (!IsAssumedNoCapture) {
7806 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7807 return indicatePessimisticFixpoint();
7808 }
7809
7810 bool IsKnownNoAlias;
7812 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7813 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7814 return indicatePessimisticFixpoint();
7815 }
7816
7817 bool IsKnown;
7818 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7819 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7820 return indicatePessimisticFixpoint();
7821 }
7822
7823 return ChangeStatus::UNCHANGED;
7824 }
7825
7826 /// See AbstractAttribute::trackStatistics()
7827 void trackStatistics() const override {
7828 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7829 }
7830};
7831
7832struct AAPrivatizablePtrCallSiteReturned final
7833 : public AAPrivatizablePtrFloating {
7834 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7835 : AAPrivatizablePtrFloating(IRP, A) {}
7836
7837 /// See AbstractAttribute::initialize(...).
7838 void initialize(Attributor &A) override {
7839 // TODO: We can privatize more than arguments.
7840 indicatePessimisticFixpoint();
7841 }
7842
7843 /// See AbstractAttribute::trackStatistics()
7844 void trackStatistics() const override {
7845 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7846 }
7847};
7848
7849struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7850 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7851 : AAPrivatizablePtrFloating(IRP, A) {}
7852
7853 /// See AbstractAttribute::initialize(...).
7854 void initialize(Attributor &A) override {
7855 // TODO: We can privatize more than arguments.
7856 indicatePessimisticFixpoint();
7857 }
7858
7859 /// See AbstractAttribute::trackStatistics()
7860 void trackStatistics() const override {
7861 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7862 }
7863};
7864} // namespace
7865
7866/// -------------------- Memory Behavior Attributes ----------------------------
7867/// Includes read-none, read-only, and write-only.
7868/// ----------------------------------------------------------------------------
7869namespace {
7870struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7871 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7872 : AAMemoryBehavior(IRP, A) {}
7873
7874 /// See AbstractAttribute::initialize(...).
7875 void initialize(Attributor &A) override {
7876 intersectAssumedBits(BEST_STATE);
7877 getKnownStateFromValue(A, getIRPosition(), getState());
7878 AAMemoryBehavior::initialize(A);
7879 }
7880
7881 /// Return the memory behavior information encoded in the IR for \p IRP.
7882 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7883 BitIntegerState &State,
7884 bool IgnoreSubsumingPositions = false) {
7886 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7887 for (const Attribute &Attr : Attrs) {
7888 switch (Attr.getKindAsEnum()) {
7889 case Attribute::ReadNone:
7890 State.addKnownBits(NO_ACCESSES);
7891 break;
7892 case Attribute::ReadOnly:
7893 State.addKnownBits(NO_WRITES);
7894 break;
7895 case Attribute::WriteOnly:
7896 State.addKnownBits(NO_READS);
7897 break;
7898 default:
7899 llvm_unreachable("Unexpected attribute!");
7900 }
7901 }
7902
7903 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7904 if (!I->mayReadFromMemory())
7905 State.addKnownBits(NO_READS);
7906 if (!I->mayWriteToMemory())
7907 State.addKnownBits(NO_WRITES);
7908 }
7909 }
7910
7911 /// See AbstractAttribute::getDeducedAttributes(...).
7912 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7913 SmallVectorImpl<Attribute> &Attrs) const override {
7914 assert(Attrs.size() == 0);
7915 if (isAssumedReadNone())
7916 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7917 else if (isAssumedReadOnly())
7918 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7919 else if (isAssumedWriteOnly())
7920 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7921 assert(Attrs.size() <= 1);
7922 }
7923
7924 /// See AbstractAttribute::manifest(...).
7925 ChangeStatus manifest(Attributor &A) override {
7926 const IRPosition &IRP = getIRPosition();
7927
7928 if (A.hasAttr(IRP, Attribute::ReadNone,
7929 /* IgnoreSubsumingPositions */ true))
7930 return ChangeStatus::UNCHANGED;
7931
7932 // Check if we would improve the existing attributes first.
7933 SmallVector<Attribute, 4> DeducedAttrs;
7934 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7935 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7936 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7937 /* IgnoreSubsumingPositions */ true);
7938 }))
7939 return ChangeStatus::UNCHANGED;
7940
7941 // Clear existing attributes.
7942 A.removeAttrs(IRP, AttrKinds);
7943 // Clear conflicting writable attribute.
7944 if (isAssumedReadOnly())
7945 A.removeAttrs(IRP, Attribute::Writable);
7946
7947 // Use the generic manifest method.
7948 return IRAttribute::manifest(A);
7949 }
7950
7951 /// See AbstractState::getAsStr().
7952 const std::string getAsStr(Attributor *A) const override {
7953 if (isAssumedReadNone())
7954 return "readnone";
7955 if (isAssumedReadOnly())
7956 return "readonly";
7957 if (isAssumedWriteOnly())
7958 return "writeonly";
7959 return "may-read/write";
7960 }
7961
7962 /// The set of IR attributes AAMemoryBehavior deals with.
7963 static const Attribute::AttrKind AttrKinds[3];
7964};
7965
7966const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7967 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7968
7969/// Memory behavior attribute for a floating value.
7970struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7971 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7972 : AAMemoryBehaviorImpl(IRP, A) {}
7973
7974 /// See AbstractAttribute::updateImpl(...).
7975 ChangeStatus updateImpl(Attributor &A) override;
7976
7977 /// See AbstractAttribute::trackStatistics()
7978 void trackStatistics() const override {
7979 if (isAssumedReadNone())
7981 else if (isAssumedReadOnly())
7983 else if (isAssumedWriteOnly())
7985 }
7986
7987private:
7988 /// Return true if users of \p UserI might access the underlying
7989 /// variable/location described by \p U and should therefore be analyzed.
7990 bool followUsersOfUseIn(Attributor &A, const Use &U,
7991 const Instruction *UserI);
7992
7993 /// Update the state according to the effect of use \p U in \p UserI.
7994 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7995};
7996
7997/// Memory behavior attribute for function argument.
7998struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7999 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8000 : AAMemoryBehaviorFloating(IRP, A) {}
8001
8002 /// See AbstractAttribute::initialize(...).
8003 void initialize(Attributor &A) override {
8004 intersectAssumedBits(BEST_STATE);
8005 const IRPosition &IRP = getIRPosition();
8006 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8007 // can query it when we use has/getAttr. That would allow us to reuse the
8008 // initialize of the base class here.
8009 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8010 /* IgnoreSubsumingPositions */ true);
8011 getKnownStateFromValue(A, IRP, getState(),
8012 /* IgnoreSubsumingPositions */ HasByVal);
8013 }
8014
8015 ChangeStatus manifest(Attributor &A) override {
8016 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8017 if (!getAssociatedValue().getType()->isPointerTy())
8018 return ChangeStatus::UNCHANGED;
8019
8020 // TODO: From readattrs.ll: "inalloca parameters are always
8021 // considered written"
8022 if (A.hasAttr(getIRPosition(),
8023 {Attribute::InAlloca, Attribute::Preallocated})) {
8024 removeKnownBits(NO_WRITES);
8025 removeAssumedBits(NO_WRITES);
8026 }
8027 A.removeAttrs(getIRPosition(), AttrKinds);
8028 return AAMemoryBehaviorFloating::manifest(A);
8029 }
8030
8031 /// See AbstractAttribute::trackStatistics()
8032 void trackStatistics() const override {
8033 if (isAssumedReadNone())
8034 STATS_DECLTRACK_ARG_ATTR(readnone)
8035 else if (isAssumedReadOnly())
8036 STATS_DECLTRACK_ARG_ATTR(readonly)
8037 else if (isAssumedWriteOnly())
8038 STATS_DECLTRACK_ARG_ATTR(writeonly)
8039 }
8040};
8041
8042struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8043 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8044 : AAMemoryBehaviorArgument(IRP, A) {}
8045
8046 /// See AbstractAttribute::initialize(...).
8047 void initialize(Attributor &A) override {
8048 // If we don't have an associated attribute this is either a variadic call
8049 // or an indirect call, either way, nothing to do here.
8050 Argument *Arg = getAssociatedArgument();
8051 if (!Arg) {
8052 indicatePessimisticFixpoint();
8053 return;
8054 }
8055 if (Arg->hasByValAttr()) {
8056 addKnownBits(NO_WRITES);
8057 removeKnownBits(NO_READS);
8058 removeAssumedBits(NO_READS);
8059 }
8060 AAMemoryBehaviorArgument::initialize(A);
8061 if (getAssociatedFunction()->isDeclaration())
8062 indicatePessimisticFixpoint();
8063 }
8064
8065 /// See AbstractAttribute::updateImpl(...).
8066 ChangeStatus updateImpl(Attributor &A) override {
8067 // TODO: Once we have call site specific value information we can provide
8068 // call site specific liveness liveness information and then it makes
8069 // sense to specialize attributes for call sites arguments instead of
8070 // redirecting requests to the callee argument.
8071 Argument *Arg = getAssociatedArgument();
8072 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8073 auto *ArgAA =
8074 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8075 if (!ArgAA)
8076 return indicatePessimisticFixpoint();
8077 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8078 }
8079
8080 /// See AbstractAttribute::trackStatistics()
8081 void trackStatistics() const override {
8082 if (isAssumedReadNone())
8084 else if (isAssumedReadOnly())
8086 else if (isAssumedWriteOnly())
8088 }
8089};
8090
8091/// Memory behavior attribute for a call site return position.
8092struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8093 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8094 : AAMemoryBehaviorFloating(IRP, A) {}
8095
8096 /// See AbstractAttribute::initialize(...).
8097 void initialize(Attributor &A) override {
8098 AAMemoryBehaviorImpl::initialize(A);
8099 }
8100 /// See AbstractAttribute::manifest(...).
8101 ChangeStatus manifest(Attributor &A) override {
8102 // We do not annotate returned values.
8103 return ChangeStatus::UNCHANGED;
8104 }
8105
8106 /// See AbstractAttribute::trackStatistics()
8107 void trackStatistics() const override {}
8108};
8109
8110/// An AA to represent the memory behavior function attributes.
8111struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8112 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8113 : AAMemoryBehaviorImpl(IRP, A) {}
8114
8115 /// See AbstractAttribute::updateImpl(Attributor &A).
8116 ChangeStatus updateImpl(Attributor &A) override;
8117
8118 /// See AbstractAttribute::manifest(...).
8119 ChangeStatus manifest(Attributor &A) override {
8120 // TODO: It would be better to merge this with AAMemoryLocation, so that
8121 // we could determine read/write per location. This would also have the
8122 // benefit of only one place trying to manifest the memory attribute.
8123 Function &F = cast<Function>(getAnchorValue());
8125 if (isAssumedReadNone())
8126 ME = MemoryEffects::none();
8127 else if (isAssumedReadOnly())
8129 else if (isAssumedWriteOnly())
8131
8132 A.removeAttrs(getIRPosition(), AttrKinds);
8133 // Clear conflicting writable attribute.
8134 if (ME.onlyReadsMemory())
8135 for (Argument &Arg : F.args())
8136 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8137 return A.manifestAttrs(getIRPosition(),
8138 Attribute::getWithMemoryEffects(F.getContext(), ME));
8139 }
8140
8141 /// See AbstractAttribute::trackStatistics()
8142 void trackStatistics() const override {
8143 if (isAssumedReadNone())
8144 STATS_DECLTRACK_FN_ATTR(readnone)
8145 else if (isAssumedReadOnly())
8146 STATS_DECLTRACK_FN_ATTR(readonly)
8147 else if (isAssumedWriteOnly())
8148 STATS_DECLTRACK_FN_ATTR(writeonly)
8149 }
8150};
8151
8152/// AAMemoryBehavior attribute for call sites.
8153struct AAMemoryBehaviorCallSite final
8154 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8155 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8156 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8157
8158 /// See AbstractAttribute::manifest(...).
8159 ChangeStatus manifest(Attributor &A) override {
8160 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8161 CallBase &CB = cast<CallBase>(getAnchorValue());
8163 if (isAssumedReadNone())
8164 ME = MemoryEffects::none();
8165 else if (isAssumedReadOnly())
8167 else if (isAssumedWriteOnly())
8169
8170 A.removeAttrs(getIRPosition(), AttrKinds);
8171 // Clear conflicting writable attribute.
8172 if (ME.onlyReadsMemory())
8173 for (Use &U : CB.args())
8174 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8175 Attribute::Writable);
8176 return A.manifestAttrs(
8177 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8178 }
8179
8180 /// See AbstractAttribute::trackStatistics()
8181 void trackStatistics() const override {
8182 if (isAssumedReadNone())
8183 STATS_DECLTRACK_CS_ATTR(readnone)
8184 else if (isAssumedReadOnly())
8185 STATS_DECLTRACK_CS_ATTR(readonly)
8186 else if (isAssumedWriteOnly())
8187 STATS_DECLTRACK_CS_ATTR(writeonly)
8188 }
8189};
8190
8191ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8192
8193 // The current assumed state used to determine a change.
8194 auto AssumedState = getAssumed();
8195
8196 auto CheckRWInst = [&](Instruction &I) {
8197 // If the instruction has an own memory behavior state, use it to restrict
8198 // the local state. No further analysis is required as the other memory
8199 // state is as optimistic as it gets.
8200 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8201 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8203 if (MemBehaviorAA) {
8204 intersectAssumedBits(MemBehaviorAA->getAssumed());
8205 return !isAtFixpoint();
8206 }
8207 }
8208
8209 // Remove access kind modifiers if necessary.
8210 if (I.mayReadFromMemory())
8211 removeAssumedBits(NO_READS);
8212 if (I.mayWriteToMemory())
8213 removeAssumedBits(NO_WRITES);
8214 return !isAtFixpoint();
8215 };
8216
8217 bool UsedAssumedInformation = false;
8218 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8219 UsedAssumedInformation))
8220 return indicatePessimisticFixpoint();
8221
8222 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8224}
8225
8226ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8227
8228 const IRPosition &IRP = getIRPosition();
8229 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8230 AAMemoryBehavior::StateType &S = getState();
8231
8232 // First, check the function scope. We take the known information and we avoid
8233 // work if the assumed information implies the current assumed information for
8234 // this attribute. This is a valid for all but byval arguments.
8235 Argument *Arg = IRP.getAssociatedArgument();
8236 AAMemoryBehavior::base_t FnMemAssumedState =
8238 if (!Arg || !Arg->hasByValAttr()) {
8239 const auto *FnMemAA =
8240 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8241 if (FnMemAA) {
8242 FnMemAssumedState = FnMemAA->getAssumed();
8243 S.addKnownBits(FnMemAA->getKnown());
8244 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8246 }
8247 }
8248
8249 // The current assumed state used to determine a change.
8250 auto AssumedState = S.getAssumed();
8251
8252 // Make sure the value is not captured (except through "return"), if
8253 // it is, any information derived would be irrelevant anyway as we cannot
8254 // check the potential aliases introduced by the capture. However, no need
8255 // to fall back to anythign less optimistic than the function state.
8256 bool IsKnownNoCapture;
8257 const AANoCapture *ArgNoCaptureAA = nullptr;
8258 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8259 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8260 &ArgNoCaptureAA);
8261
8262 if (!IsAssumedNoCapture &&
8263 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8264 S.intersectAssumedBits(FnMemAssumedState);
8265 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8267 }
8268
8269 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8270 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8271 Instruction *UserI = cast<Instruction>(U.getUser());
8272 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8273 << " \n");
8274
8275 // Droppable users, e.g., llvm::assume does not actually perform any action.
8276 if (UserI->isDroppable())
8277 return true;
8278
8279 // Check if the users of UserI should also be visited.
8280 Follow = followUsersOfUseIn(A, U, UserI);
8281
8282 // If UserI might touch memory we analyze the use in detail.
8283 if (UserI->mayReadOrWriteMemory())
8284 analyzeUseIn(A, U, UserI);
8285
8286 return !isAtFixpoint();
8287 };
8288
8289 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8290 return indicatePessimisticFixpoint();
8291
8292 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8294}
8295
8296bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8297 const Instruction *UserI) {
8298 // The loaded value is unrelated to the pointer argument, no need to
8299 // follow the users of the load.
8300 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8301 return false;
8302
8303 // By default we follow all uses assuming UserI might leak information on U,
8304 // we have special handling for call sites operands though.
8305 const auto *CB = dyn_cast<CallBase>(UserI);
8306 if (!CB || !CB->isArgOperand(&U))
8307 return true;
8308
8309 // If the use is a call argument known not to be captured, the users of
8310 // the call do not need to be visited because they have to be unrelated to
8311 // the input. Note that this check is not trivial even though we disallow
8312 // general capturing of the underlying argument. The reason is that the
8313 // call might the argument "through return", which we allow and for which we
8314 // need to check call users.
8315 if (U.get()->getType()->isPointerTy()) {
8316 unsigned ArgNo = CB->getArgOperandNo(&U);
8317 bool IsKnownNoCapture;
8319 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8320 DepClassTy::OPTIONAL, IsKnownNoCapture);
8321 }
8322
8323 return true;
8324}
8325
8326void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8327 const Instruction *UserI) {
8328 assert(UserI->mayReadOrWriteMemory());
8329
8330 switch (UserI->getOpcode()) {
8331 default:
8332 // TODO: Handle all atomics and other side-effect operations we know of.
8333 break;
8334 case Instruction::Load:
8335 // Loads cause the NO_READS property to disappear.
8336 removeAssumedBits(NO_READS);
8337 return;
8338
8339 case Instruction::Store:
8340 // Stores cause the NO_WRITES property to disappear if the use is the
8341 // pointer operand. Note that while capturing was taken care of somewhere
8342 // else we need to deal with stores of the value that is not looked through.
8343 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8344 removeAssumedBits(NO_WRITES);
8345 else
8346 indicatePessimisticFixpoint();
8347 return;
8348
8349 case Instruction::Call:
8350 case Instruction::CallBr:
8351 case Instruction::Invoke: {
8352 // For call sites we look at the argument memory behavior attribute (this
8353 // could be recursive!) in order to restrict our own state.
8354 const auto *CB = cast<CallBase>(UserI);
8355
8356 // Give up on operand bundles.
8357 if (CB->isBundleOperand(&U)) {
8358 indicatePessimisticFixpoint();
8359 return;
8360 }
8361
8362 // Calling a function does read the function pointer, maybe write it if the
8363 // function is self-modifying.
8364 if (CB->isCallee(&U)) {
8365 removeAssumedBits(NO_READS);
8366 break;
8367 }
8368
8369 // Adjust the possible access behavior based on the information on the
8370 // argument.
8371 IRPosition Pos;
8372 if (U.get()->getType()->isPointerTy())
8374 else
8376 const auto *MemBehaviorAA =
8377 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8378 if (!MemBehaviorAA)
8379 break;
8380 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8381 // and at least "known".
8382 intersectAssumedBits(MemBehaviorAA->getAssumed());
8383 return;
8384 }
8385 };
8386
8387 // Generally, look at the "may-properties" and adjust the assumed state if we
8388 // did not trigger special handling before.
8389 if (UserI->mayReadFromMemory())
8390 removeAssumedBits(NO_READS);
8391 if (UserI->mayWriteToMemory())
8392 removeAssumedBits(NO_WRITES);
8393}
8394} // namespace
8395
8396/// -------------------- Memory Locations Attributes ---------------------------
8397/// Includes read-none, argmemonly, inaccessiblememonly,
8398/// inaccessiblememorargmemonly
8399/// ----------------------------------------------------------------------------
8400
8403 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8404 return "all memory";
8406 return "no memory";
8407 std::string S = "memory:";
8408 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8409 S += "stack,";
8410 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8411 S += "constant,";
8413 S += "internal global,";
8415 S += "external global,";
8416 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8417 S += "argument,";
8419 S += "inaccessible,";
8420 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8421 S += "malloced,";
8422 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8423 S += "unknown,";
8424 S.pop_back();
8425 return S;
8426}
8427
8428namespace {
8429struct AAMemoryLocationImpl : public AAMemoryLocation {
8430
8431 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8432 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8433 AccessKind2Accesses.fill(nullptr);
8434 }
8435
8436 ~AAMemoryLocationImpl() override {
8437 // The AccessSets are allocated via a BumpPtrAllocator, we call
8438 // the destructor manually.
8439 for (AccessSet *AS : AccessKind2Accesses)
8440 if (AS)
8441 AS->~AccessSet();
8442 }
8443
8444 /// See AbstractAttribute::initialize(...).
8445 void initialize(Attributor &A) override {
8446 intersectAssumedBits(BEST_STATE);
8447 getKnownStateFromValue(A, getIRPosition(), getState());
8448 AAMemoryLocation::initialize(A);
8449 }
8450
8451 /// Return the memory behavior information encoded in the IR for \p IRP.
8452 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8453 BitIntegerState &State,
8454 bool IgnoreSubsumingPositions = false) {
8455 // For internal functions we ignore `argmemonly` and
8456 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8457 // constant propagation. It is unclear if this is the best way but it is
8458 // unlikely this will cause real performance problems. If we are deriving
8459 // attributes for the anchor function we even remove the attribute in
8460 // addition to ignoring it.
8461 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8462 // MemoryEffects::Other as a possible location.
8463 bool UseArgMemOnly = true;
8464 Function *AnchorFn = IRP.getAnchorScope();
8465 if (AnchorFn && A.isRunOn(*AnchorFn))
8466 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8467
8469 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8470 for (const Attribute &Attr : Attrs) {
8471 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8472 MemoryEffects ME = Attr.getMemoryEffects();
8473 if (ME.doesNotAccessMemory()) {
8474 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8475 continue;
8476 }
8477 if (ME.onlyAccessesInaccessibleMem()) {
8478 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8479 continue;
8480 }
8481 if (ME.onlyAccessesArgPointees()) {
8482 if (UseArgMemOnly)
8483 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8484 else {
8485 // Remove location information, only keep read/write info.
8486 ME = MemoryEffects(ME.getModRef());
8487 A.manifestAttrs(IRP,
8488 Attribute::getWithMemoryEffects(
8489 IRP.getAnchorValue().getContext(), ME),
8490 /*ForceReplace*/ true);
8491 }
8492 continue;
8493 }
8495 if (UseArgMemOnly)
8496 State.addKnownBits(inverseLocation(
8497 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8498 else {
8499 // Remove location information, only keep read/write info.
8500 ME = MemoryEffects(ME.getModRef());
8501 A.manifestAttrs(IRP,
8502 Attribute::getWithMemoryEffects(
8503 IRP.getAnchorValue().getContext(), ME),
8504 /*ForceReplace*/ true);
8505 }
8506 continue;
8507 }
8508 }
8509 }
8510
8511 /// See AbstractAttribute::getDeducedAttributes(...).
8512 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8513 SmallVectorImpl<Attribute> &Attrs) const override {
8514 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8515 assert(Attrs.size() == 0);
8516 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8517 if (isAssumedReadNone())
8518 Attrs.push_back(
8519 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8520 else if (isAssumedInaccessibleMemOnly())
8521 Attrs.push_back(Attribute::getWithMemoryEffects(
8523 else if (isAssumedArgMemOnly())
8524 Attrs.push_back(
8525 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8526 else if (isAssumedInaccessibleOrArgMemOnly())
8527 Attrs.push_back(Attribute::getWithMemoryEffects(
8529 }
8530 assert(Attrs.size() <= 1);
8531 }
8532
8533 /// See AbstractAttribute::manifest(...).
8534 ChangeStatus manifest(Attributor &A) override {
8535 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8536 // provide per-location modref information here.
8537 const IRPosition &IRP = getIRPosition();
8538
8539 SmallVector<Attribute, 1> DeducedAttrs;
8540 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8541 if (DeducedAttrs.size() != 1)
8542 return ChangeStatus::UNCHANGED;
8543 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8544
8545 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8546 IRP.getAnchorValue().getContext(), ME));
8547 }
8548
8549 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8550 bool checkForAllAccessesToMemoryKind(
8551 function_ref<bool(const Instruction *, const Value *, AccessKind,
8552 MemoryLocationsKind)>
8553 Pred,
8554 MemoryLocationsKind RequestedMLK) const override {
8555 if (!isValidState())
8556 return false;
8557
8558 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8559 if (AssumedMLK == NO_LOCATIONS)
8560 return true;
8561
8562 unsigned Idx = 0;
8563 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8564 CurMLK *= 2, ++Idx) {
8565 if (CurMLK & RequestedMLK)
8566 continue;
8567
8568 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8569 for (const AccessInfo &AI : *Accesses)
8570 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8571 return false;
8572 }
8573
8574 return true;
8575 }
8576
8577 ChangeStatus indicatePessimisticFixpoint() override {
8578 // If we give up and indicate a pessimistic fixpoint this instruction will
8579 // become an access for all potential access kinds:
8580 // TODO: Add pointers for argmemonly and globals to improve the results of
8581 // checkForAllAccessesToMemoryKind.
8582 bool Changed = false;
8583 MemoryLocationsKind KnownMLK = getKnown();
8584 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8585 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8586 if (!(CurMLK & KnownMLK))
8587 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8588 getAccessKindFromInst(I));
8589 return AAMemoryLocation::indicatePessimisticFixpoint();
8590 }
8591
8592protected:
8593 /// Helper struct to tie together an instruction that has a read or write
8594 /// effect with the pointer it accesses (if any).
8595 struct AccessInfo {
8596
8597 /// The instruction that caused the access.
8598 const Instruction *I;
8599
8600 /// The base pointer that is accessed, or null if unknown.
8601 const Value *Ptr;
8602
8603 /// The kind of access (read/write/read+write).
8605
8606 bool operator==(const AccessInfo &RHS) const {
8607 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8608 }
8609 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8610 if (LHS.I != RHS.I)
8611 return LHS.I < RHS.I;
8612 if (LHS.Ptr != RHS.Ptr)
8613 return LHS.Ptr < RHS.Ptr;
8614 if (LHS.Kind != RHS.Kind)
8615 return LHS.Kind < RHS.Kind;
8616 return false;
8617 }
8618 };
8619
8620 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8621 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8622 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8623 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8624 AccessKind2Accesses;
8625
8626 /// Categorize the pointer arguments of CB that might access memory in
8627 /// AccessedLoc and update the state and access map accordingly.
8628 void
8629 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8630 AAMemoryLocation::StateType &AccessedLocs,
8631 bool &Changed);
8632
8633 /// Return the kind(s) of location that may be accessed by \p V.
8635 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8636
8637 /// Return the access kind as determined by \p I.
8638 AccessKind getAccessKindFromInst(const Instruction *I) {
8639 AccessKind AK = READ_WRITE;
8640 if (I) {
8641 AK = I->mayReadFromMemory() ? READ : NONE;
8642 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8643 }
8644 return AK;
8645 }
8646
8647 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8648 /// an access of kind \p AK to a \p MLK memory location with the access
8649 /// pointer \p Ptr.
8650 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8651 MemoryLocationsKind MLK, const Instruction *I,
8652 const Value *Ptr, bool &Changed,
8653 AccessKind AK = READ_WRITE) {
8654
8655 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8656 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8657 if (!Accesses)
8658 Accesses = new (Allocator) AccessSet();
8659 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8660 if (MLK == NO_UNKOWN_MEM)
8661 MLK = NO_LOCATIONS;
8662 State.removeAssumedBits(MLK);
8663 }
8664
8665 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8666 /// arguments, and update the state and access map accordingly.
8667 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8668 AAMemoryLocation::StateType &State, bool &Changed,
8669 unsigned AccessAS = 0);
8670
8671 /// Used to allocate access sets.
8673};
8674
8675void AAMemoryLocationImpl::categorizePtrValue(
8676 Attributor &A, const Instruction &I, const Value &Ptr,
8677 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8678 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8679 << Ptr << " ["
8680 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8681
8682 auto Pred = [&](Value &Obj) {
8683 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8684 // TODO: recognize the TBAA used for constant accesses.
8685 MemoryLocationsKind MLK = NO_LOCATIONS;
8686
8687 // Filter accesses to constant (GPU) memory if we have an AS at the access
8688 // site or the object is known to actually have the associated AS.
8689 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8690 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8691 isIdentifiedObject(&Obj))) &&
8692 AA::isGPU(*I.getModule()))
8693 return true;
8694
8695 if (isa<UndefValue>(&Obj))
8696 return true;
8697 if (isa<Argument>(&Obj)) {
8698 // TODO: For now we do not treat byval arguments as local copies performed
8699 // on the call edge, though, we should. To make that happen we need to
8700 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8701 // would also allow us to mark functions only accessing byval arguments as
8702 // readnone again, arguably their accesses have no effect outside of the
8703 // function, like accesses to allocas.
8704 MLK = NO_ARGUMENT_MEM;
8705 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8706 // Reading constant memory is not treated as a read "effect" by the
8707 // function attr pass so we won't neither. Constants defined by TBAA are
8708 // similar. (We know we do not write it because it is constant.)
8709 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8710 if (GVar->isConstant())
8711 return true;
8712
8713 if (GV->hasLocalLinkage())
8714 MLK = NO_GLOBAL_INTERNAL_MEM;
8715 else
8716 MLK = NO_GLOBAL_EXTERNAL_MEM;
8717 } else if (isa<ConstantPointerNull>(&Obj) &&
8718 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8719 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8720 return true;
8721 } else if (isa<AllocaInst>(&Obj)) {
8722 MLK = NO_LOCAL_MEM;
8723 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8724 bool IsKnownNoAlias;
8727 IsKnownNoAlias))
8728 MLK = NO_MALLOCED_MEM;
8729 else
8730 MLK = NO_UNKOWN_MEM;
8731 } else {
8732 MLK = NO_UNKOWN_MEM;
8733 }
8734
8735 assert(MLK != NO_LOCATIONS && "No location specified!");
8736 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8737 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8738 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8739 getAccessKindFromInst(&I));
8740
8741 return true;
8742 };
8743
8744 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8746 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8747 LLVM_DEBUG(
8748 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8749 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8750 getAccessKindFromInst(&I));
8751 return;
8752 }
8753
8754 LLVM_DEBUG(
8755 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8756 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8757}
8758
8759void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8760 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8761 bool &Changed) {
8762 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8763
8764 // Skip non-pointer arguments.
8765 const Value *ArgOp = CB.getArgOperand(ArgNo);
8766 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8767 continue;
8768
8769 // Skip readnone arguments.
8770 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8771 const auto *ArgOpMemLocationAA =
8772 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8773
8774 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8775 continue;
8776
8777 // Categorize potentially accessed pointer arguments as if there was an
8778 // access instruction with them as pointer.
8779 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8780 }
8781}
8782
8784AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8785 bool &Changed) {
8786 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8787 << I << "\n");
8788
8789 AAMemoryLocation::StateType AccessedLocs;
8790 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8791
8792 if (auto *CB = dyn_cast<CallBase>(&I)) {
8793
8794 // First check if we assume any memory is access is visible.
8795 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8797 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8798 << " [" << CBMemLocationAA << "]\n");
8799 if (!CBMemLocationAA) {
8800 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8801 Changed, getAccessKindFromInst(&I));
8802 return NO_UNKOWN_MEM;
8803 }
8804
8805 if (CBMemLocationAA->isAssumedReadNone())
8806 return NO_LOCATIONS;
8807
8808 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8809 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8810 Changed, getAccessKindFromInst(&I));
8811 return AccessedLocs.getAssumed();
8812 }
8813
8814 uint32_t CBAssumedNotAccessedLocs =
8815 CBMemLocationAA->getAssumedNotAccessedLocation();
8816
8817 // Set the argmemonly and global bit as we handle them separately below.
8818 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8819 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8820
8821 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8822 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8823 continue;
8824 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8825 getAccessKindFromInst(&I));
8826 }
8827
8828 // Now handle global memory if it might be accessed. This is slightly tricky
8829 // as NO_GLOBAL_MEM has multiple bits set.
8830 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8831 if (HasGlobalAccesses) {
8832 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8833 AccessKind Kind, MemoryLocationsKind MLK) {
8834 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8835 getAccessKindFromInst(&I));
8836 return true;
8837 };
8838 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8839 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8840 return AccessedLocs.getWorstState();
8841 }
8842
8843 LLVM_DEBUG(
8844 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8845 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8846
8847 // Now handle argument memory if it might be accessed.
8848 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8849 if (HasArgAccesses)
8850 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8851
8852 LLVM_DEBUG(
8853 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8854 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8855
8856 return AccessedLocs.getAssumed();
8857 }
8858
8859 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8860 LLVM_DEBUG(
8861 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8862 << I << " [" << *Ptr << "]\n");
8863 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8864 Ptr->getType()->getPointerAddressSpace());
8865 return AccessedLocs.getAssumed();
8866 }
8867
8868 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8869 << I << "\n");
8870 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8871 getAccessKindFromInst(&I));
8872 return AccessedLocs.getAssumed();
8873}
8874
8875/// An AA to represent the memory behavior function attributes.
8876struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8877 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8878 : AAMemoryLocationImpl(IRP, A) {}
8879
8880 /// See AbstractAttribute::updateImpl(Attributor &A).
8881 ChangeStatus updateImpl(Attributor &A) override {
8882
8883 const auto *MemBehaviorAA =
8884 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8885 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8886 if (MemBehaviorAA->isKnownReadNone())
8887 return indicateOptimisticFixpoint();
8889 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8890 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8891 return ChangeStatus::UNCHANGED;
8892 }
8893
8894 // The current assumed state used to determine a change.
8895 auto AssumedState = getAssumed();
8896 bool Changed = false;
8897
8898 auto CheckRWInst = [&](Instruction &I) {
8899 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8900 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8901 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8902 removeAssumedBits(inverseLocation(MLK, false, false));
8903 // Stop once only the valid bit set in the *not assumed location*, thus
8904 // once we don't actually exclude any memory locations in the state.
8905 return getAssumedNotAccessedLocation() != VALID_STATE;
8906 };
8907
8908 bool UsedAssumedInformation = false;
8909 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8910 UsedAssumedInformation))
8911 return indicatePessimisticFixpoint();
8912
8913 Changed |= AssumedState != getAssumed();
8914 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8915 }
8916
8917 /// See AbstractAttribute::trackStatistics()
8918 void trackStatistics() const override {
8919 if (isAssumedReadNone())
8920 STATS_DECLTRACK_FN_ATTR(readnone)
8921 else if (isAssumedArgMemOnly())
8922 STATS_DECLTRACK_FN_ATTR(argmemonly)
8923 else if (isAssumedInaccessibleMemOnly())
8924 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8925 else if (isAssumedInaccessibleOrArgMemOnly())
8926 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8927 }
8928};
8929
8930/// AAMemoryLocation attribute for call sites.
8931struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8932 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8933 : AAMemoryLocationImpl(IRP, A) {}
8934
8935 /// See AbstractAttribute::updateImpl(...).
8936 ChangeStatus updateImpl(Attributor &A) override {
8937 // TODO: Once we have call site specific value information we can provide
8938 // call site specific liveness liveness information and then it makes
8939 // sense to specialize attributes for call sites arguments instead of
8940 // redirecting requests to the callee argument.
8941 Function *F = getAssociatedFunction();
8942 const IRPosition &FnPos = IRPosition::function(*F);
8943 auto *FnAA =
8944 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8945 if (!FnAA)
8946 return indicatePessimisticFixpoint();
8947 bool Changed = false;
8948 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8949 AccessKind Kind, MemoryLocationsKind MLK) {
8950 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8951 getAccessKindFromInst(I));
8952 return true;
8953 };
8954 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8955 return indicatePessimisticFixpoint();
8956 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8957 }
8958
8959 /// See AbstractAttribute::trackStatistics()
8960 void trackStatistics() const override {
8961 if (isAssumedReadNone())
8962 STATS_DECLTRACK_CS_ATTR(readnone)
8963 }
8964};
8965} // namespace
8966
8967/// ------------------ denormal-fp-math Attribute -------------------------
8968
8969namespace {
8970struct AADenormalFPMathImpl : public AADenormalFPMath {
8971 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8972 : AADenormalFPMath(IRP, A) {}
8973
8974 const std::string getAsStr(Attributor *A) const override {
8975 std::string Str("AADenormalFPMath[");
8976 raw_string_ostream OS(Str);
8977
8978 DenormalState Known = getKnown();
8979 if (Known.Mode.isValid())
8980 OS << "denormal-fp-math=" << Known.Mode;
8981 else
8982 OS << "invalid";
8983
8984 if (Known.ModeF32.isValid())
8985 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8986 OS << ']';
8987 return Str;
8988 }
8989};
8990
8991struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8992 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8993 : AADenormalFPMathImpl(IRP, A) {}
8994
8995 void initialize(Attributor &A) override {
8996 const Function *F = getAnchorScope();
8997 DenormalMode Mode = F->getDenormalModeRaw();
8998 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8999
9000 // TODO: Handling this here prevents handling the case where a callee has a
9001 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
9002 // a function with a fully fixed mode.
9003 if (ModeF32 == DenormalMode::getInvalid())
9004 ModeF32 = Mode;
9005 Known = DenormalState{Mode, ModeF32};
9006 if (isModeFixed())
9007 indicateFixpoint();
9008 }
9009
9010 ChangeStatus updateImpl(Attributor &A) override {
9011 ChangeStatus Change = ChangeStatus::UNCHANGED;
9012
9013 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9014 Function *Caller = CS.getInstruction()->getFunction();
9015 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9016 << "->" << getAssociatedFunction()->getName() << '\n');
9017
9018 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9019 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9020 if (!CallerInfo)
9021 return false;
9022
9023 Change = Change | clampStateAndIndicateChange(this->getState(),
9024 CallerInfo->getState());
9025 return true;
9026 };
9027
9028 bool AllCallSitesKnown = true;
9029 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9030 return indicatePessimisticFixpoint();
9031
9032 if (Change == ChangeStatus::CHANGED && isModeFixed())
9033 indicateFixpoint();
9034 return Change;
9035 }
9036
9037 ChangeStatus manifest(Attributor &A) override {
9038 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9039
9040 SmallVector<Attribute, 2> AttrToAdd;
9041 SmallVector<StringRef, 2> AttrToRemove;
9042 if (Known.Mode == DenormalMode::getDefault()) {
9043 AttrToRemove.push_back("denormal-fp-math");
9044 } else {
9045 AttrToAdd.push_back(
9046 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
9047 }
9048
9049 if (Known.ModeF32 != Known.Mode) {
9050 AttrToAdd.push_back(
9051 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
9052 } else {
9053 AttrToRemove.push_back("denormal-fp-math-f32");
9054 }
9055
9056 auto &IRP = getIRPosition();
9057
9058 // TODO: There should be a combined add and remove API.
9059 return A.removeAttrs(IRP, AttrToRemove) |
9060 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9061 }
9062
9063 void trackStatistics() const override {
9064 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
9065 }
9066};
9067} // namespace
9068
9069/// ------------------ Value Constant Range Attribute -------------------------
9070
9071namespace {
9072struct AAValueConstantRangeImpl : AAValueConstantRange {
9073 using StateType = IntegerRangeState;
9074 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9075 : AAValueConstantRange(IRP, A) {}
9076
9077 /// See AbstractAttribute::initialize(..).
9078 void initialize(Attributor &A) override {
9079 if (A.hasSimplificationCallback(getIRPosition())) {
9080 indicatePessimisticFixpoint();
9081 return;
9082 }
9083
9084 // Intersect a range given by SCEV.
9085 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9086
9087 // Intersect a range given by LVI.
9088 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9089 }
9090
9091 /// See AbstractAttribute::getAsStr().
9092 const std::string getAsStr(Attributor *A) const override {
9093 std::string Str;
9094 llvm::raw_string_ostream OS(Str);
9095 OS << "range(" << getBitWidth() << ")<";
9096 getKnown().print(OS);
9097 OS << " / ";
9098 getAssumed().print(OS);
9099 OS << ">";
9100 return Str;
9101 }
9102
9103 /// Helper function to get a SCEV expr for the associated value at program
9104 /// point \p I.
9105 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9106 if (!getAnchorScope())
9107 return nullptr;
9108
9109 ScalarEvolution *SE =
9110 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9111 *getAnchorScope());
9112
9113 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9114 *getAnchorScope());
9115
9116 if (!SE || !LI)
9117 return nullptr;
9118
9119 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9120 if (!I)
9121 return S;
9122
9123 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9124 }
9125
9126 /// Helper function to get a range from SCEV for the associated value at
9127 /// program point \p I.
9128 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9129 const Instruction *I = nullptr) const {
9130 if (!getAnchorScope())
9131 return getWorstState(getBitWidth());
9132
9133 ScalarEvolution *SE =
9134 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9135 *getAnchorScope());
9136
9137 const SCEV *S = getSCEV(A, I);
9138 if (!SE || !S)
9139 return getWorstState(getBitWidth());
9140
9141 return SE->getUnsignedRange(S);
9142 }
9143
9144 /// Helper function to get a range from LVI for the associated value at
9145 /// program point \p I.
9146 ConstantRange
9147 getConstantRangeFromLVI(Attributor &A,
9148 const Instruction *CtxI = nullptr) const {
9149 if (!getAnchorScope())
9150 return getWorstState(getBitWidth());
9151
9152 LazyValueInfo *LVI =
9153 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9154 *getAnchorScope());
9155
9156 if (!LVI || !CtxI)
9157 return getWorstState(getBitWidth());
9158 return LVI->getConstantRange(&getAssociatedValue(),
9159 const_cast<Instruction *>(CtxI),
9160 /*UndefAllowed*/ false);
9161 }
9162
9163 /// Return true if \p CtxI is valid for querying outside analyses.
9164 /// This basically makes sure we do not ask intra-procedural analysis
9165 /// about a context in the wrong function or a context that violates
9166 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9167 /// if the original context of this AA is OK or should be considered invalid.
9168 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9169 const Instruction *CtxI,
9170 bool AllowAACtxI) const {
9171 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9172 return false;
9173
9174 // Our context might be in a different function, neither intra-procedural
9175 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9176 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9177 return false;
9178
9179 // If the context is not dominated by the value there are paths to the
9180 // context that do not define the value. This cannot be handled by
9181 // LazyValueInfo so we need to bail.
9182 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9183 InformationCache &InfoCache = A.getInfoCache();
9184 const DominatorTree *DT =
9185 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9186 *I->getFunction());
9187 return DT && DT->dominates(I, CtxI);
9188 }
9189
9190 return true;
9191 }
9192
9193 /// See AAValueConstantRange::getKnownConstantRange(..).
9194 ConstantRange
9195 getKnownConstantRange(Attributor &A,
9196 const Instruction *CtxI = nullptr) const override {
9197 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9198 /* AllowAACtxI */ false))
9199 return getKnown();
9200
9201 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9202 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9203 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9204 }
9205
9206 /// See AAValueConstantRange::getAssumedConstantRange(..).
9207 ConstantRange
9208 getAssumedConstantRange(Attributor &A,
9209 const Instruction *CtxI = nullptr) const override {
9210 // TODO: Make SCEV use Attributor assumption.
9211 // We may be able to bound a variable range via assumptions in
9212 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9213 // evolve to x^2 + x, then we can say that y is in [2, 12].
9214 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9215 /* AllowAACtxI */ false))
9216 return getAssumed();
9217
9218 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9219 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9220 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9221 }
9222
9223 /// Helper function to create MDNode for range metadata.
9224 static MDNode *
9225 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9226 const ConstantRange &AssumedConstantRange) {
9227 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9228 Ty, AssumedConstantRange.getLower())),
9229 ConstantAsMetadata::get(ConstantInt::get(
9230 Ty, AssumedConstantRange.getUpper()))};
9231 return MDNode::get(Ctx, LowAndHigh);
9232 }
9233
9234 /// Return true if \p Assumed is included in ranges from instruction \p I.
9235 static bool isBetterRange(const ConstantRange &Assumed,
9236 const Instruction &I) {
9237 if (Assumed.isFullSet())
9238 return false;
9239
9240 std::optional<ConstantRange> Known;
9241
9242 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9243 Known = CB->getRange();
9244 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9245 // If multiple ranges are annotated in IR, we give up to annotate assumed
9246 // range for now.
9247
9248 // TODO: If there exists a known range which containts assumed range, we
9249 // can say assumed range is better.
9250 if (KnownRanges->getNumOperands() > 2)
9251 return false;
9252
9253 ConstantInt *Lower =
9254 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9255 ConstantInt *Upper =
9256 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9257
9258 Known.emplace(Lower->getValue(), Upper->getValue());
9259 }
9260 return !Known || (*Known != Assumed && Known->contains(Assumed));
9261 }
9262
9263 /// Helper function to set range metadata.
9264 static bool
9265 setRangeMetadataIfisBetterRange(Instruction *I,
9266 const ConstantRange &AssumedConstantRange) {
9267 if (isBetterRange(AssumedConstantRange, *I)) {
9268 I->setMetadata(LLVMContext::MD_range,
9269 getMDNodeForConstantRange(I->getType(), I->getContext(),
9270 AssumedConstantRange));
9271 return true;
9272 }
9273 return false;
9274 }
9275 /// Helper function to set range return attribute.
9276 static bool
9277 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9278 Instruction *I,
9279 const ConstantRange &AssumedConstantRange) {
9280 if (isBetterRange(AssumedConstantRange, *I)) {
9281 A.manifestAttrs(IRP,
9282 Attribute::get(I->getContext(), Attribute::Range,
9283 AssumedConstantRange),
9284 /*ForceReplace*/ true);
9285 return true;
9286 }
9287 return false;
9288 }
9289
9290 /// See AbstractAttribute::manifest()
9291 ChangeStatus manifest(Attributor &A) override {
9292 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9293 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9294 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9295
9296 auto &V = getAssociatedValue();
9297 if (!AssumedConstantRange.isEmptySet() &&
9298 !AssumedConstantRange.isSingleElement()) {
9299 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9300 assert(I == getCtxI() && "Should not annotate an instruction which is "
9301 "not the context instruction");
9302 if (isa<LoadInst>(I))
9303 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9304 Changed = ChangeStatus::CHANGED;
9305 if (isa<CallInst>(I))
9306 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9307 AssumedConstantRange))
9308 Changed = ChangeStatus::CHANGED;
9309 }
9310 }
9311
9312 return Changed;
9313 }
9314};
9315
9316struct AAValueConstantRangeArgument final
9317 : AAArgumentFromCallSiteArguments<
9318 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9319 true /* BridgeCallBaseContext */> {
9320 using Base = AAArgumentFromCallSiteArguments<
9321 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9322 true /* BridgeCallBaseContext */>;
9323 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9324 : Base(IRP, A) {}
9325
9326 /// See AbstractAttribute::trackStatistics()
9327 void trackStatistics() const override {
9328 STATS_DECLTRACK_ARG_ATTR(value_range)
9329 }
9330};
9331
9332struct AAValueConstantRangeReturned
9333 : AAReturnedFromReturnedValues<AAValueConstantRange,
9334 AAValueConstantRangeImpl,
9335 AAValueConstantRangeImpl::StateType,
9336 /* PropagateCallBaseContext */ true> {
9337 using Base =
9338 AAReturnedFromReturnedValues<AAValueConstantRange,
9339 AAValueConstantRangeImpl,
9340 AAValueConstantRangeImpl::StateType,
9341 /* PropagateCallBaseContext */ true>;
9342 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9343 : Base(IRP, A) {}
9344
9345 /// See AbstractAttribute::initialize(...).
9346 void initialize(Attributor &A) override {
9347 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9348 indicatePessimisticFixpoint();
9349 }
9350
9351 /// See AbstractAttribute::trackStatistics()
9352 void trackStatistics() const override {
9353 STATS_DECLTRACK_FNRET_ATTR(value_range)
9354 }
9355};
9356
9357struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9358 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9359 : AAValueConstantRangeImpl(IRP, A) {}
9360
9361 /// See AbstractAttribute::initialize(...).
9362 void initialize(Attributor &A) override {
9363 AAValueConstantRangeImpl::initialize(A);
9364 if (isAtFixpoint())
9365 return;
9366
9367 Value &V = getAssociatedValue();
9368
9369 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9370 unionAssumed(ConstantRange(C->getValue()));
9371 indicateOptimisticFixpoint();
9372 return;
9373 }
9374
9375 if (isa<UndefValue>(&V)) {
9376 // Collapse the undef state to 0.
9377 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9378 indicateOptimisticFixpoint();
9379 return;
9380 }
9381
9382 if (isa<CallBase>(&V))
9383 return;
9384
9385 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9386 return;
9387
9388 // If it is a load instruction with range metadata, use it.
9389 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9390 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9391 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9392 return;
9393 }
9394
9395 // We can work with PHI and select instruction as we traverse their operands
9396 // during update.
9397 if (isa<SelectInst>(V) || isa<PHINode>(V))
9398 return;
9399
9400 // Otherwise we give up.
9401 indicatePessimisticFixpoint();
9402
9403 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9404 << getAssociatedValue() << "\n");
9405 }
9406
9407 bool calculateBinaryOperator(
9408 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9409 const Instruction *CtxI,
9410 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9411 Value *LHS = BinOp->getOperand(0);
9412 Value *RHS = BinOp->getOperand(1);
9413
9414 // Simplify the operands first.
9415 bool UsedAssumedInformation = false;
9416 const auto &SimplifiedLHS = A.getAssumedSimplified(
9417 IRPosition::value(*LHS, getCallBaseContext()), *this,
9418 UsedAssumedInformation, AA::Interprocedural);
9419 if (!SimplifiedLHS.has_value())
9420 return true;
9421 if (!*SimplifiedLHS)
9422 return false;
9423 LHS = *SimplifiedLHS;
9424
9425 const auto &SimplifiedRHS = A.getAssumedSimplified(
9426 IRPosition::value(*RHS, getCallBaseContext()), *this,
9427 UsedAssumedInformation, AA::Interprocedural);
9428 if (!SimplifiedRHS.has_value())
9429 return true;
9430 if (!*SimplifiedRHS)
9431 return false;
9432 RHS = *SimplifiedRHS;
9433
9434 // TODO: Allow non integers as well.
9435 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9436 return false;
9437
9438 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9439 *this, IRPosition::value(*LHS, getCallBaseContext()),
9440 DepClassTy::REQUIRED);
9441 if (!LHSAA)
9442 return false;
9443 QuerriedAAs.push_back(LHSAA);
9444 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9445
9446 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9447 *this, IRPosition::value(*RHS, getCallBaseContext()),
9448 DepClassTy::REQUIRED);
9449 if (!RHSAA)
9450 return false;
9451 QuerriedAAs.push_back(RHSAA);
9452 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9453
9454 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9455
9456 T.unionAssumed(AssumedRange);
9457
9458 // TODO: Track a known state too.
9459
9460 return T.isValidState();
9461 }
9462
9463 bool calculateCastInst(
9464 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9465 const Instruction *CtxI,
9466 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9467 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9468 // TODO: Allow non integers as well.
9469 Value *OpV = CastI->getOperand(0);
9470
9471 // Simplify the operand first.
9472 bool UsedAssumedInformation = false;
9473 const auto &SimplifiedOpV = A.getAssumedSimplified(
9474 IRPosition::value(*OpV, getCallBaseContext()), *this,
9475 UsedAssumedInformation, AA::Interprocedural);
9476 if (!SimplifiedOpV.has_value())
9477 return true;
9478 if (!*SimplifiedOpV)
9479 return false;
9480 OpV = *SimplifiedOpV;
9481
9482 if (!OpV->getType()->isIntegerTy())
9483 return false;
9484
9485 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9486 *this, IRPosition::value(*OpV, getCallBaseContext()),
9487 DepClassTy::REQUIRED);
9488 if (!OpAA)
9489 return false;
9490 QuerriedAAs.push_back(OpAA);
9491 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9492 getState().getBitWidth()));
9493 return T.isValidState();
9494 }
9495
9496 bool
9497 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9498 const Instruction *CtxI,
9499 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9500 Value *LHS = CmpI->getOperand(0);
9501 Value *RHS = CmpI->getOperand(1);
9502
9503 // Simplify the operands first.
9504 bool UsedAssumedInformation = false;
9505 const auto &SimplifiedLHS = A.getAssumedSimplified(
9506 IRPosition::value(*LHS, getCallBaseContext()), *this,
9507 UsedAssumedInformation, AA::Interprocedural);
9508 if (!SimplifiedLHS.has_value())
9509 return true;
9510 if (!*SimplifiedLHS)
9511 return false;
9512 LHS = *SimplifiedLHS;
9513
9514 const auto &SimplifiedRHS = A.getAssumedSimplified(
9515 IRPosition::value(*RHS, getCallBaseContext()), *this,
9516 UsedAssumedInformation, AA::Interprocedural);
9517 if (!SimplifiedRHS.has_value())
9518 return true;
9519 if (!*SimplifiedRHS)
9520 return false;
9521 RHS = *SimplifiedRHS;
9522
9523 // TODO: Allow non integers as well.
9524 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9525 return false;
9526
9527 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9528 *this, IRPosition::value(*LHS, getCallBaseContext()),
9529 DepClassTy::REQUIRED);
9530 if (!LHSAA)
9531 return false;
9532 QuerriedAAs.push_back(LHSAA);
9533 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9534 *this, IRPosition::value(*RHS, getCallBaseContext()),
9535 DepClassTy::REQUIRED);
9536 if (!RHSAA)
9537 return false;
9538 QuerriedAAs.push_back(RHSAA);
9539 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9540 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9541
9542 // If one of them is empty set, we can't decide.
9543 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9544 return true;
9545
9546 bool MustTrue = false, MustFalse = false;
9547
9548 auto AllowedRegion =
9550
9551 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9552 MustFalse = true;
9553
9554 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9555 MustTrue = true;
9556
9557 assert((!MustTrue || !MustFalse) &&
9558 "Either MustTrue or MustFalse should be false!");
9559
9560 if (MustTrue)
9561 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9562 else if (MustFalse)
9563 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9564 else
9565 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9566
9567 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9568 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9569 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9570 << *RHSAA);
9571
9572 // TODO: Track a known state too.
9573 return T.isValidState();
9574 }
9575
9576 /// See AbstractAttribute::updateImpl(...).
9577 ChangeStatus updateImpl(Attributor &A) override {
9578
9579 IntegerRangeState T(getBitWidth());
9580 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9582 if (!I || isa<CallBase>(I)) {
9583
9584 // Simplify the operand first.
9585 bool UsedAssumedInformation = false;
9586 const auto &SimplifiedOpV = A.getAssumedSimplified(
9587 IRPosition::value(V, getCallBaseContext()), *this,
9588 UsedAssumedInformation, AA::Interprocedural);
9589 if (!SimplifiedOpV.has_value())
9590 return true;
9591 if (!*SimplifiedOpV)
9592 return false;
9593 Value *VPtr = *SimplifiedOpV;
9594
9595 // If the value is not instruction, we query AA to Attributor.
9596 const auto *AA = A.getAAFor<AAValueConstantRange>(
9597 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9598 DepClassTy::REQUIRED);
9599
9600 // Clamp operator is not used to utilize a program point CtxI.
9601 if (AA)
9602 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9603 else
9604 return false;
9605
9606 return T.isValidState();
9607 }
9608
9610 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9611 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9612 return false;
9613 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9614 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9615 return false;
9616 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9617 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9618 return false;
9619 } else {
9620 // Give up with other instructions.
9621 // TODO: Add other instructions
9622
9623 T.indicatePessimisticFixpoint();
9624 return false;
9625 }
9626
9627 // Catch circular reasoning in a pessimistic way for now.
9628 // TODO: Check how the range evolves and if we stripped anything, see also
9629 // AADereferenceable or AAAlign for similar situations.
9630 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9631 if (QueriedAA != this)
9632 continue;
9633 // If we are in a stady state we do not need to worry.
9634 if (T.getAssumed() == getState().getAssumed())
9635 continue;
9636 T.indicatePessimisticFixpoint();
9637 }
9638
9639 return T.isValidState();
9640 };
9641
9642 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9643 return indicatePessimisticFixpoint();
9644
9645 // Ensure that long def-use chains can't cause circular reasoning either by
9646 // introducing a cutoff below.
9647 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9648 return ChangeStatus::UNCHANGED;
9649 if (++NumChanges > MaxNumChanges) {
9650 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9651 << " but only " << MaxNumChanges
9652 << " are allowed to avoid cyclic reasoning.");
9653 return indicatePessimisticFixpoint();
9654 }
9655 return ChangeStatus::CHANGED;
9656 }
9657
9658 /// See AbstractAttribute::trackStatistics()
9659 void trackStatistics() const override {
9661 }
9662
9663 /// Tracker to bail after too many widening steps of the constant range.
9664 int NumChanges = 0;
9665
9666 /// Upper bound for the number of allowed changes (=widening steps) for the
9667 /// constant range before we give up.
9668 static constexpr int MaxNumChanges = 5;
9669};
9670
9671struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9672 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9673 : AAValueConstantRangeImpl(IRP, A) {}
9674
9675 /// See AbstractAttribute::initialize(...).
9676 ChangeStatus updateImpl(Attributor &A) override {
9677 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9678 "not be called");
9679 }
9680
9681 /// See AbstractAttribute::trackStatistics()
9682 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9683};
9684
9685struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9686 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9687 : AAValueConstantRangeFunction(IRP, A) {}
9688
9689 /// See AbstractAttribute::trackStatistics()
9690 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9691};
9692
9693struct AAValueConstantRangeCallSiteReturned
9694 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9695 AAValueConstantRangeImpl::StateType,
9696 /* IntroduceCallBaseContext */ true> {
9697 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9698 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9699 AAValueConstantRangeImpl::StateType,
9700 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9701
9702 /// See AbstractAttribute::initialize(...).
9703 void initialize(Attributor &A) override {
9704 // If it is a call instruction with range attribute, use the range.
9705 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9706 if (std::optional<ConstantRange> Range = CI->getRange())
9707 intersectKnown(*Range);
9708 }
9709
9710 AAValueConstantRangeImpl::initialize(A);
9711 }
9712
9713 /// See AbstractAttribute::trackStatistics()
9714 void trackStatistics() const override {
9715 STATS_DECLTRACK_CSRET_ATTR(value_range)
9716 }
9717};
9718struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9719 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9720 : AAValueConstantRangeFloating(IRP, A) {}
9721
9722 /// See AbstractAttribute::manifest()
9723 ChangeStatus manifest(Attributor &A) override {
9724 return ChangeStatus::UNCHANGED;
9725 }
9726
9727 /// See AbstractAttribute::trackStatistics()
9728 void trackStatistics() const override {
9729 STATS_DECLTRACK_CSARG_ATTR(value_range)
9730 }
9731};
9732} // namespace
9733
9734/// ------------------ Potential Values Attribute -------------------------
9735
9736namespace {
9737struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9738 using StateType = PotentialConstantIntValuesState;
9739
9740 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9741 : AAPotentialConstantValues(IRP, A) {}
9742
9743 /// See AbstractAttribute::initialize(..).
9744 void initialize(Attributor &A) override {
9745 if (A.hasSimplificationCallback(getIRPosition()))
9746 indicatePessimisticFixpoint();
9747 else
9748 AAPotentialConstantValues::initialize(A);
9749 }
9750
9751 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9752 bool &ContainsUndef, bool ForSelf) {
9754 bool UsedAssumedInformation = false;
9755 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9756 UsedAssumedInformation)) {
9757 // Avoid recursion when the caller is computing constant values for this
9758 // IRP itself.
9759 if (ForSelf)
9760 return false;
9761 if (!IRP.getAssociatedType()->isIntegerTy())
9762 return false;
9763 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9764 *this, IRP, DepClassTy::REQUIRED);
9765 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9766 return false;
9767 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9768 S = PotentialValuesAA->getState().getAssumedSet();
9769 return true;
9770 }
9771
9772 // Copy all the constant values, except UndefValue. ContainsUndef is true
9773 // iff Values contains only UndefValue instances. If there are other known
9774 // constants, then UndefValue is dropped.
9775 ContainsUndef = false;
9776 for (auto &It : Values) {
9777 if (isa<UndefValue>(It.getValue())) {
9778 ContainsUndef = true;
9779 continue;
9780 }
9781 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9782 if (!CI)
9783 return false;
9784 S.insert(CI->getValue());
9785 }
9786 ContainsUndef &= S.empty();
9787
9788 return true;
9789 }
9790
9791 /// See AbstractAttribute::getAsStr().
9792 const std::string getAsStr(Attributor *A) const override {
9793 std::string Str;
9794 llvm::raw_string_ostream OS(Str);
9795 OS << getState();
9796 return Str;
9797 }
9798
9799 /// See AbstractAttribute::updateImpl(...).
9800 ChangeStatus updateImpl(Attributor &A) override {
9801 return indicatePessimisticFixpoint();
9802 }
9803};
9804
9805struct AAPotentialConstantValuesArgument final
9806 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9807 AAPotentialConstantValuesImpl,
9808 PotentialConstantIntValuesState> {
9809 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9810 AAPotentialConstantValuesImpl,
9812 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9813 : Base(IRP, A) {}
9814
9815 /// See AbstractAttribute::trackStatistics()
9816 void trackStatistics() const override {
9817 STATS_DECLTRACK_ARG_ATTR(potential_values)
9818 }
9819};
9820
9821struct AAPotentialConstantValuesReturned
9822 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9823 AAPotentialConstantValuesImpl> {
9824 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9825 AAPotentialConstantValuesImpl>;
9826 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9827 : Base(IRP, A) {}
9828
9829 void initialize(Attributor &A) override {
9830 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9831 indicatePessimisticFixpoint();
9832 Base::initialize(A);
9833 }
9834
9835 /// See AbstractAttribute::trackStatistics()
9836 void trackStatistics() const override {
9837 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9838 }
9839};
9840
9841struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9842 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9843 : AAPotentialConstantValuesImpl(IRP, A) {}
9844
9845 /// See AbstractAttribute::initialize(..).
9846 void initialize(Attributor &A) override {
9847 AAPotentialConstantValuesImpl::initialize(A);
9848 if (isAtFixpoint())
9849 return;
9850
9851 Value &V = getAssociatedValue();
9852
9853 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9854 unionAssumed(C->getValue());
9855 indicateOptimisticFixpoint();
9856 return;
9857 }
9858
9859 if (isa<UndefValue>(&V)) {
9860 unionAssumedWithUndef();
9861 indicateOptimisticFixpoint();
9862 return;
9863 }
9864
9865 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9866 return;
9867
9868 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9869 return;
9870
9871 indicatePessimisticFixpoint();
9872
9873 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9874 << getAssociatedValue() << "\n");
9875 }
9876
9877 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9878 const APInt &RHS) {
9879 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9880 }
9881
9882 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9883 uint32_t ResultBitWidth) {
9884 Instruction::CastOps CastOp = CI->getOpcode();
9885 switch (CastOp) {
9886 default:
9887 llvm_unreachable("unsupported or not integer cast");
9888 case Instruction::Trunc:
9889 return Src.trunc(ResultBitWidth);
9890 case Instruction::SExt:
9891 return Src.sext(ResultBitWidth);
9892 case Instruction::ZExt:
9893 return Src.zext(ResultBitWidth);
9894 case Instruction::BitCast:
9895 return Src;
9896 }
9897 }
9898
9899 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9900 const APInt &LHS, const APInt &RHS,
9901 bool &SkipOperation, bool &Unsupported) {
9902 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9903 // Unsupported is set to true when the binary operator is not supported.
9904 // SkipOperation is set to true when UB occur with the given operand pair
9905 // (LHS, RHS).
9906 // TODO: we should look at nsw and nuw keywords to handle operations
9907 // that create poison or undef value.
9908 switch (BinOpcode) {
9909 default:
9910 Unsupported = true;
9911 return LHS;
9912 case Instruction::Add:
9913 return LHS + RHS;
9914 case Instruction::Sub:
9915 return LHS - RHS;
9916 case Instruction::Mul:
9917 return LHS * RHS;
9918 case Instruction::UDiv:
9919 if (RHS.isZero()) {
9920 SkipOperation = true;
9921 return LHS;
9922 }
9923 return LHS.udiv(RHS);
9924 case Instruction::SDiv:
9925 if (RHS.isZero()) {
9926 SkipOperation = true;
9927 return LHS;
9928 }
9929 return LHS.sdiv(RHS);
9930 case Instruction::URem:
9931 if (RHS.isZero()) {
9932 SkipOperation = true;
9933 return LHS;
9934 }
9935 return LHS.urem(RHS);
9936 case Instruction::SRem:
9937 if (RHS.isZero()) {
9938 SkipOperation = true;
9939 return LHS;
9940 }
9941 return LHS.srem(RHS);
9942 case Instruction::Shl:
9943 return LHS.shl(RHS);
9944 case Instruction::LShr:
9945 return LHS.lshr(RHS);
9946 case Instruction::AShr:
9947 return LHS.ashr(RHS);
9948 case Instruction::And:
9949 return LHS & RHS;
9950 case Instruction::Or:
9951 return LHS | RHS;
9952 case Instruction::Xor:
9953 return LHS ^ RHS;
9954 }
9955 }
9956
9957 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9958 const APInt &LHS, const APInt &RHS) {
9959 bool SkipOperation = false;
9960 bool Unsupported = false;
9961 APInt Result =
9962 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9963 if (Unsupported)
9964 return false;
9965 // If SkipOperation is true, we can ignore this operand pair (L, R).
9966 if (!SkipOperation)
9967 unionAssumed(Result);
9968 return isValidState();
9969 }
9970
9971 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9972 auto AssumedBefore = getAssumed();
9973 Value *LHS = ICI->getOperand(0);
9974 Value *RHS = ICI->getOperand(1);
9975
9976 bool LHSContainsUndef = false, RHSContainsUndef = false;
9977 SetTy LHSAAPVS, RHSAAPVS;
9978 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9979 LHSContainsUndef, /* ForSelf */ false) ||
9980 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9981 RHSContainsUndef, /* ForSelf */ false))
9982 return indicatePessimisticFixpoint();
9983
9984 // TODO: make use of undef flag to limit potential values aggressively.
9985 bool MaybeTrue = false, MaybeFalse = false;
9986 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9987 if (LHSContainsUndef && RHSContainsUndef) {
9988 // The result of any comparison between undefs can be soundly replaced
9989 // with undef.
9990 unionAssumedWithUndef();
9991 } else if (LHSContainsUndef) {
9992 for (const APInt &R : RHSAAPVS) {
9993 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9994 MaybeTrue |= CmpResult;
9995 MaybeFalse |= !CmpResult;
9996 if (MaybeTrue & MaybeFalse)
9997 return indicatePessimisticFixpoint();
9998 }
9999 } else if (RHSContainsUndef) {
10000 for (const APInt &L : LHSAAPVS) {
10001 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10002 MaybeTrue |= CmpResult;
10003 MaybeFalse |= !CmpResult;
10004 if (MaybeTrue & MaybeFalse)
10005 return indicatePessimisticFixpoint();
10006 }
10007 } else {
10008 for (const APInt &L : LHSAAPVS) {
10009 for (const APInt &R : RHSAAPVS) {
10010 bool CmpResult = calculateICmpInst(ICI, L, R);
10011 MaybeTrue |= CmpResult;
10012 MaybeFalse |= !CmpResult;
10013 if (MaybeTrue & MaybeFalse)
10014 return indicatePessimisticFixpoint();
10015 }
10016 }
10017 }
10018 if (MaybeTrue)
10019 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10020 if (MaybeFalse)
10021 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10022 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10023 : ChangeStatus::CHANGED;
10024 }
10025
10026 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10027 auto AssumedBefore = getAssumed();
10028 Value *LHS = SI->getTrueValue();
10029 Value *RHS = SI->getFalseValue();
10030
10031 bool UsedAssumedInformation = false;
10032 std::optional<Constant *> C = A.getAssumedConstant(
10033 *SI->getCondition(), *this, UsedAssumedInformation);
10034
10035 // Check if we only need one operand.
10036 bool OnlyLeft = false, OnlyRight = false;
10037 if (C && *C && (*C)->isOneValue())
10038 OnlyLeft = true;
10039 else if (C && *C && (*C)->isZeroValue())
10040 OnlyRight = true;
10041
10042 bool LHSContainsUndef = false, RHSContainsUndef = false;
10043 SetTy LHSAAPVS, RHSAAPVS;
10044 if (!OnlyRight &&
10045 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10046 LHSContainsUndef, /* ForSelf */ false))
10047 return indicatePessimisticFixpoint();
10048
10049 if (!OnlyLeft &&
10050 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10051 RHSContainsUndef, /* ForSelf */ false))
10052 return indicatePessimisticFixpoint();
10053
10054 if (OnlyLeft || OnlyRight) {
10055 // select (true/false), lhs, rhs
10056 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10057 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10058
10059 if (Undef)
10060 unionAssumedWithUndef();
10061 else {
10062 for (const auto &It : *OpAA)
10063 unionAssumed(It);
10064 }
10065
10066 } else if (LHSContainsUndef && RHSContainsUndef) {
10067 // select i1 *, undef , undef => undef
10068 unionAssumedWithUndef();
10069 } else {
10070 for (const auto &It : LHSAAPVS)
10071 unionAssumed(It);
10072 for (const auto &It : RHSAAPVS)
10073 unionAssumed(It);
10074 }
10075 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10076 : ChangeStatus::CHANGED;
10077 }
10078
10079 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10080 auto AssumedBefore = getAssumed();
10081 if (!CI->isIntegerCast())
10082 return indicatePessimisticFixpoint();
10083 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10084 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10085 Value *Src = CI->getOperand(0);
10086
10087 bool SrcContainsUndef = false;
10088 SetTy SrcPVS;
10089 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10090 SrcContainsUndef, /* ForSelf */ false))
10091 return indicatePessimisticFixpoint();
10092
10093 if (SrcContainsUndef)
10094 unionAssumedWithUndef();
10095 else {
10096 for (const APInt &S : SrcPVS) {
10097 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10098 unionAssumed(T);
10099 }
10100 }
10101 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10102 : ChangeStatus::CHANGED;
10103 }
10104
10105 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10106 auto AssumedBefore = getAssumed();
10107 Value *LHS = BinOp->getOperand(0);
10108 Value *RHS = BinOp->getOperand(1);
10109
10110 bool LHSContainsUndef = false, RHSContainsUndef = false;
10111 SetTy LHSAAPVS, RHSAAPVS;
10112 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10113 LHSContainsUndef, /* ForSelf */ false) ||
10114 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10115 RHSContainsUndef, /* ForSelf */ false))
10116 return indicatePessimisticFixpoint();
10117
10118 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10119
10120 // TODO: make use of undef flag to limit potential values aggressively.
10121 if (LHSContainsUndef && RHSContainsUndef) {
10122 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10123 return indicatePessimisticFixpoint();
10124 } else if (LHSContainsUndef) {
10125 for (const APInt &R : RHSAAPVS) {
10126 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10127 return indicatePessimisticFixpoint();
10128 }
10129 } else if (RHSContainsUndef) {
10130 for (const APInt &L : LHSAAPVS) {
10131 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10132 return indicatePessimisticFixpoint();
10133 }
10134 } else {
10135 for (const APInt &L : LHSAAPVS) {
10136 for (const APInt &R : RHSAAPVS) {
10137 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10138 return indicatePessimisticFixpoint();
10139 }
10140 }
10141 }
10142 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10143 : ChangeStatus::CHANGED;
10144 }
10145
10146 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10147 auto AssumedBefore = getAssumed();
10148 SetTy Incoming;
10149 bool ContainsUndef;
10150 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10151 ContainsUndef, /* ForSelf */ true))
10152 return indicatePessimisticFixpoint();
10153 if (ContainsUndef) {
10154 unionAssumedWithUndef();
10155 } else {
10156 for (const auto &It : Incoming)
10157 unionAssumed(It);
10158 }
10159 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10160 : ChangeStatus::CHANGED;
10161 }
10162
10163 /// See AbstractAttribute::updateImpl(...).
10164 ChangeStatus updateImpl(Attributor &A) override {
10165 Value &V = getAssociatedValue();
10167
10168 if (auto *ICI = dyn_cast<ICmpInst>(I))
10169 return updateWithICmpInst(A, ICI);
10170
10171 if (auto *SI = dyn_cast<SelectInst>(I))
10172 return updateWithSelectInst(A, SI);
10173
10174 if (auto *CI = dyn_cast<CastInst>(I))
10175 return updateWithCastInst(A, CI);
10176
10177 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10178 return updateWithBinaryOperator(A, BinOp);
10179
10180 if (isa<PHINode>(I) || isa<LoadInst>(I))
10181 return updateWithInstruction(A, I);
10182
10183 return indicatePessimisticFixpoint();
10184 }
10185
10186 /// See AbstractAttribute::trackStatistics()
10187 void trackStatistics() const override {
10188 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10189 }
10190};
10191
10192struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10193 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10194 : AAPotentialConstantValuesImpl(IRP, A) {}
10195
10196 /// See AbstractAttribute::initialize(...).
10197 ChangeStatus updateImpl(Attributor &A) override {
10199 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10200 "not be called");
10201 }
10202
10203 /// See AbstractAttribute::trackStatistics()
10204 void trackStatistics() const override {
10205 STATS_DECLTRACK_FN_ATTR(potential_values)
10206 }
10207};
10208
10209struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10210 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10211 : AAPotentialConstantValuesFunction(IRP, A) {}
10212
10213 /// See AbstractAttribute::trackStatistics()
10214 void trackStatistics() const override {
10215 STATS_DECLTRACK_CS_ATTR(potential_values)
10216 }
10217};
10218
10219struct AAPotentialConstantValuesCallSiteReturned
10220 : AACalleeToCallSite<AAPotentialConstantValues,
10221 AAPotentialConstantValuesImpl> {
10222 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10223 Attributor &A)
10224 : AACalleeToCallSite<AAPotentialConstantValues,
10225 AAPotentialConstantValuesImpl>(IRP, A) {}
10226
10227 /// See AbstractAttribute::trackStatistics()
10228 void trackStatistics() const override {
10229 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10230 }
10231};
10232
10233struct AAPotentialConstantValuesCallSiteArgument
10234 : AAPotentialConstantValuesFloating {
10235 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10236 Attributor &A)
10237 : AAPotentialConstantValuesFloating(IRP, A) {}
10238
10239 /// See AbstractAttribute::initialize(..).
10240 void initialize(Attributor &A) override {
10241 AAPotentialConstantValuesImpl::initialize(A);
10242 if (isAtFixpoint())
10243 return;
10244
10245 Value &V = getAssociatedValue();
10246
10247 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10248 unionAssumed(C->getValue());
10249 indicateOptimisticFixpoint();
10250 return;
10251 }
10252
10253 if (isa<UndefValue>(&V)) {
10254 unionAssumedWithUndef();
10255 indicateOptimisticFixpoint();
10256 return;
10257 }
10258 }
10259
10260 /// See AbstractAttribute::updateImpl(...).
10261 ChangeStatus updateImpl(Attributor &A) override {
10262 Value &V = getAssociatedValue();
10263 auto AssumedBefore = getAssumed();
10264 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10265 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10266 if (!AA)
10267 return indicatePessimisticFixpoint();
10268 const auto &S = AA->getAssumed();
10269 unionAssumed(S);
10270 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10271 : ChangeStatus::CHANGED;
10272 }
10273
10274 /// See AbstractAttribute::trackStatistics()
10275 void trackStatistics() const override {
10276 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10277 }
10278};
10279} // namespace
10280
10281/// ------------------------ NoUndef Attribute ---------------------------------
10283 Attribute::AttrKind ImpliedAttributeKind,
10284 bool IgnoreSubsumingPositions) {
10285 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10286 "Unexpected attribute kind");
10287 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10288 Attribute::NoUndef))
10289 return true;
10290
10291 Value &Val = IRP.getAssociatedValue();
10294 LLVMContext &Ctx = Val.getContext();
10295 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10296 return true;
10297 }
10298
10299 return false;
10300}
10301
10302namespace {
10303struct AANoUndefImpl : AANoUndef {
10304 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10305
10306 /// See AbstractAttribute::initialize(...).
10307 void initialize(Attributor &A) override {
10308 Value &V = getAssociatedValue();
10309 if (isa<UndefValue>(V))
10310 indicatePessimisticFixpoint();
10311 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10312 }
10313
10314 /// See followUsesInMBEC
10315 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10316 AANoUndef::StateType &State) {
10317 const Value *UseV = U->get();
10318 const DominatorTree *DT = nullptr;
10319 AssumptionCache *AC = nullptr;
10320 InformationCache &InfoCache = A.getInfoCache();
10321 if (Function *F = getAnchorScope()) {
10322 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10323 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10324 }
10325 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10326 bool TrackUse = false;
10327 // Track use for instructions which must produce undef or poison bits when
10328 // at least one operand contains such bits.
10330 TrackUse = true;
10331 return TrackUse;
10332 }
10333
10334 /// See AbstractAttribute::getAsStr().
10335 const std::string getAsStr(Attributor *A) const override {
10336 return getAssumed() ? "noundef" : "may-undef-or-poison";
10337 }
10338
10339 ChangeStatus manifest(Attributor &A) override {
10340 // We don't manifest noundef attribute for dead positions because the
10341 // associated values with dead positions would be replaced with undef
10342 // values.
10343 bool UsedAssumedInformation = false;
10344 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10345 UsedAssumedInformation))
10346 return ChangeStatus::UNCHANGED;
10347 // A position whose simplified value does not have any value is
10348 // considered to be dead. We don't manifest noundef in such positions for
10349 // the same reason above.
10350 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10352 .has_value())
10353 return ChangeStatus::UNCHANGED;
10354 return AANoUndef::manifest(A);
10355 }
10356};
10357
10358struct AANoUndefFloating : public AANoUndefImpl {
10359 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10360 : AANoUndefImpl(IRP, A) {}
10361
10362 /// See AbstractAttribute::initialize(...).
10363 void initialize(Attributor &A) override {
10364 AANoUndefImpl::initialize(A);
10365 if (!getState().isAtFixpoint() && getAnchorScope() &&
10366 !getAnchorScope()->isDeclaration())
10367 if (Instruction *CtxI = getCtxI())
10368 followUsesInMBEC(*this, A, getState(), *CtxI);
10369 }
10370
10371 /// See AbstractAttribute::updateImpl(...).
10372 ChangeStatus updateImpl(Attributor &A) override {
10373 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10374 bool IsKnownNoUndef;
10376 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10377 };
10378
10379 bool Stripped;
10380 bool UsedAssumedInformation = false;
10381 Value *AssociatedValue = &getAssociatedValue();
10383 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10384 AA::AnyScope, UsedAssumedInformation))
10385 Stripped = false;
10386 else
10387 Stripped =
10388 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10389
10390 if (!Stripped) {
10391 // If we haven't stripped anything we might still be able to use a
10392 // different AA, but only if the IRP changes. Effectively when we
10393 // interpret this not as a call site value but as a floating/argument
10394 // value.
10395 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10396 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10397 return indicatePessimisticFixpoint();
10398 return ChangeStatus::UNCHANGED;
10399 }
10400
10401 for (const auto &VAC : Values)
10402 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10403 return indicatePessimisticFixpoint();
10404
10405 return ChangeStatus::UNCHANGED;
10406 }
10407
10408 /// See AbstractAttribute::trackStatistics()
10409 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10410};
10411
10412struct AANoUndefReturned final
10413 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10414 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10415 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10416
10417 /// See AbstractAttribute::trackStatistics()
10418 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10419};
10420
10421struct AANoUndefArgument final
10422 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10423 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10424 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10425
10426 /// See AbstractAttribute::trackStatistics()
10427 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10428};
10429
10430struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10431 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10432 : AANoUndefFloating(IRP, A) {}
10433
10434 /// See AbstractAttribute::trackStatistics()
10435 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10436};
10437
10438struct AANoUndefCallSiteReturned final
10439 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10440 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10441 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10442
10443 /// See AbstractAttribute::trackStatistics()
10444 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10445};
10446
10447/// ------------------------ NoFPClass Attribute -------------------------------
10448
10449struct AANoFPClassImpl : AANoFPClass {
10450 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10451
10452 void initialize(Attributor &A) override {
10453 const IRPosition &IRP = getIRPosition();
10454
10455 Value &V = IRP.getAssociatedValue();
10456 if (isa<UndefValue>(V)) {
10457 indicateOptimisticFixpoint();
10458 return;
10459 }
10460
10462 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10463 for (const auto &Attr : Attrs) {
10464 addKnownBits(Attr.getNoFPClass());
10465 }
10466
10467 const DataLayout &DL = A.getDataLayout();
10468 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10469 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL);
10470 addKnownBits(~KnownFPClass.KnownFPClasses);
10471 }
10472
10473 if (Instruction *CtxI = getCtxI())
10474 followUsesInMBEC(*this, A, getState(), *CtxI);
10475 }
10476
10477 /// See followUsesInMBEC
10478 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10479 AANoFPClass::StateType &State) {
10480 // TODO: Determine what instructions can be looked through.
10481 auto *CB = dyn_cast<CallBase>(I);
10482 if (!CB)
10483 return false;
10484
10485 if (!CB->isArgOperand(U))
10486 return false;
10487
10488 unsigned ArgNo = CB->getArgOperandNo(U);
10489 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10490 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10491 State.addKnownBits(NoFPAA->getState().getKnown());
10492 return false;
10493 }
10494
10495 const std::string getAsStr(Attributor *A) const override {
10496 std::string Result = "nofpclass";
10497 raw_string_ostream OS(Result);
10498 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10499 return Result;
10500 }
10501
10502 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10503 SmallVectorImpl<Attribute> &Attrs) const override {
10504 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10505 }
10506};
10507
10508struct AANoFPClassFloating : public AANoFPClassImpl {
10509 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10510 : AANoFPClassImpl(IRP, A) {}
10511
10512 /// See AbstractAttribute::updateImpl(...).
10513 ChangeStatus updateImpl(Attributor &A) override {
10515 bool UsedAssumedInformation = false;
10516 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10517 AA::AnyScope, UsedAssumedInformation)) {
10518 Values.push_back({getAssociatedValue(), getCtxI()});
10519 }
10520
10521 StateType T;
10522 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10523 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10524 DepClassTy::REQUIRED);
10525 if (!AA || this == AA) {
10526 T.indicatePessimisticFixpoint();
10527 } else {
10528 const AANoFPClass::StateType &S =
10529 static_cast<const AANoFPClass::StateType &>(AA->getState());
10530 T ^= S;
10531 }
10532 return T.isValidState();
10533 };
10534
10535 for (const auto &VAC : Values)
10536 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10537 return indicatePessimisticFixpoint();
10538
10539 return clampStateAndIndicateChange(getState(), T);
10540 }
10541
10542 /// See AbstractAttribute::trackStatistics()
10543 void trackStatistics() const override {
10545 }
10546};
10547
10548struct AANoFPClassReturned final
10549 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10550 AANoFPClassImpl::StateType, false,
10551 Attribute::None, false> {
10552 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10553 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10554 AANoFPClassImpl::StateType, false,
10555 Attribute::None, false>(IRP, A) {}
10556
10557 /// See AbstractAttribute::trackStatistics()
10558 void trackStatistics() const override {
10560 }
10561};
10562
10563struct AANoFPClassArgument final
10564 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10565 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10566 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10567
10568 /// See AbstractAttribute::trackStatistics()
10569 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10570};
10571
10572struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10573 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10574 : AANoFPClassFloating(IRP, A) {}
10575
10576 /// See AbstractAttribute::trackStatistics()
10577 void trackStatistics() const override {
10579 }
10580};
10581
10582struct AANoFPClassCallSiteReturned final
10583 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10584 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10585 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10586
10587 /// See AbstractAttribute::trackStatistics()
10588 void trackStatistics() const override {
10590 }
10591};
10592
10593struct AACallEdgesImpl : public AACallEdges {
10594 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10595
10596 const SetVector<Function *> &getOptimisticEdges() const override {
10597 return CalledFunctions;
10598 }
10599
10600 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10601
10602 bool hasNonAsmUnknownCallee() const override {
10603 return HasUnknownCalleeNonAsm;
10604 }
10605
10606 const std::string getAsStr(Attributor *A) const override {
10607 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10608 std::to_string(CalledFunctions.size()) + "]";
10609 }
10610
10611 void trackStatistics() const override {}
10612
10613protected:
10614 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10615 if (CalledFunctions.insert(Fn)) {
10616 Change = ChangeStatus::CHANGED;
10617 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10618 << "\n");
10619 }
10620 }
10621
10622 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10623 if (!HasUnknownCallee)
10624 Change = ChangeStatus::CHANGED;
10625 if (NonAsm && !HasUnknownCalleeNonAsm)
10626 Change = ChangeStatus::CHANGED;
10627 HasUnknownCalleeNonAsm |= NonAsm;
10628 HasUnknownCallee = true;
10629 }
10630
10631private:
10632 /// Optimistic set of functions that might be called by this position.
10633 SetVector<Function *> CalledFunctions;
10634
10635 /// Is there any call with a unknown callee.
10636 bool HasUnknownCallee = false;
10637
10638 /// Is there any call with a unknown callee, excluding any inline asm.
10639 bool HasUnknownCalleeNonAsm = false;
10640};
10641
10642struct AACallEdgesCallSite : public AACallEdgesImpl {
10643 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10644 : AACallEdgesImpl(IRP, A) {}
10645 /// See AbstractAttribute::updateImpl(...).
10646 ChangeStatus updateImpl(Attributor &A) override {
10647 ChangeStatus Change = ChangeStatus::UNCHANGED;
10648
10649 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10650 if (Function *Fn = dyn_cast<Function>(&V)) {
10651 addCalledFunction(Fn, Change);
10652 } else {
10653 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10654 setHasUnknownCallee(true, Change);
10655 }
10656
10657 // Explore all values.
10658 return true;
10659 };
10660
10662 // Process any value that we might call.
10663 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10664 if (isa<Constant>(V)) {
10665 VisitValue(*V, CtxI);
10666 return;
10667 }
10668
10669 bool UsedAssumedInformation = false;
10670 Values.clear();
10671 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10672 AA::AnyScope, UsedAssumedInformation)) {
10673 Values.push_back({*V, CtxI});
10674 }
10675 for (auto &VAC : Values)
10676 VisitValue(*VAC.getValue(), VAC.getCtxI());
10677 };
10678
10679 CallBase *CB = cast<CallBase>(getCtxI());
10680
10681 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10682 if (IA->hasSideEffects() &&
10683 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10684 !hasAssumption(*CB, "ompx_no_call_asm")) {
10685 setHasUnknownCallee(false, Change);
10686 }
10687 return Change;
10688 }
10689
10690 if (CB->isIndirectCall())
10691 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10692 *this, getIRPosition(), DepClassTy::OPTIONAL))
10693 if (IndirectCallAA->foreachCallee(
10694 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10695 return Change;
10696
10697 // The most simple case.
10698 ProcessCalledOperand(CB->getCalledOperand(), CB);
10699
10700 // Process callback functions.
10701 SmallVector<const Use *, 4u> CallbackUses;
10702 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10703 for (const Use *U : CallbackUses)
10704 ProcessCalledOperand(U->get(), CB);
10705
10706 return Change;
10707 }
10708};
10709
10710struct AACallEdgesFunction : public AACallEdgesImpl {
10711 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10712 : AACallEdgesImpl(IRP, A) {}
10713
10714 /// See AbstractAttribute::updateImpl(...).
10715 ChangeStatus updateImpl(Attributor &A) override {
10716 ChangeStatus Change = ChangeStatus::UNCHANGED;
10717
10718 auto ProcessCallInst = [&](Instruction &Inst) {
10719 CallBase &CB = cast<CallBase>(Inst);
10720
10721 auto *CBEdges = A.getAAFor<AACallEdges>(
10722 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10723 if (!CBEdges)
10724 return false;
10725 if (CBEdges->hasNonAsmUnknownCallee())
10726 setHasUnknownCallee(true, Change);
10727 if (CBEdges->hasUnknownCallee())
10728 setHasUnknownCallee(false, Change);
10729
10730 for (Function *F : CBEdges->getOptimisticEdges())
10731 addCalledFunction(F, Change);
10732
10733 return true;
10734 };
10735
10736 // Visit all callable instructions.
10737 bool UsedAssumedInformation = false;
10738 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10739 UsedAssumedInformation,
10740 /* CheckBBLivenessOnly */ true)) {
10741 // If we haven't looked at all call like instructions, assume that there
10742 // are unknown callees.
10743 setHasUnknownCallee(true, Change);
10744 }
10745
10746 return Change;
10747 }
10748};
10749
10750/// -------------------AAInterFnReachability Attribute--------------------------
10751
10752struct AAInterFnReachabilityFunction
10753 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10754 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10755 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10756 : Base(IRP, A) {}
10757
10758 bool instructionCanReach(
10759 Attributor &A, const Instruction &From, const Function &To,
10760 const AA::InstExclusionSetTy *ExclusionSet) const override {
10761 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10762 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10763
10764 RQITy StackRQI(A, From, To, ExclusionSet, false);
10765 RQITy::Reachable Result;
10766 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10767 return NonConstThis->isReachableImpl(A, StackRQI,
10768 /*IsTemporaryRQI=*/true);
10769 return Result == RQITy::Reachable::Yes;
10770 }
10771
10772 bool isReachableImpl(Attributor &A, RQITy &RQI,
10773 bool IsTemporaryRQI) override {
10774 const Instruction *EntryI =
10775 &RQI.From->getFunction()->getEntryBlock().front();
10776 if (EntryI != RQI.From &&
10777 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10778 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10779 IsTemporaryRQI);
10780
10781 auto CheckReachableCallBase = [&](CallBase *CB) {
10782 auto *CBEdges = A.getAAFor<AACallEdges>(
10783 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10784 if (!CBEdges || !CBEdges->getState().isValidState())
10785 return false;
10786 // TODO Check To backwards in this case.
10787 if (CBEdges->hasUnknownCallee())
10788 return false;
10789
10790 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10791 if (Fn == RQI.To)
10792 return false;
10793
10794 if (Fn->isDeclaration()) {
10795 if (Fn->hasFnAttribute(Attribute::NoCallback))
10796 continue;
10797 // TODO Check To backwards in this case.
10798 return false;
10799 }
10800
10801 if (Fn == getAnchorScope()) {
10802 if (EntryI == RQI.From)
10803 continue;
10804 return false;
10805 }
10806
10807 const AAInterFnReachability *InterFnReachability =
10808 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10809 DepClassTy::OPTIONAL);
10810
10811 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10812 if (!InterFnReachability ||
10813 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10814 RQI.ExclusionSet))
10815 return false;
10816 }
10817 return true;
10818 };
10819
10820 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10821 *this, IRPosition::function(*RQI.From->getFunction()),
10822 DepClassTy::OPTIONAL);
10823
10824 // Determine call like instructions that we can reach from the inst.
10825 auto CheckCallBase = [&](Instruction &CBInst) {
10826 // There are usually less nodes in the call graph, check inter function
10827 // reachability first.
10828 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10829 return true;
10830 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10831 A, *RQI.From, CBInst, RQI.ExclusionSet);
10832 };
10833
10834 bool UsedExclusionSet = /* conservative */ true;
10835 bool UsedAssumedInformation = false;
10836 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10837 UsedAssumedInformation,
10838 /* CheckBBLivenessOnly */ true))
10839 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10840 IsTemporaryRQI);
10841
10842 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10843 IsTemporaryRQI);
10844 }
10845
10846 void trackStatistics() const override {}
10847};
10848} // namespace
10849
10850template <typename AAType>
10851static std::optional<Constant *>
10853 const IRPosition &IRP, Type &Ty) {
10854 if (!Ty.isIntegerTy())
10855 return nullptr;
10856
10857 // This will also pass the call base context.
10858 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10859 if (!AA)
10860 return nullptr;
10861
10862 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10863
10864 if (!COpt.has_value()) {
10865 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10866 return std::nullopt;
10867 }
10868 if (auto *C = *COpt) {
10869 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10870 return C;
10871 }
10872 return nullptr;
10873}
10874
10876 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10878 Type &Ty = *IRP.getAssociatedType();
10879 std::optional<Value *> V;
10880 for (auto &It : Values) {
10881 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10882 if (V.has_value() && !*V)
10883 break;
10884 }
10885 if (!V.has_value())
10886 return UndefValue::get(&Ty);
10887 return *V;
10888}
10889
10890namespace {
10891struct AAPotentialValuesImpl : AAPotentialValues {
10892 using StateType = PotentialLLVMValuesState;
10893
10894 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10895 : AAPotentialValues(IRP, A) {}
10896
10897 /// See AbstractAttribute::initialize(..).
10898 void initialize(Attributor &A) override {
10899 if (A.hasSimplificationCallback(getIRPosition())) {
10900 indicatePessimisticFixpoint();
10901 return;
10902 }
10903 Value *Stripped = getAssociatedValue().stripPointerCasts();
10904 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10905 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10906 getAnchorScope());
10907 indicateOptimisticFixpoint();
10908 return;
10909 }
10910 AAPotentialValues::initialize(A);
10911 }
10912
10913 /// See AbstractAttribute::getAsStr().
10914 const std::string getAsStr(Attributor *A) const override {
10915 std::string Str;
10916 llvm::raw_string_ostream OS(Str);
10917 OS << getState();
10918 return Str;
10919 }
10920
10921 template <typename AAType>
10922 static std::optional<Value *> askOtherAA(Attributor &A,
10923 const AbstractAttribute &AA,
10924 const IRPosition &IRP, Type &Ty) {
10926 return &IRP.getAssociatedValue();
10927 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10928 if (!C)
10929 return std::nullopt;
10930 if (*C)
10931 if (auto *CC = AA::getWithType(**C, Ty))
10932 return CC;
10933 return nullptr;
10934 }
10935
10936 virtual void addValue(Attributor &A, StateType &State, Value &V,
10937 const Instruction *CtxI, AA::ValueScope S,
10938 Function *AnchorScope) const {
10939
10940 IRPosition ValIRP = IRPosition::value(V);
10941 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10942 for (const auto &U : CB->args()) {
10943 if (U.get() != &V)
10944 continue;
10945 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10946 break;
10947 }
10948 }
10949
10950 Value *VPtr = &V;
10951 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10952 Type &Ty = *getAssociatedType();
10953 std::optional<Value *> SimpleV =
10954 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10955 if (SimpleV.has_value() && !*SimpleV) {
10956 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10957 *this, ValIRP, DepClassTy::OPTIONAL);
10958 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10959 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10960 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10961 if (PotentialConstantsAA->undefIsContained())
10962 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10963 return;
10964 }
10965 }
10966 if (!SimpleV.has_value())
10967 return;
10968
10969 if (*SimpleV)
10970 VPtr = *SimpleV;
10971 }
10972
10973 if (isa<ConstantInt>(VPtr))
10974 CtxI = nullptr;
10975 if (!AA::isValidInScope(*VPtr, AnchorScope))
10977
10978 State.unionAssumed({{*VPtr, CtxI}, S});
10979 }
10980
10981 /// Helper struct to tie a value+context pair together with the scope for
10982 /// which this is the simplified version.
10983 struct ItemInfo {
10984 AA::ValueAndContext I;
10986
10987 bool operator==(const ItemInfo &II) const {
10988 return II.I == I && II.S == S;
10989 };
10990 bool operator<(const ItemInfo &II) const {
10991 return std::tie(I, S) < std::tie(II.I, II.S);
10992 };
10993 };
10994
10995 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10996 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
10997 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10998 if (!(CS & S))
10999 continue;
11000
11001 bool UsedAssumedInformation = false;
11003 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11004 UsedAssumedInformation))
11005 return false;
11006
11007 for (auto &It : Values)
11008 ValueScopeMap[It] += CS;
11009 }
11010 for (auto &It : ValueScopeMap)
11011 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11012 AA::ValueScope(It.second), getAnchorScope());
11013
11014 return true;
11015 }
11016
11017 void giveUpOnIntraprocedural(Attributor &A) {
11018 auto NewS = StateType::getBestState(getState());
11019 for (const auto &It : getAssumedSet()) {
11020 if (It.second == AA::Intraprocedural)
11021 continue;
11022 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11023 AA::Interprocedural, getAnchorScope());
11024 }
11025 assert(!undefIsContained() && "Undef should be an explicit value!");
11026 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11027 getAnchorScope());
11028 getState() = NewS;
11029 }
11030
11031 /// See AbstractState::indicatePessimisticFixpoint(...).
11032 ChangeStatus indicatePessimisticFixpoint() override {
11033 getState() = StateType::getBestState(getState());
11034 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11035 AAPotentialValues::indicateOptimisticFixpoint();
11036 return ChangeStatus::CHANGED;
11037 }
11038
11039 /// See AbstractAttribute::updateImpl(...).
11040 ChangeStatus updateImpl(Attributor &A) override {
11041 return indicatePessimisticFixpoint();
11042 }
11043
11044 /// See AbstractAttribute::manifest(...).
11045 ChangeStatus manifest(Attributor &A) override {
11048 Values.clear();
11049 if (!getAssumedSimplifiedValues(A, Values, S))
11050 continue;
11051 Value &OldV = getAssociatedValue();
11052 if (isa<UndefValue>(OldV))
11053 continue;
11054 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11055 if (!NewV || NewV == &OldV)
11056 continue;
11057 if (getCtxI() &&
11058 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11059 continue;
11060 if (A.changeAfterManifest(getIRPosition(), *NewV))
11061 return ChangeStatus::CHANGED;
11062 }
11063 return ChangeStatus::UNCHANGED;
11064 }
11065
11066 bool getAssumedSimplifiedValues(
11067 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11068 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11069 if (!isValidState())
11070 return false;
11071 bool UsedAssumedInformation = false;
11072 for (const auto &It : getAssumedSet())
11073 if (It.second & S) {
11074 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11075 isa<SelectInst>(It.first.getValue()))) {
11076 if (A.getAssumedSimplifiedValues(
11077 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11078 this, Values, S, UsedAssumedInformation))
11079 continue;
11080 }
11081 Values.push_back(It.first);
11082 }
11083 assert(!undefIsContained() && "Undef should be an explicit value!");
11084 return true;
11085 }
11086};
11087
11088struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11089 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11090 : AAPotentialValuesImpl(IRP, A) {}
11091
11092 /// See AbstractAttribute::updateImpl(...).
11093 ChangeStatus updateImpl(Attributor &A) override {
11094 auto AssumedBefore = getAssumed();
11095
11096 genericValueTraversal(A, &getAssociatedValue());
11097
11098 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11099 : ChangeStatus::CHANGED;
11100 }
11101
11102 /// Helper struct to remember which AAIsDead instances we actually used.
11103 struct LivenessInfo {
11104 const AAIsDead *LivenessAA = nullptr;
11105 bool AnyDead = false;
11106 };
11107
11108 /// Check if \p Cmp is a comparison we can simplify.
11109 ///
11110 /// We handle multiple cases, one in which at least one operand is an
11111 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11112 /// operand. Return true if successful, in that case Worklist will be updated.
11113 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11114 CmpInst::Predicate Pred, ItemInfo II,
11115 SmallVectorImpl<ItemInfo> &Worklist) {
11116
11117 // Simplify the operands first.
11118 bool UsedAssumedInformation = false;
11119 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11120 auto GetSimplifiedValues = [&](Value &V,
11122 if (!A.getAssumedSimplifiedValues(
11123 IRPosition::value(V, getCallBaseContext()), this, Values,
11124 AA::Intraprocedural, UsedAssumedInformation)) {
11125 Values.clear();
11126 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11127 }
11128 return Values.empty();
11129 };
11130 if (GetSimplifiedValues(*LHS, LHSValues))
11131 return true;
11132 if (GetSimplifiedValues(*RHS, RHSValues))
11133 return true;
11134
11135 LLVMContext &Ctx = LHS->getContext();
11136
11137 InformationCache &InfoCache = A.getInfoCache();
11138 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11139 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11140 const auto *DT =
11141 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11142 : nullptr;
11143 const auto *TLI =
11144 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11145 auto *AC =
11146 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11147 : nullptr;
11148
11149 const DataLayout &DL = A.getDataLayout();
11150 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11151
11152 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11153 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11154 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11155 /* CtxI */ nullptr, II.S, getAnchorScope());
11156 return true;
11157 }
11158
11159 // Handle the trivial case first in which we don't even need to think
11160 // about null or non-null.
11161 if (&LHSV == &RHSV &&
11163 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11165 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11166 getAnchorScope());
11167 return true;
11168 }
11169
11170 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11171 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11172 if (TypedLHS && TypedRHS) {
11173 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11174 if (NewV && NewV != &Cmp) {
11175 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11176 getAnchorScope());
11177 return true;
11178 }
11179 }
11180
11181 // From now on we only handle equalities (==, !=).
11182 if (!CmpInst::isEquality(Pred))
11183 return false;
11184
11185 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11186 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11187 if (!LHSIsNull && !RHSIsNull)
11188 return false;
11189
11190 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11191 // non-nullptr operand and if we assume it's non-null we can conclude the
11192 // result of the comparison.
11193 assert((LHSIsNull || RHSIsNull) &&
11194 "Expected nullptr versus non-nullptr comparison at this point");
11195
11196 // The index is the operand that we assume is not null.
11197 unsigned PtrIdx = LHSIsNull;
11198 bool IsKnownNonNull;
11199 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11200 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11201 DepClassTy::REQUIRED, IsKnownNonNull);
11202 if (!IsAssumedNonNull)
11203 return false;
11204
11205 // The new value depends on the predicate, true for != and false for ==.
11206 Constant *NewV =
11207 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11208 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11209 getAnchorScope());
11210 return true;
11211 };
11212
11213 for (auto &LHSValue : LHSValues)
11214 for (auto &RHSValue : RHSValues)
11215 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11216 return false;
11217 return true;
11218 }
11219
11220 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11221 SmallVectorImpl<ItemInfo> &Worklist) {
11222 const Instruction *CtxI = II.I.getCtxI();
11223 bool UsedAssumedInformation = false;
11224
11225 std::optional<Constant *> C =
11226 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11227 bool NoValueYet = !C.has_value();
11228 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11229 return true;
11230 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11231 if (CI->isZero())
11232 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11233 else
11234 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11235 } else if (&SI == &getAssociatedValue()) {
11236 // We could not simplify the condition, assume both values.
11237 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11238 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11239 } else {
11240 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11241 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11242 if (!SimpleV.has_value())
11243 return true;
11244 if (*SimpleV) {
11245 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11246 return true;
11247 }
11248 return false;
11249 }
11250 return true;
11251 }
11252
11253 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11254 SmallVectorImpl<ItemInfo> &Worklist) {
11255 SmallSetVector<Value *, 4> PotentialCopies;
11256 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11257 bool UsedAssumedInformation = false;
11258 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11259 PotentialValueOrigins, *this,
11260 UsedAssumedInformation,
11261 /* OnlyExact */ true)) {
11262 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11263 "loaded values for load instruction "
11264 << LI << "\n");
11265 return false;
11266 }
11267
11268 // Do not simplify loads that are only used in llvm.assume if we cannot also
11269 // remove all stores that may feed into the load. The reason is that the
11270 // assume is probably worth something as long as the stores are around.
11271 InformationCache &InfoCache = A.getInfoCache();
11272 if (InfoCache.isOnlyUsedByAssume(LI)) {
11273 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11274 if (!I || isa<AssumeInst>(I))
11275 return true;
11276 if (auto *SI = dyn_cast<StoreInst>(I))
11277 return A.isAssumedDead(SI->getOperandUse(0), this,
11278 /* LivenessAA */ nullptr,
11279 UsedAssumedInformation,
11280 /* CheckBBLivenessOnly */ false);
11281 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11282 UsedAssumedInformation,
11283 /* CheckBBLivenessOnly */ false);
11284 })) {
11285 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11286 "and we cannot delete all the stores: "
11287 << LI << "\n");
11288 return false;
11289 }
11290 }
11291
11292 // Values have to be dynamically unique or we loose the fact that a
11293 // single llvm::Value might represent two runtime values (e.g.,
11294 // stack locations in different recursive calls).
11295 const Instruction *CtxI = II.I.getCtxI();
11296 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11297 bool AllLocal = ScopeIsLocal;
11298 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11299 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11300 return AA::isDynamicallyUnique(A, *this, *PC);
11301 });
11302 if (!DynamicallyUnique) {
11303 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11304 "values are dynamically unique: "
11305 << LI << "\n");
11306 return false;
11307 }
11308
11309 for (auto *PotentialCopy : PotentialCopies) {
11310 if (AllLocal) {
11311 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11312 } else {
11313 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11314 }
11315 }
11316 if (!AllLocal && ScopeIsLocal)
11317 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11318 return true;
11319 }
11320
11321 bool handlePHINode(
11322 Attributor &A, PHINode &PHI, ItemInfo II,
11323 SmallVectorImpl<ItemInfo> &Worklist,
11324 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11325 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11326 LivenessInfo &LI = LivenessAAs[&F];
11327 if (!LI.LivenessAA)
11328 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11329 DepClassTy::NONE);
11330 return LI;
11331 };
11332
11333 if (&PHI == &getAssociatedValue()) {
11334 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11335 const auto *CI =
11336 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11337 *PHI.getFunction());
11338
11339 Cycle *C = nullptr;
11340 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11341 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11342 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11343 if (LI.LivenessAA &&
11344 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11345 LI.AnyDead = true;
11346 continue;
11347 }
11348 Value *V = PHI.getIncomingValue(u);
11349 if (V == &PHI)
11350 continue;
11351
11352 // If the incoming value is not the PHI but an instruction in the same
11353 // cycle we might have multiple versions of it flying around.
11354 if (CyclePHI && isa<Instruction>(V) &&
11355 (!C || C->contains(cast<Instruction>(V)->getParent())))
11356 return false;
11357
11358 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11359 }
11360 return true;
11361 }
11362
11363 bool UsedAssumedInformation = false;
11364 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11365 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11366 if (!SimpleV.has_value())
11367 return true;
11368 if (!(*SimpleV))
11369 return false;
11370 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11371 return true;
11372 }
11373
11374 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11375 /// simplify any operand of the instruction \p I. Return true if successful,
11376 /// in that case Worklist will be updated.
11377 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11378 SmallVectorImpl<ItemInfo> &Worklist) {
11379 bool SomeSimplified = false;
11380 bool UsedAssumedInformation = false;
11381
11382 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11383 int Idx = 0;
11384 for (Value *Op : I.operands()) {
11385 const auto &SimplifiedOp = A.getAssumedSimplified(
11386 IRPosition::value(*Op, getCallBaseContext()), *this,
11387 UsedAssumedInformation, AA::Intraprocedural);
11388 // If we are not sure about any operand we are not sure about the entire
11389 // instruction, we'll wait.
11390 if (!SimplifiedOp.has_value())
11391 return true;
11392
11393 if (*SimplifiedOp)
11394 NewOps[Idx] = *SimplifiedOp;
11395 else
11396 NewOps[Idx] = Op;
11397
11398 SomeSimplified |= (NewOps[Idx] != Op);
11399 ++Idx;
11400 }
11401
11402 // We won't bother with the InstSimplify interface if we didn't simplify any
11403 // operand ourselves.
11404 if (!SomeSimplified)
11405 return false;
11406
11407 InformationCache &InfoCache = A.getInfoCache();
11408 Function *F = I.getFunction();
11409 const auto *DT =
11410 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11411 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11412 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11413
11414 const DataLayout &DL = I.getDataLayout();
11415 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11416 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11417 if (!NewV || NewV == &I)
11418 return false;
11419
11420 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11421 << *NewV << "\n");
11422 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11423 return true;
11424 }
11425
11427 Attributor &A, Instruction &I, ItemInfo II,
11428 SmallVectorImpl<ItemInfo> &Worklist,
11429 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11430 if (auto *CI = dyn_cast<CmpInst>(&I))
11431 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11432 CI->getPredicate(), II, Worklist);
11433
11434 switch (I.getOpcode()) {
11435 case Instruction::Select:
11436 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11437 case Instruction::PHI:
11438 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11439 case Instruction::Load:
11440 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11441 default:
11442 return handleGenericInst(A, I, II, Worklist);
11443 };
11444 return false;
11445 }
11446
11447 void genericValueTraversal(Attributor &A, Value *InitialV) {
11448 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11449
11450 SmallSet<ItemInfo, 16> Visited;
11452 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11453
11454 int Iteration = 0;
11455 do {
11456 ItemInfo II = Worklist.pop_back_val();
11457 Value *V = II.I.getValue();
11458 assert(V);
11459 const Instruction *CtxI = II.I.getCtxI();
11460 AA::ValueScope S = II.S;
11461
11462 // Check if we should process the current value. To prevent endless
11463 // recursion keep a record of the values we followed!
11464 if (!Visited.insert(II).second)
11465 continue;
11466
11467 // Make sure we limit the compile time for complex expressions.
11468 if (Iteration++ >= MaxPotentialValuesIterations) {
11469 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11470 << Iteration << "!\n");
11471 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11472 continue;
11473 }
11474
11475 // Explicitly look through calls with a "returned" attribute if we do
11476 // not have a pointer as stripPointerCasts only works on them.
11477 Value *NewV = nullptr;
11478 if (V->getType()->isPointerTy()) {
11479 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11480 } else {
11481 if (auto *CB = dyn_cast<CallBase>(V))
11482 if (auto *Callee =
11484 for (Argument &Arg : Callee->args())
11485 if (Arg.hasReturnedAttr()) {
11486 NewV = CB->getArgOperand(Arg.getArgNo());
11487 break;
11488 }
11489 }
11490 }
11491 if (NewV && NewV != V) {
11492 Worklist.push_back({{*NewV, CtxI}, S});
11493 continue;
11494 }
11495
11496 if (auto *I = dyn_cast<Instruction>(V)) {
11497 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11498 continue;
11499 }
11500
11501 if (V != InitialV || isa<Argument>(V))
11502 if (recurseForValue(A, IRPosition::value(*V), II.S))
11503 continue;
11504
11505 // If we haven't stripped anything we give up.
11506 if (V == InitialV && CtxI == getCtxI()) {
11507 indicatePessimisticFixpoint();
11508 return;
11509 }
11510
11511 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11512 } while (!Worklist.empty());
11513
11514 // If we actually used liveness information so we have to record a
11515 // dependence.
11516 for (auto &It : LivenessAAs)
11517 if (It.second.AnyDead)
11518 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11519 }
11520
11521 /// See AbstractAttribute::trackStatistics()
11522 void trackStatistics() const override {
11523 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11524 }
11525};
11526
11527struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11528 using Base = AAPotentialValuesImpl;
11529 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11530 : Base(IRP, A) {}
11531
11532 /// See AbstractAttribute::initialize(..).
11533 void initialize(Attributor &A) override {
11534 auto &Arg = cast<Argument>(getAssociatedValue());
11536 indicatePessimisticFixpoint();
11537 }
11538
11539 /// See AbstractAttribute::updateImpl(...).
11540 ChangeStatus updateImpl(Attributor &A) override {
11541 auto AssumedBefore = getAssumed();
11542
11543 unsigned ArgNo = getCalleeArgNo();
11544
11545 bool UsedAssumedInformation = false;
11547 auto CallSitePred = [&](AbstractCallSite ACS) {
11548 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11549 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11550 return false;
11551
11552 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11554 UsedAssumedInformation))
11555 return false;
11556
11557 return isValidState();
11558 };
11559
11560 if (!A.checkForAllCallSites(CallSitePred, *this,
11561 /* RequireAllCallSites */ true,
11562 UsedAssumedInformation))
11563 return indicatePessimisticFixpoint();
11564
11565 Function *Fn = getAssociatedFunction();
11566 bool AnyNonLocal = false;
11567 for (auto &It : Values) {
11568 if (isa<Constant>(It.getValue())) {
11569 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11570 getAnchorScope());
11571 continue;
11572 }
11573 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11574 return indicatePessimisticFixpoint();
11575
11576 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11577 if (Arg->getParent() == Fn) {
11578 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11579 getAnchorScope());
11580 continue;
11581 }
11582 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11583 getAnchorScope());
11584 AnyNonLocal = true;
11585 }
11586 assert(!undefIsContained() && "Undef should be an explicit value!");
11587 if (AnyNonLocal)
11588 giveUpOnIntraprocedural(A);
11589
11590 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11591 : ChangeStatus::CHANGED;
11592 }
11593
11594 /// See AbstractAttribute::trackStatistics()
11595 void trackStatistics() const override {
11596 STATS_DECLTRACK_ARG_ATTR(potential_values)
11597 }
11598};
11599
11600struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11601 using Base = AAPotentialValuesFloating;
11602 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11603 : Base(IRP, A) {}
11604
11605 /// See AbstractAttribute::initialize(..).
11606 void initialize(Attributor &A) override {
11607 Function *F = getAssociatedFunction();
11608 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11609 indicatePessimisticFixpoint();
11610 return;
11611 }
11612
11613 for (Argument &Arg : F->args())
11614 if (Arg.hasReturnedAttr()) {
11615 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11616 ReturnedArg = &Arg;
11617 break;
11618 }
11619 if (!A.isFunctionIPOAmendable(*F) ||
11620 A.hasSimplificationCallback(getIRPosition())) {
11621 if (!ReturnedArg)
11622 indicatePessimisticFixpoint();
11623 else
11624 indicateOptimisticFixpoint();
11625 }
11626 }
11627
11628 /// See AbstractAttribute::updateImpl(...).
11629 ChangeStatus updateImpl(Attributor &A) override {
11630 auto AssumedBefore = getAssumed();
11631 bool UsedAssumedInformation = false;
11632
11634 Function *AnchorScope = getAnchorScope();
11635 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11636 bool AddValues) {
11638 Values.clear();
11639 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11640 UsedAssumedInformation,
11641 /* RecurseForSelectAndPHI */ true))
11642 return false;
11643 if (!AddValues)
11644 continue;
11645
11646 bool AllInterAreIntra = false;
11647 if (S == AA::Interprocedural)
11648 AllInterAreIntra =
11649 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11650 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11651 });
11652
11653 for (const AA::ValueAndContext &VAC : Values) {
11654 addValue(A, getState(), *VAC.getValue(),
11655 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11656 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11657 }
11658 if (AllInterAreIntra)
11659 break;
11660 }
11661 return true;
11662 };
11663
11664 if (ReturnedArg) {
11665 HandleReturnedValue(*ReturnedArg, nullptr, true);
11666 } else {
11667 auto RetInstPred = [&](Instruction &RetI) {
11668 bool AddValues = true;
11669 if (isa<PHINode>(RetI.getOperand(0)) ||
11670 isa<SelectInst>(RetI.getOperand(0))) {
11671 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11672 AnchorScope);
11673 AddValues = false;
11674 }
11675 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11676 };
11677
11678 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11679 UsedAssumedInformation,
11680 /* CheckBBLivenessOnly */ true))
11681 return indicatePessimisticFixpoint();
11682 }
11683
11684 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11685 : ChangeStatus::CHANGED;
11686 }
11687
11688 ChangeStatus manifest(Attributor &A) override {
11689 if (ReturnedArg)
11690 return ChangeStatus::UNCHANGED;
11692 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11693 /* RecurseForSelectAndPHI */ true))
11694 return ChangeStatus::UNCHANGED;
11695 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11696 if (!NewVal)
11697 return ChangeStatus::UNCHANGED;
11698
11699 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11700 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11701 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11702 "Number of function with unique return");
11703 Changed |= A.manifestAttrs(
11705 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11706 STATS_DECLTRACK_ARG_ATTR(returned);
11707 }
11708
11709 auto RetInstPred = [&](Instruction &RetI) {
11710 Value *RetOp = RetI.getOperand(0);
11711 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11712 return true;
11713 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11714 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11715 Changed = ChangeStatus::CHANGED;
11716 return true;
11717 };
11718 bool UsedAssumedInformation = false;
11719 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11720 UsedAssumedInformation,
11721 /* CheckBBLivenessOnly */ true);
11722 return Changed;
11723 }
11724
11725 ChangeStatus indicatePessimisticFixpoint() override {
11726 return AAPotentialValues::indicatePessimisticFixpoint();
11727 }
11728
11729 /// See AbstractAttribute::trackStatistics()
11730 void trackStatistics() const override{
11731 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11732
11733 /// The argumented with an existing `returned` attribute.
11734 Argument *ReturnedArg = nullptr;
11735};
11736
11737struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11738 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11739 : AAPotentialValuesImpl(IRP, A) {}
11740
11741 /// See AbstractAttribute::updateImpl(...).
11742 ChangeStatus updateImpl(Attributor &A) override {
11743 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11744 "not be called");
11745 }
11746
11747 /// See AbstractAttribute::trackStatistics()
11748 void trackStatistics() const override {
11749 STATS_DECLTRACK_FN_ATTR(potential_values)
11750 }
11751};
11752
11753struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11754 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11755 : AAPotentialValuesFunction(IRP, A) {}
11756
11757 /// See AbstractAttribute::trackStatistics()
11758 void trackStatistics() const override {
11759 STATS_DECLTRACK_CS_ATTR(potential_values)
11760 }
11761};
11762
11763struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11764 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11765 : AAPotentialValuesImpl(IRP, A) {}
11766
11767 /// See AbstractAttribute::updateImpl(...).
11768 ChangeStatus updateImpl(Attributor &A) override {
11769 auto AssumedBefore = getAssumed();
11770
11771 Function *Callee = getAssociatedFunction();
11772 if (!Callee)
11773 return indicatePessimisticFixpoint();
11774
11775 bool UsedAssumedInformation = false;
11776 auto *CB = cast<CallBase>(getCtxI());
11777 if (CB->isMustTailCall() &&
11778 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11779 UsedAssumedInformation))
11780 return indicatePessimisticFixpoint();
11781
11782 Function *Caller = CB->getCaller();
11783
11784 auto AddScope = [&](AA::ValueScope S) {
11786 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11787 Values, S, UsedAssumedInformation))
11788 return false;
11789
11790 for (auto &It : Values) {
11791 Value *V = It.getValue();
11792 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11793 V, *CB, *this, UsedAssumedInformation);
11794 if (!CallerV.has_value()) {
11795 // Nothing to do as long as no value was determined.
11796 continue;
11797 }
11798 V = *CallerV ? *CallerV : V;
11799 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11800 if (recurseForValue(A, IRPosition::value(*V), S))
11801 continue;
11802 }
11803 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11804 giveUpOnIntraprocedural(A);
11805 return true;
11806 }
11807 addValue(A, getState(), *V, CB, S, getAnchorScope());
11808 }
11809 return true;
11810 };
11811 if (!AddScope(AA::Intraprocedural))
11812 return indicatePessimisticFixpoint();
11813 if (!AddScope(AA::Interprocedural))
11814 return indicatePessimisticFixpoint();
11815 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11816 : ChangeStatus::CHANGED;
11817 }
11818
11819 ChangeStatus indicatePessimisticFixpoint() override {
11820 return AAPotentialValues::indicatePessimisticFixpoint();
11821 }
11822
11823 /// See AbstractAttribute::trackStatistics()
11824 void trackStatistics() const override {
11825 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11826 }
11827};
11828
11829struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11830 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11831 : AAPotentialValuesFloating(IRP, A) {}
11832
11833 /// See AbstractAttribute::trackStatistics()
11834 void trackStatistics() const override {
11835 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11836 }
11837};
11838} // namespace
11839
11840/// ---------------------- Assumption Propagation ------------------------------
11841namespace {
11842struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11843 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11844 const DenseSet<StringRef> &Known)
11845 : AAAssumptionInfo(IRP, A, Known) {}
11846
11847 /// See AbstractAttribute::manifest(...).
11848 ChangeStatus manifest(Attributor &A) override {
11849 // Don't manifest a universal set if it somehow made it here.
11850 if (getKnown().isUniversal())
11851 return ChangeStatus::UNCHANGED;
11852
11853 const IRPosition &IRP = getIRPosition();
11854 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11855 getAssumed().getSet().end());
11856 llvm::sort(Set);
11857 return A.manifestAttrs(IRP,
11858 Attribute::get(IRP.getAnchorValue().getContext(),
11860 llvm::join(Set, ",")),
11861 /*ForceReplace=*/true);
11862 }
11863
11864 bool hasAssumption(const StringRef Assumption) const override {
11865 return isValidState() && setContains(Assumption);
11866 }
11867
11868 /// See AbstractAttribute::getAsStr()
11869 const std::string getAsStr(Attributor *A) const override {
11870 const SetContents &Known = getKnown();
11871 const SetContents &Assumed = getAssumed();
11872
11873 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11874 llvm::sort(Set);
11875 const std::string KnownStr = llvm::join(Set, ",");
11876
11877 std::string AssumedStr = "Universal";
11878 if (!Assumed.isUniversal()) {
11879 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11880 AssumedStr = llvm::join(Set, ",");
11881 }
11882 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11883 }
11884};
11885
11886/// Propagates assumption information from parent functions to all of their
11887/// successors. An assumption can be propagated if the containing function
11888/// dominates the called function.
11889///
11890/// We start with a "known" set of assumptions already valid for the associated
11891/// function and an "assumed" set that initially contains all possible
11892/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11893/// contents as concrete values are known. The concrete values are seeded by the
11894/// first nodes that are either entries into the call graph, or contains no
11895/// assumptions. Each node is updated as the intersection of the assumed state
11896/// with all of its predecessors.
11897struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11898 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11899 : AAAssumptionInfoImpl(IRP, A,
11900 getAssumptions(*IRP.getAssociatedFunction())) {}
11901
11902 /// See AbstractAttribute::updateImpl(...).
11903 ChangeStatus updateImpl(Attributor &A) override {
11904 bool Changed = false;
11905
11906 auto CallSitePred = [&](AbstractCallSite ACS) {
11907 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11908 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11909 DepClassTy::REQUIRED);
11910 if (!AssumptionAA)
11911 return false;
11912 // Get the set of assumptions shared by all of this function's callers.
11913 Changed |= getIntersection(AssumptionAA->getAssumed());
11914 return !getAssumed().empty() || !getKnown().empty();
11915 };
11916
11917 bool UsedAssumedInformation = false;
11918 // Get the intersection of all assumptions held by this node's predecessors.
11919 // If we don't know all the call sites then this is either an entry into the
11920 // call graph or an empty node. This node is known to only contain its own
11921 // assumptions and can be propagated to its successors.
11922 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11923 UsedAssumedInformation))
11924 return indicatePessimisticFixpoint();
11925
11926 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11927 }
11928
11929 void trackStatistics() const override {}
11930};
11931
11932/// Assumption Info defined for call sites.
11933struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11934
11935 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11936 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11937
11938 /// See AbstractAttribute::initialize(...).
11939 void initialize(Attributor &A) override {
11940 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11941 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11942 }
11943
11944 /// See AbstractAttribute::updateImpl(...).
11945 ChangeStatus updateImpl(Attributor &A) override {
11946 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11947 auto *AssumptionAA =
11948 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11949 if (!AssumptionAA)
11950 return indicatePessimisticFixpoint();
11951 bool Changed = getIntersection(AssumptionAA->getAssumed());
11952 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11953 }
11954
11955 /// See AbstractAttribute::trackStatistics()
11956 void trackStatistics() const override {}
11957
11958private:
11959 /// Helper to initialized the known set as all the assumptions this call and
11960 /// the callee contain.
11961 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11962 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11963 auto Assumptions = getAssumptions(CB);
11964 if (const Function *F = CB.getCaller())
11965 set_union(Assumptions, getAssumptions(*F));
11966 if (Function *F = IRP.getAssociatedFunction())
11967 set_union(Assumptions, getAssumptions(*F));
11968 return Assumptions;
11969 }
11970};
11971} // namespace
11972
11974 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11975 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11976}
11977
11979
11980/// ------------------------ UnderlyingObjects ---------------------------------
11981
11982namespace {
11983struct AAUnderlyingObjectsImpl
11984 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11986 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11987
11988 /// See AbstractAttribute::getAsStr().
11989 const std::string getAsStr(Attributor *A) const override {
11990 if (!isValidState())
11991 return "<invalid>";
11992 std::string Str;
11994 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
11995 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
11996 << " objects.\n";
11997 if (!InterAssumedUnderlyingObjects.empty()) {
11998 OS << "inter objects:\n";
11999 for (auto *Obj : InterAssumedUnderlyingObjects)
12000 OS << *Obj << '\n';
12001 }
12002 if (!IntraAssumedUnderlyingObjects.empty()) {
12003 OS << "intra objects:\n";
12004 for (auto *Obj : IntraAssumedUnderlyingObjects)
12005 OS << *Obj << '\n';
12006 }
12007 return Str;
12008 }
12009
12010 /// See AbstractAttribute::trackStatistics()
12011 void trackStatistics() const override {}
12012
12013 /// See AbstractAttribute::updateImpl(...).
12014 ChangeStatus updateImpl(Attributor &A) override {
12015 auto &Ptr = getAssociatedValue();
12016
12017 bool UsedAssumedInformation = false;
12018 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12020 SmallPtrSet<Value *, 8> SeenObjects;
12022
12023 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12024 Scope, UsedAssumedInformation))
12025 return UnderlyingObjects.insert(&Ptr);
12026
12027 bool Changed = false;
12028
12029 for (unsigned I = 0; I < Values.size(); ++I) {
12030 auto &VAC = Values[I];
12031 auto *Obj = VAC.getValue();
12032 Value *UO = getUnderlyingObject(Obj);
12033 if (!SeenObjects.insert(UO ? UO : Obj).second)
12034 continue;
12035 if (UO && UO != Obj) {
12036 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12037 Changed |= UnderlyingObjects.insert(UO);
12038 continue;
12039 }
12040
12041 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12042 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12043 auto Pred = [&](Value &V) {
12044 if (&V == UO)
12045 Changed |= UnderlyingObjects.insert(UO);
12046 else
12047 Values.emplace_back(V, nullptr);
12048 return true;
12049 };
12050
12051 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12053 "The forall call should not return false at this position");
12054 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12055 continue;
12056 }
12057
12058 if (isa<SelectInst>(Obj)) {
12059 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12060 UsedAssumedInformation);
12061 continue;
12062 }
12063 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12064 // Explicitly look through PHIs as we do not care about dynamically
12065 // uniqueness.
12066 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12067 Changed |=
12068 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12069 Scope, UsedAssumedInformation);
12070 }
12071 continue;
12072 }
12073
12074 Changed |= UnderlyingObjects.insert(Obj);
12075 }
12076
12077 return Changed;
12078 };
12079
12080 bool Changed = false;
12081 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12082 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12083 if (!UsedAssumedInformation)
12084 indicateOptimisticFixpoint();
12085 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12086 }
12087
12088 bool forallUnderlyingObjects(
12089 function_ref<bool(Value &)> Pred,
12090 AA::ValueScope Scope = AA::Interprocedural) const override {
12091 if (!isValidState())
12092 return Pred(getAssociatedValue());
12093
12094 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12095 ? IntraAssumedUnderlyingObjects
12096 : InterAssumedUnderlyingObjects;
12097 for (Value *Obj : AssumedUnderlyingObjects)
12098 if (!Pred(*Obj))
12099 return false;
12100
12101 return true;
12102 }
12103
12104private:
12105 /// Handle the case where the value is not the actual underlying value, such
12106 /// as a phi node or a select instruction.
12107 bool handleIndirect(Attributor &A, Value &V,
12108 SmallSetVector<Value *, 8> &UnderlyingObjects,
12109 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12110 bool Changed = false;
12111 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12112 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12113 auto Pred = [&](Value &V) {
12114 Changed |= UnderlyingObjects.insert(&V);
12115 return true;
12116 };
12117 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12119 "The forall call should not return false at this position");
12120 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12121 return Changed;
12122 }
12123
12124 /// All the underlying objects collected so far via intra procedural scope.
12125 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12126 /// All the underlying objects collected so far via inter procedural scope.
12127 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12128};
12129
12130struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12131 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12132 : AAUnderlyingObjectsImpl(IRP, A) {}
12133};
12134
12135struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12136 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12137 : AAUnderlyingObjectsImpl(IRP, A) {}
12138};
12139
12140struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12141 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12142 : AAUnderlyingObjectsImpl(IRP, A) {}
12143};
12144
12145struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12146 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12147 : AAUnderlyingObjectsImpl(IRP, A) {}
12148};
12149
12150struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12151 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12152 : AAUnderlyingObjectsImpl(IRP, A) {}
12153};
12154
12155struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12156 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12157 : AAUnderlyingObjectsImpl(IRP, A) {}
12158};
12159
12160struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12161 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12162 : AAUnderlyingObjectsImpl(IRP, A) {}
12163};
12164} // namespace
12165
12166/// ------------------------ Global Value Info -------------------------------
12167namespace {
12168struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12169 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12170 : AAGlobalValueInfo(IRP, A) {}
12171
12172 /// See AbstractAttribute::initialize(...).
12173 void initialize(Attributor &A) override {}
12174
12175 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12176 SmallVectorImpl<const Value *> &Worklist) {
12177 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12178 if (!UInst) {
12179 Follow = true;
12180 return true;
12181 }
12182
12183 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12184 << *UInst << "\n");
12185
12186 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12187 int Idx = &Cmp->getOperandUse(0) == &U;
12188 if (isa<Constant>(Cmp->getOperand(Idx)))
12189 return true;
12190 return U == &getAnchorValue();
12191 }
12192
12193 // Explicitly catch return instructions.
12194 if (isa<ReturnInst>(UInst)) {
12195 auto CallSitePred = [&](AbstractCallSite ACS) {
12196 Worklist.push_back(ACS.getInstruction());
12197 return true;
12198 };
12199 bool UsedAssumedInformation = false;
12200 // TODO: We should traverse the uses or add a "non-call-site" CB.
12201 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12202 /*RequireAllCallSites=*/true, this,
12203 UsedAssumedInformation))
12204 return false;
12205 return true;
12206 }
12207
12208 // For now we only use special logic for call sites. However, the tracker
12209 // itself knows about a lot of other non-capturing cases already.
12210 auto *CB = dyn_cast<CallBase>(UInst);
12211 if (!CB)
12212 return false;
12213 // Direct calls are OK uses.
12214 if (CB->isCallee(&U))
12215 return true;
12216 // Non-argument uses are scary.
12217 if (!CB->isArgOperand(&U))
12218 return false;
12219 // TODO: Iterate callees.
12220 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12221 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12222 return false;
12223
12224 unsigned ArgNo = CB->getArgOperandNo(&U);
12225 Worklist.push_back(Fn->getArg(ArgNo));
12226 return true;
12227 }
12228
12229 ChangeStatus updateImpl(Attributor &A) override {
12230 unsigned NumUsesBefore = Uses.size();
12231
12232 SmallPtrSet<const Value *, 8> Visited;
12234 Worklist.push_back(&getAnchorValue());
12235
12236 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12237 Uses.insert(&U);
12238 // TODO(captures): Make this more precise.
12239 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12240 if (CI.isPassthrough()) {
12241 Follow = true;
12242 return true;
12243 }
12244 return checkUse(A, U, Follow, Worklist);
12245 };
12246 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12247 Uses.insert(&OldU);
12248 return true;
12249 };
12250
12251 while (!Worklist.empty()) {
12252 const Value *V = Worklist.pop_back_val();
12253 if (!Visited.insert(V).second)
12254 continue;
12255 if (!A.checkForAllUses(UsePred, *this, *V,
12256 /* CheckBBLivenessOnly */ true,
12257 DepClassTy::OPTIONAL,
12258 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12259 return indicatePessimisticFixpoint();
12260 }
12261 }
12262
12263 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12264 : ChangeStatus::CHANGED;
12265 }
12266
12267 bool isPotentialUse(const Use &U) const override {
12268 return !isValidState() || Uses.contains(&U);
12269 }
12270
12271 /// See AbstractAttribute::manifest(...).
12272 ChangeStatus manifest(Attributor &A) override {
12273 return ChangeStatus::UNCHANGED;
12274 }
12275
12276 /// See AbstractAttribute::getAsStr().
12277 const std::string getAsStr(Attributor *A) const override {
12278 return "[" + std::to_string(Uses.size()) + " uses]";
12279 }
12280
12281 void trackStatistics() const override {
12282 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12283 }
12284
12285private:
12286 /// Set of (transitive) uses of this GlobalValue.
12287 SmallPtrSet<const Use *, 8> Uses;
12288};
12289} // namespace
12290
12291/// ------------------------ Indirect Call Info -------------------------------
12292namespace {
12293struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12294 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12295 : AAIndirectCallInfo(IRP, A) {}
12296
12297 /// See AbstractAttribute::initialize(...).
12298 void initialize(Attributor &A) override {
12299 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12300 if (!MD && !A.isClosedWorldModule())
12301 return;
12302
12303 if (MD) {
12304 for (const auto &Op : MD->operands())
12305 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12306 PotentialCallees.insert(Callee);
12307 } else if (A.isClosedWorldModule()) {
12308 ArrayRef<Function *> IndirectlyCallableFunctions =
12309 A.getInfoCache().getIndirectlyCallableFunctions(A);
12310 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12311 }
12312
12313 if (PotentialCallees.empty())
12314 indicateOptimisticFixpoint();
12315 }
12316
12317 ChangeStatus updateImpl(Attributor &A) override {
12318 CallBase *CB = cast<CallBase>(getCtxI());
12319 const Use &CalleeUse = CB->getCalledOperandUse();
12320 Value *FP = CB->getCalledOperand();
12321
12322 SmallSetVector<Function *, 4> AssumedCalleesNow;
12323 bool AllCalleesKnownNow = AllCalleesKnown;
12324
12325 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12326 bool &UsedAssumedInformation) {
12327 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12328 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12329 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12330 return true;
12331 UsedAssumedInformation = !GIAA->isAtFixpoint();
12332 return false;
12333 };
12334
12335 auto AddPotentialCallees = [&]() {
12336 for (auto *PotentialCallee : PotentialCallees) {
12337 bool UsedAssumedInformation = false;
12338 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12339 AssumedCalleesNow.insert(PotentialCallee);
12340 }
12341 };
12342
12343 // Use simplification to find potential callees, if !callees was present,
12344 // fallback to that set if necessary.
12345 bool UsedAssumedInformation = false;
12347 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12348 AA::ValueScope::AnyScope,
12349 UsedAssumedInformation)) {
12350 if (PotentialCallees.empty())
12351 return indicatePessimisticFixpoint();
12352 AddPotentialCallees();
12353 }
12354
12355 // Try to find a reason for \p Fn not to be a potential callee. If none was
12356 // found, add it to the assumed callees set.
12357 auto CheckPotentialCallee = [&](Function &Fn) {
12358 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12359 return false;
12360
12361 auto &CachedResult = FilterResults[&Fn];
12362 if (CachedResult.has_value())
12363 return CachedResult.value();
12364
12365 bool UsedAssumedInformation = false;
12366 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12367 if (!UsedAssumedInformation)
12368 CachedResult = false;
12369 return false;
12370 }
12371
12372 int NumFnArgs = Fn.arg_size();
12373 int NumCBArgs = CB->arg_size();
12374
12375 // Check if any excess argument (which we fill up with poison) is known to
12376 // be UB on undef.
12377 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12378 bool IsKnown = false;
12380 A, this, IRPosition::argument(*Fn.getArg(I)),
12381 DepClassTy::OPTIONAL, IsKnown)) {
12382 if (IsKnown)
12383 CachedResult = false;
12384 return false;
12385 }
12386 }
12387
12388 CachedResult = true;
12389 return true;
12390 };
12391
12392 // Check simplification result, prune known UB callees, also restrict it to
12393 // the !callees set, if present.
12394 for (auto &VAC : Values) {
12395 if (isa<UndefValue>(VAC.getValue()))
12396 continue;
12397 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12398 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12399 continue;
12400 // TODO: Check for known UB, e.g., poison + noundef.
12401 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12402 if (CheckPotentialCallee(*VACFn))
12403 AssumedCalleesNow.insert(VACFn);
12404 continue;
12405 }
12406 if (!PotentialCallees.empty()) {
12407 AddPotentialCallees();
12408 break;
12409 }
12410 AllCalleesKnownNow = false;
12411 }
12412
12413 if (AssumedCalleesNow == AssumedCallees &&
12414 AllCalleesKnown == AllCalleesKnownNow)
12415 return ChangeStatus::UNCHANGED;
12416
12417 std::swap(AssumedCallees, AssumedCalleesNow);
12418 AllCalleesKnown = AllCalleesKnownNow;
12419 return ChangeStatus::CHANGED;
12420 }
12421
12422 /// See AbstractAttribute::manifest(...).
12423 ChangeStatus manifest(Attributor &A) override {
12424 // If we can't specialize at all, give up now.
12425 if (!AllCalleesKnown && AssumedCallees.empty())
12426 return ChangeStatus::UNCHANGED;
12427
12428 CallBase *CB = cast<CallBase>(getCtxI());
12429 bool UsedAssumedInformation = false;
12430 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12431 UsedAssumedInformation))
12432 return ChangeStatus::UNCHANGED;
12433
12434 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12435 Value *FP = CB->getCalledOperand();
12436 if (FP->getType()->getPointerAddressSpace())
12437 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12438 FP->getName() + ".as0", CB->getIterator());
12439
12440 bool CBIsVoid = CB->getType()->isVoidTy();
12442 FunctionType *CSFT = CB->getFunctionType();
12443 SmallVector<Value *> CSArgs(CB->args());
12444
12445 // If we know all callees and there are none, the call site is (effectively)
12446 // dead (or UB).
12447 if (AssumedCallees.empty()) {
12448 assert(AllCalleesKnown &&
12449 "Expected all callees to be known if there are none.");
12450 A.changeToUnreachableAfterManifest(CB);
12451 return ChangeStatus::CHANGED;
12452 }
12453
12454 // Special handling for the single callee case.
12455 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12456 auto *NewCallee = AssumedCallees.front();
12457 if (isLegalToPromote(*CB, NewCallee)) {
12458 promoteCall(*CB, NewCallee, nullptr);
12459 NumIndirectCallsPromoted++;
12460 return ChangeStatus::CHANGED;
12461 }
12462 Instruction *NewCall =
12463 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12464 CB->getName(), CB->getIterator());
12465 if (!CBIsVoid)
12466 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12467 A.deleteAfterManifest(*CB);
12468 return ChangeStatus::CHANGED;
12469 }
12470
12471 // For each potential value we create a conditional
12472 //
12473 // ```
12474 // if (ptr == value) value(args);
12475 // else ...
12476 // ```
12477 //
12478 bool SpecializedForAnyCallees = false;
12479 bool SpecializedForAllCallees = AllCalleesKnown;
12480 ICmpInst *LastCmp = nullptr;
12481 SmallVector<Function *, 8> SkippedAssumedCallees;
12483 for (Function *NewCallee : AssumedCallees) {
12484 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12485 AssumedCallees.size())) {
12486 SkippedAssumedCallees.push_back(NewCallee);
12487 SpecializedForAllCallees = false;
12488 continue;
12489 }
12490 SpecializedForAnyCallees = true;
12491
12492 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12493 Instruction *ThenTI =
12494 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12495 BasicBlock *CBBB = CB->getParent();
12496 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12497 A.registerManifestAddedBasicBlock(*IP->getParent());
12498 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12499 BasicBlock *ElseBB;
12500 if (&*IP == CB) {
12501 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12502 ThenTI->getFunction(), CBBB);
12503 A.registerManifestAddedBasicBlock(*ElseBB);
12504 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12505 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12506 } else {
12507 ElseBB = IP->getParent();
12508 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12509 }
12510 CastInst *RetBC = nullptr;
12511 CallInst *NewCall = nullptr;
12512 if (isLegalToPromote(*CB, NewCallee)) {
12513 auto *CBClone = cast<CallBase>(CB->clone());
12514 CBClone->insertBefore(ThenTI->getIterator());
12515 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12516 NumIndirectCallsPromoted++;
12517 } else {
12518 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12519 CB->getName(), ThenTI->getIterator());
12520 }
12521 NewCalls.push_back({NewCall, RetBC});
12522 }
12523
12524 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12525 if (!AllCalleesKnown)
12526 return ChangeStatus::UNCHANGED;
12527 MDBuilder MDB(IndirectCB.getContext());
12528 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12529 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12530 return ChangeStatus::CHANGED;
12531 };
12532
12533 if (!SpecializedForAnyCallees)
12534 return AttachCalleeMetadata(*CB);
12535
12536 // Check if we need the fallback indirect call still.
12537 if (SpecializedForAllCallees) {
12539 LastCmp->eraseFromParent();
12540 new UnreachableInst(IP->getContext(), IP);
12541 IP->eraseFromParent();
12542 } else {
12543 auto *CBClone = cast<CallInst>(CB->clone());
12544 CBClone->setName(CB->getName());
12545 CBClone->insertBefore(*IP->getParent(), IP);
12546 NewCalls.push_back({CBClone, nullptr});
12547 AttachCalleeMetadata(*CBClone);
12548 }
12549
12550 // Check if we need a PHI to merge the results.
12551 if (!CBIsVoid) {
12552 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12553 CB->getName() + ".phi",
12554 CB->getParent()->getFirstInsertionPt());
12555 for (auto &It : NewCalls) {
12556 CallBase *NewCall = It.first;
12557 Instruction *CallRet = It.second ? It.second : It.first;
12558 if (CallRet->getType() == CB->getType())
12559 PHI->addIncoming(CallRet, CallRet->getParent());
12560 else if (NewCall->getType()->isVoidTy())
12561 PHI->addIncoming(PoisonValue::get(CB->getType()),
12562 NewCall->getParent());
12563 else
12564 llvm_unreachable("Call return should match or be void!");
12565 }
12566 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12567 }
12568
12569 A.deleteAfterManifest(*CB);
12570 Changed = ChangeStatus::CHANGED;
12571
12572 return Changed;
12573 }
12574
12575 /// See AbstractAttribute::getAsStr().
12576 const std::string getAsStr(Attributor *A) const override {
12577 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12578 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12579 " functions";
12580 }
12581
12582 void trackStatistics() const override {
12583 if (AllCalleesKnown) {
12585 Eliminated, CallSites,
12586 "Number of indirect call sites eliminated via specialization")
12587 } else {
12588 STATS_DECLTRACK(Specialized, CallSites,
12589 "Number of indirect call sites specialized")
12590 }
12591 }
12592
12593 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12594 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12595 }
12596
12597private:
12598 /// Map to remember filter results.
12599 DenseMap<Function *, std::optional<bool>> FilterResults;
12600
12601 /// If the !callee metadata was present, this set will contain all potential
12602 /// callees (superset).
12603 SmallSetVector<Function *, 4> PotentialCallees;
12604
12605 /// This set contains all currently assumed calllees, which might grow over
12606 /// time.
12607 SmallSetVector<Function *, 4> AssumedCallees;
12608
12609 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12610 /// if there could be others.
12611 bool AllCalleesKnown = true;
12612};
12613} // namespace
12614
12615/// --------------------- Invariant Load Pointer -------------------------------
12616namespace {
12617
12618struct AAInvariantLoadPointerImpl
12619 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12620 AAInvariantLoadPointer> {
12621
12622 enum {
12623 // pointer does not alias within the bounds of the function
12624 IS_NOALIAS = 1 << 0,
12625 // pointer is not involved in any effectful instructions within the bounds
12626 // of the function
12627 IS_NOEFFECT = 1 << 1,
12628 // loads are invariant within the bounds of the function
12629 IS_LOCALLY_INVARIANT = 1 << 2,
12630 // memory lifetime is constrained within the bounds of the function
12631 IS_LOCALLY_CONSTRAINED = 1 << 3,
12632
12633 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12634 IS_LOCALLY_CONSTRAINED,
12635 };
12636 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12637
12638 using Base =
12639 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12640
12641 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12642 // pessimistic about IS_KNOWN_INVARIANT
12643 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12644 : Base(IRP) {}
12645
12646 bool isKnownInvariant() const final {
12647 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12648 }
12649
12650 bool isKnownLocallyInvariant() const final {
12651 if (isKnown(IS_LOCALLY_INVARIANT))
12652 return true;
12653 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12654 }
12655
12656 bool isAssumedInvariant() const final {
12657 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12658 }
12659
12660 bool isAssumedLocallyInvariant() const final {
12661 if (isAssumed(IS_LOCALLY_INVARIANT))
12662 return true;
12663 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12664 }
12665
12666 ChangeStatus updateImpl(Attributor &A) override {
12667 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12668
12669 Changed |= updateNoAlias(A);
12670 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12671 return indicatePessimisticFixpoint();
12672
12673 Changed |= updateNoEffect(A);
12674
12675 Changed |= updateLocalInvariance(A);
12676
12677 return Changed;
12678 }
12679
12680 ChangeStatus manifest(Attributor &A) override {
12681 if (!isKnownInvariant())
12682 return ChangeStatus::UNCHANGED;
12683
12684 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12685 const Value *Ptr = &getAssociatedValue();
12686 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12687 if (U.get() != Ptr)
12688 return true;
12689 auto *I = dyn_cast<Instruction>(U.getUser());
12690 if (!I)
12691 return true;
12692
12693 // Ensure that we are only changing uses from the corresponding callgraph
12694 // SSC in the case that the AA isn't run on the entire module
12695 if (!A.isRunOn(I->getFunction()))
12696 return true;
12697
12698 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12699 return true;
12700
12701 if (auto *LI = dyn_cast<LoadInst>(I)) {
12702 LI->setMetadata(LLVMContext::MD_invariant_load,
12703 MDNode::get(LI->getContext(), {}));
12704 Changed = ChangeStatus::CHANGED;
12705 }
12706 return true;
12707 };
12708
12709 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12710 return Changed;
12711 }
12712
12713 /// See AbstractAttribute::getAsStr().
12714 const std::string getAsStr(Attributor *) const override {
12715 if (isKnownInvariant())
12716 return "load-invariant pointer";
12717 return "non-invariant pointer";
12718 }
12719
12720 /// See AbstractAttribute::trackStatistics().
12721 void trackStatistics() const override {}
12722
12723private:
12724 /// Indicate that noalias is required for the pointer to be invariant.
12725 bool requiresNoAlias() const {
12726 switch (getPositionKind()) {
12727 default:
12728 // Conservatively default to require noalias.
12729 return true;
12730 case IRP_FLOAT:
12731 case IRP_RETURNED:
12732 case IRP_CALL_SITE:
12733 return false;
12734 case IRP_CALL_SITE_RETURNED: {
12735 const auto &CB = cast<CallBase>(getAnchorValue());
12737 &CB, /*MustPreserveNullness=*/false);
12738 }
12739 case IRP_ARGUMENT: {
12740 const Function *F = getAssociatedFunction();
12741 assert(F && "no associated function for argument");
12742 return !isCallableCC(F->getCallingConv());
12743 }
12744 }
12745 }
12746
12747 bool isExternal() const {
12748 const Function *F = getAssociatedFunction();
12749 if (!F)
12750 return true;
12751 return isCallableCC(F->getCallingConv()) &&
12752 getPositionKind() != IRP_CALL_SITE_RETURNED;
12753 }
12754
12755 ChangeStatus updateNoAlias(Attributor &A) {
12756 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12757 return ChangeStatus::UNCHANGED;
12758
12759 // Try to use AANoAlias.
12760 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12761 getIRPosition(), this, DepClassTy::REQUIRED)) {
12762 if (ANoAlias->isKnownNoAlias()) {
12763 addKnownBits(IS_NOALIAS);
12764 return ChangeStatus::CHANGED;
12765 }
12766
12767 if (!ANoAlias->isAssumedNoAlias()) {
12768 removeAssumedBits(IS_NOALIAS);
12769 return ChangeStatus::CHANGED;
12770 }
12771
12772 return ChangeStatus::UNCHANGED;
12773 }
12774
12775 // Try to infer noalias from argument attribute, since it is applicable for
12776 // the duration of the function.
12777 if (const Argument *Arg = getAssociatedArgument()) {
12778 if (Arg->hasNoAliasAttr()) {
12779 addKnownBits(IS_NOALIAS);
12780 return ChangeStatus::UNCHANGED;
12781 }
12782
12783 // Noalias information is not provided, and cannot be inferred,
12784 // so we conservatively assume the pointer aliases.
12785 removeAssumedBits(IS_NOALIAS);
12786 return ChangeStatus::CHANGED;
12787 }
12788
12789 return ChangeStatus::UNCHANGED;
12790 }
12791
12792 ChangeStatus updateNoEffect(Attributor &A) {
12793 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12794 return ChangeStatus::UNCHANGED;
12795
12796 if (!getAssociatedFunction())
12797 return indicatePessimisticFixpoint();
12798
12799 if (isa<AllocaInst>(&getAssociatedValue()))
12800 return indicatePessimisticFixpoint();
12801
12802 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12803 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12804 return !LI || !LI->mayHaveSideEffects();
12805 };
12806 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12807 return indicatePessimisticFixpoint();
12808
12809 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12810 getIRPosition(), this, DepClassTy::REQUIRED)) {
12811 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12812 // attribute
12813 if (!AMemoryBehavior->isAssumedReadOnly())
12814 return indicatePessimisticFixpoint();
12815
12816 if (AMemoryBehavior->isKnownReadOnly()) {
12817 addKnownBits(IS_NOEFFECT);
12818 return ChangeStatus::UNCHANGED;
12819 }
12820
12821 return ChangeStatus::UNCHANGED;
12822 }
12823
12824 if (const Argument *Arg = getAssociatedArgument()) {
12825 if (Arg->onlyReadsMemory()) {
12826 addKnownBits(IS_NOEFFECT);
12827 return ChangeStatus::UNCHANGED;
12828 }
12829
12830 // Readonly information is not provided, and cannot be inferred from
12831 // AAMemoryBehavior.
12832 return indicatePessimisticFixpoint();
12833 }
12834
12835 return ChangeStatus::UNCHANGED;
12836 }
12837
12838 ChangeStatus updateLocalInvariance(Attributor &A) {
12839 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12840 return ChangeStatus::UNCHANGED;
12841
12842 // try to infer invariance from underlying objects
12843 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12844 getIRPosition(), this, DepClassTy::REQUIRED);
12845 if (!AUO)
12846 return ChangeStatus::UNCHANGED;
12847
12848 bool UsedAssumedInformation = false;
12849 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12850 if (!V.getType()->isPointerTy())
12851 return true;
12852 const auto *IsInvariantLoadPointer =
12853 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12854 DepClassTy::REQUIRED);
12855 // Conservatively fail if invariance cannot be inferred.
12856 if (!IsInvariantLoadPointer)
12857 return false;
12858
12859 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12860 return true;
12861 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12862 return false;
12863
12864 UsedAssumedInformation = true;
12865 return true;
12866 };
12867 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12868 return indicatePessimisticFixpoint();
12869
12870 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12872 CB, /*MustPreserveNullness=*/false)) {
12873 for (const Value *Arg : CB->args()) {
12874 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12875 return indicatePessimisticFixpoint();
12876 }
12877 }
12878 }
12879
12880 if (!UsedAssumedInformation) {
12881 // Pointer is known and not just assumed to be locally invariant.
12882 addKnownBits(IS_LOCALLY_INVARIANT);
12883 return ChangeStatus::CHANGED;
12884 }
12885
12886 return ChangeStatus::UNCHANGED;
12887 }
12888};
12889
12890struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12891 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12892 : AAInvariantLoadPointerImpl(IRP, A) {}
12893};
12894
12895struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12896 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12897 : AAInvariantLoadPointerImpl(IRP, A) {}
12898
12899 void initialize(Attributor &) override {
12900 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12901 }
12902};
12903
12904struct AAInvariantLoadPointerCallSiteReturned final
12905 : AAInvariantLoadPointerImpl {
12906 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12907 : AAInvariantLoadPointerImpl(IRP, A) {}
12908
12909 void initialize(Attributor &A) override {
12910 const Function *F = getAssociatedFunction();
12911 assert(F && "no associated function for return from call");
12912
12913 if (!F->isDeclaration() && !F->isIntrinsic())
12914 return AAInvariantLoadPointerImpl::initialize(A);
12915
12916 const auto &CB = cast<CallBase>(getAnchorValue());
12918 &CB, /*MustPreserveNullness=*/false))
12919 return AAInvariantLoadPointerImpl::initialize(A);
12920
12921 if (F->onlyReadsMemory() && F->hasNoSync())
12922 return AAInvariantLoadPointerImpl::initialize(A);
12923
12924 // At this point, the function is opaque, so we conservatively assume
12925 // non-invariance.
12926 indicatePessimisticFixpoint();
12927 }
12928};
12929
12930struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12931 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12932 : AAInvariantLoadPointerImpl(IRP, A) {}
12933
12934 void initialize(Attributor &) override {
12935 const Function *F = getAssociatedFunction();
12936 assert(F && "no associated function for argument");
12937
12938 if (!isCallableCC(F->getCallingConv())) {
12939 addKnownBits(IS_LOCALLY_CONSTRAINED);
12940 return;
12941 }
12942
12943 if (!F->hasLocalLinkage())
12944 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12945 }
12946};
12947
12948struct AAInvariantLoadPointerCallSiteArgument final
12949 : AAInvariantLoadPointerImpl {
12950 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12951 : AAInvariantLoadPointerImpl(IRP, A) {}
12952};
12953} // namespace
12954
12955/// ------------------------ Address Space ------------------------------------
12956namespace {
12957
12958template <typename InstType>
12959static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12960 Value *OriginalValue, PointerType *NewPtrTy,
12961 bool UseOriginalValue) {
12962 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12963 return false;
12964
12965 if (MemInst->isVolatile()) {
12966 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12967 *MemInst->getFunction());
12968 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12969 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12970 return false;
12971 }
12972
12973 if (UseOriginalValue) {
12974 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
12975 return true;
12976 }
12977
12978 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12979 CastInst->insertBefore(MemInst->getIterator());
12980 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
12981 return true;
12982}
12983
12984struct AAAddressSpaceImpl : public AAAddressSpace {
12985 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12986 : AAAddressSpace(IRP, A) {}
12987
12988 uint32_t getAddressSpace() const override {
12989 assert(isValidState() && "the AA is invalid");
12990 return AssumedAddressSpace;
12991 }
12992
12993 /// See AbstractAttribute::initialize(...).
12994 void initialize(Attributor &A) override {
12995 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12996 "Associated value is not a pointer");
12997
12998 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
12999 indicatePessimisticFixpoint();
13000 return;
13001 }
13002
13003 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13004 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13005 if (AS != FlatAS) {
13006 [[maybe_unused]] bool R = takeAddressSpace(AS);
13007 assert(R && "The take should happen");
13008 indicateOptimisticFixpoint();
13009 }
13010 }
13011
13012 ChangeStatus updateImpl(Attributor &A) override {
13013 uint32_t OldAddressSpace = AssumedAddressSpace;
13014 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13015
13016 auto CheckAddressSpace = [&](Value &Obj) {
13017 // Ignore undef.
13018 if (isa<UndefValue>(&Obj))
13019 return true;
13020
13021 // If the object already has a non-flat address space, we simply take it.
13022 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13023 if (ObjAS != FlatAS)
13024 return takeAddressSpace(ObjAS);
13025
13026 // At this point, we know Obj is in the flat address space. For a final
13027 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13028 // associated function, if possible.
13029 Function *F = nullptr;
13030 if (auto *Arg = dyn_cast<Argument>(&Obj))
13031 F = Arg->getParent();
13032 else if (auto *I = dyn_cast<Instruction>(&Obj))
13033 F = I->getFunction();
13034
13035 // Use getAssumedAddrSpace if the associated function exists.
13036 if (F) {
13037 auto *TTI =
13038 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13039 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13040 if (AssumedAS != ~0U)
13041 return takeAddressSpace(AssumedAS);
13042 }
13043
13044 // Now we can't do anything else but to take the flat AS.
13045 return takeAddressSpace(FlatAS);
13046 };
13047
13048 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13049 DepClassTy::REQUIRED);
13050 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13051 return indicatePessimisticFixpoint();
13052
13053 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13054 : ChangeStatus::CHANGED;
13055 }
13056
13057 /// See AbstractAttribute::manifest(...).
13058 ChangeStatus manifest(Attributor &A) override {
13059 unsigned NewAS = getAddressSpace();
13060
13061 if (NewAS == InvalidAddressSpace ||
13062 NewAS == getAssociatedType()->getPointerAddressSpace())
13063 return ChangeStatus::UNCHANGED;
13064
13065 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13066
13067 Value *AssociatedValue = &getAssociatedValue();
13068 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13069
13070 PointerType *NewPtrTy =
13071 PointerType::get(getAssociatedType()->getContext(), NewAS);
13072 bool UseOriginalValue =
13073 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13074
13075 bool Changed = false;
13076
13077 auto Pred = [&](const Use &U, bool &) {
13078 if (U.get() != AssociatedValue)
13079 return true;
13080 auto *Inst = dyn_cast<Instruction>(U.getUser());
13081 if (!Inst)
13082 return true;
13083 // This is a WA to make sure we only change uses from the corresponding
13084 // CGSCC if the AA is run on CGSCC instead of the entire module.
13085 if (!A.isRunOn(Inst->getFunction()))
13086 return true;
13087 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13088 Changed |=
13089 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13090 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13091 Changed |=
13092 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13093 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13094 Changed |=
13095 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13096 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13097 Changed |=
13098 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13099 }
13100 return true;
13101 };
13102
13103 // It doesn't matter if we can't check all uses as we can simply
13104 // conservatively ignore those that can not be visited.
13105 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13106 /* CheckBBLivenessOnly */ true);
13107
13108 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13109 }
13110
13111 /// See AbstractAttribute::getAsStr().
13112 const std::string getAsStr(Attributor *A) const override {
13113 if (!isValidState())
13114 return "addrspace(<invalid>)";
13115 return "addrspace(" +
13116 (AssumedAddressSpace == InvalidAddressSpace
13117 ? "none"
13118 : std::to_string(AssumedAddressSpace)) +
13119 ")";
13120 }
13121
13122private:
13123 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13124
13125 bool takeAddressSpace(uint32_t AS) {
13126 if (AssumedAddressSpace == InvalidAddressSpace) {
13127 AssumedAddressSpace = AS;
13128 return true;
13129 }
13130 return AssumedAddressSpace == AS;
13131 }
13132
13133 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13134 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13135 assert(I->getSrcAddressSpace() != FlatAS &&
13136 "there should not be flat AS -> non-flat AS");
13137 return I->getPointerOperand();
13138 }
13139 if (auto *C = dyn_cast<ConstantExpr>(V))
13140 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13141 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13142 FlatAS &&
13143 "there should not be flat AS -> non-flat AS X");
13144 return C->getOperand(0);
13145 }
13146 return V;
13147 }
13148};
13149
13150struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13151 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13152 : AAAddressSpaceImpl(IRP, A) {}
13153
13154 void trackStatistics() const override {
13156 }
13157};
13158
13159struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13160 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13161 : AAAddressSpaceImpl(IRP, A) {}
13162
13163 /// See AbstractAttribute::initialize(...).
13164 void initialize(Attributor &A) override {
13165 // TODO: we don't rewrite function argument for now because it will need to
13166 // rewrite the function signature and all call sites.
13167 (void)indicatePessimisticFixpoint();
13168 }
13169
13170 void trackStatistics() const override {
13171 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13172 }
13173};
13174
13175struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13176 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13177 : AAAddressSpaceImpl(IRP, A) {}
13178
13179 void trackStatistics() const override {
13180 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13181 }
13182};
13183
13184struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13185 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13186 : AAAddressSpaceImpl(IRP, A) {}
13187
13188 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13189};
13190
13191struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13192 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13193 : AAAddressSpaceImpl(IRP, A) {}
13194
13195 /// See AbstractAttribute::initialize(...).
13196 void initialize(Attributor &A) override {
13197 // TODO: we don't rewrite call site argument for now because it will need to
13198 // rewrite the function signature of the callee.
13199 (void)indicatePessimisticFixpoint();
13200 }
13201
13202 void trackStatistics() const override {
13203 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13204 }
13205};
13206} // namespace
13207
13208/// ------------------------ No Alias Address Space ---------------------------
13209// This attribute assumes flat address space can alias all other address space
13210
13211// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13212// But merging it created failing cased on gateway test that cannot be
13213// reproduced locally. So should open a seperated PR to hande the merge of
13214// AANoAliasAddrSpace and AAAddressSpace attribute
13215
13216namespace {
13217struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13218 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13219 : AANoAliasAddrSpace(IRP, A) {}
13220
13221 void initialize(Attributor &A) override {
13222 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13223 "Associated value is not a pointer");
13224
13225 resetASRanges(A);
13226
13227 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13228 if (!FlatAS.has_value()) {
13229 indicatePessimisticFixpoint();
13230 return;
13231 }
13232
13233 removeAS(*FlatAS);
13234
13235 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13236 if (AS != *FlatAS) {
13237 removeAS(AS);
13238 indicateOptimisticFixpoint();
13239 }
13240 }
13241
13242 ChangeStatus updateImpl(Attributor &A) override {
13243 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13244 uint32_t OldAssumed = getAssumed();
13245
13246 auto CheckAddressSpace = [&](Value &Obj) {
13247 if (isa<PoisonValue>(&Obj))
13248 return true;
13249
13250 unsigned AS = Obj.getType()->getPointerAddressSpace();
13251 if (AS == FlatAS)
13252 return false;
13253
13254 removeAS(Obj.getType()->getPointerAddressSpace());
13255 return true;
13256 };
13257
13258 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13259 getIRPosition(), this, DepClassTy::REQUIRED);
13260 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13261 return indicatePessimisticFixpoint();
13262
13263 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13264 : ChangeStatus::CHANGED;
13265 }
13266
13267 /// See AbstractAttribute::manifest(...).
13268 ChangeStatus manifest(Attributor &A) override {
13269 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13270
13271 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13272 if (AS != FlatAS || Map.empty())
13273 return ChangeStatus::UNCHANGED;
13274
13275 LLVMContext &Ctx = getAssociatedValue().getContext();
13276 MDNode *NoAliasASNode = nullptr;
13277 MDBuilder MDB(Ctx);
13278 // Has to use iterator to get the range info.
13279 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13280 if (!I.value())
13281 continue;
13282 unsigned Upper = I.stop();
13283 unsigned Lower = I.start();
13284 if (!NoAliasASNode) {
13285 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13286 continue;
13287 }
13288 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13289 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13290 }
13291
13292 Value *AssociatedValue = &getAssociatedValue();
13293 bool Changed = false;
13294
13295 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13296 if (U.get() != AssociatedValue)
13297 return true;
13298 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13299 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13300 return true;
13301 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13303 return true;
13304 if (!A.isRunOn(Inst->getFunction()))
13305 return true;
13306 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13307 Changed = true;
13308 return true;
13309 };
13310 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13311 /*CheckBBLivenessOnly=*/true);
13312 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13313 }
13314
13315 /// See AbstractAttribute::getAsStr().
13316 const std::string getAsStr(Attributor *A) const override {
13317 if (!isValidState())
13318 return "<invalid>";
13319 std::string Str;
13320 raw_string_ostream OS(Str);
13321 OS << "CanNotBeAddrSpace(";
13322 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13323 unsigned Upper = I.stop();
13324 unsigned Lower = I.start();
13325 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13326 }
13327 OS << " )";
13328 return OS.str();
13329 }
13330
13331private:
13332 void removeAS(unsigned AS) {
13333 RangeMap::iterator I = Map.find(AS);
13334
13335 if (I != Map.end()) {
13336 unsigned Upper = I.stop();
13337 unsigned Lower = I.start();
13338 I.erase();
13339 if (Upper == Lower)
13340 return;
13341 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13342 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13343 if (AS != 0 && Lower <= AS - 1)
13344 Map.insert(Lower, AS - 1, true);
13345 }
13346 }
13347
13348 void resetASRanges(Attributor &A) {
13349 Map.clear();
13350 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13351 }
13352};
13353
13354struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13355 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13356 : AANoAliasAddrSpaceImpl(IRP, A) {}
13357
13358 void trackStatistics() const override {
13359 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13360 }
13361};
13362
13363struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13364 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13365 : AANoAliasAddrSpaceImpl(IRP, A) {}
13366
13367 void trackStatistics() const override {
13368 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13369 }
13370};
13371
13372struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13373 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13374 : AANoAliasAddrSpaceImpl(IRP, A) {}
13375
13376 void trackStatistics() const override {
13377 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13378 }
13379};
13380
13381struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13382 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13383 : AANoAliasAddrSpaceImpl(IRP, A) {}
13384
13385 void trackStatistics() const override {
13386 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13387 }
13388};
13389
13390struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13391 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13392 : AANoAliasAddrSpaceImpl(IRP, A) {}
13393
13394 void trackStatistics() const override {
13395 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13396 }
13397};
13398} // namespace
13399/// ----------- Allocation Info ----------
13400namespace {
13401struct AAAllocationInfoImpl : public AAAllocationInfo {
13402 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13403 : AAAllocationInfo(IRP, A) {}
13404
13405 std::optional<TypeSize> getAllocatedSize() const override {
13406 assert(isValidState() && "the AA is invalid");
13407 return AssumedAllocatedSize;
13408 }
13409
13410 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13411 const DataLayout &DL) {
13412
13413 // TODO: implement case for malloc like instructions
13414 switch (I->getOpcode()) {
13415 case Instruction::Alloca: {
13416 AllocaInst *AI = cast<AllocaInst>(I);
13417 return AI->getAllocationSize(DL);
13418 }
13419 default:
13420 return std::nullopt;
13421 }
13422 }
13423
13424 ChangeStatus updateImpl(Attributor &A) override {
13425
13426 const IRPosition &IRP = getIRPosition();
13427 Instruction *I = IRP.getCtxI();
13428
13429 // TODO: update check for malloc like calls
13430 if (!isa<AllocaInst>(I))
13431 return indicatePessimisticFixpoint();
13432
13433 bool IsKnownNoCapture;
13435 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13436 return indicatePessimisticFixpoint();
13437
13438 const AAPointerInfo *PI =
13439 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13440
13441 if (!PI)
13442 return indicatePessimisticFixpoint();
13443
13444 if (!PI->getState().isValidState() || PI->reachesReturn())
13445 return indicatePessimisticFixpoint();
13446
13447 const DataLayout &DL = A.getDataLayout();
13448 const auto AllocationSize = findInitialAllocationSize(I, DL);
13449
13450 // If allocation size is nullopt, we give up.
13451 if (!AllocationSize)
13452 return indicatePessimisticFixpoint();
13453
13454 // For zero sized allocations, we give up.
13455 // Since we can't reduce further
13456 if (*AllocationSize == 0)
13457 return indicatePessimisticFixpoint();
13458
13459 int64_t BinSize = PI->numOffsetBins();
13460
13461 // TODO: implement for multiple bins
13462 if (BinSize > 1)
13463 return indicatePessimisticFixpoint();
13464
13465 if (BinSize == 0) {
13466 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13467 if (!changeAllocationSize(NewAllocationSize))
13468 return ChangeStatus::UNCHANGED;
13469 return ChangeStatus::CHANGED;
13470 }
13471
13472 // TODO: refactor this to be part of multiple bin case
13473 const auto &It = PI->begin();
13474
13475 // TODO: handle if Offset is not zero
13476 if (It->first.Offset != 0)
13477 return indicatePessimisticFixpoint();
13478
13479 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13480
13481 if (SizeOfBin >= *AllocationSize)
13482 return indicatePessimisticFixpoint();
13483
13484 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13485
13486 if (!changeAllocationSize(NewAllocationSize))
13487 return ChangeStatus::UNCHANGED;
13488
13489 return ChangeStatus::CHANGED;
13490 }
13491
13492 /// See AbstractAttribute::manifest(...).
13493 ChangeStatus manifest(Attributor &A) override {
13494
13495 assert(isValidState() &&
13496 "Manifest should only be called if the state is valid.");
13497
13498 Instruction *I = getIRPosition().getCtxI();
13499
13500 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13501
13502 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13503
13504 switch (I->getOpcode()) {
13505 // TODO: add case for malloc like calls
13506 case Instruction::Alloca: {
13507
13508 AllocaInst *AI = cast<AllocaInst>(I);
13509
13510 Type *CharType = Type::getInt8Ty(I->getContext());
13511
13512 auto *NumBytesToValue =
13513 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13514
13515 BasicBlock::iterator insertPt = AI->getIterator();
13516 insertPt = std::next(insertPt);
13517 AllocaInst *NewAllocaInst =
13518 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13519 AI->getAlign(), AI->getName(), insertPt);
13520
13521 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13522 return ChangeStatus::CHANGED;
13523
13524 break;
13525 }
13526 default:
13527 break;
13528 }
13529
13530 return ChangeStatus::UNCHANGED;
13531 }
13532
13533 /// See AbstractAttribute::getAsStr().
13534 const std::string getAsStr(Attributor *A) const override {
13535 if (!isValidState())
13536 return "allocationinfo(<invalid>)";
13537 return "allocationinfo(" +
13538 (AssumedAllocatedSize == HasNoAllocationSize
13539 ? "none"
13540 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13541 ")";
13542 }
13543
13544private:
13545 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13546
13547 // Maintain the computed allocation size of the object.
13548 // Returns (bool) weather the size of the allocation was modified or not.
13549 bool changeAllocationSize(std::optional<TypeSize> Size) {
13550 if (AssumedAllocatedSize == HasNoAllocationSize ||
13551 AssumedAllocatedSize != Size) {
13552 AssumedAllocatedSize = Size;
13553 return true;
13554 }
13555 return false;
13556 }
13557};
13558
13559struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13560 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13561 : AAAllocationInfoImpl(IRP, A) {}
13562
13563 void trackStatistics() const override {
13564 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13565 }
13566};
13567
13568struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13569 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13570 : AAAllocationInfoImpl(IRP, A) {}
13571
13572 /// See AbstractAttribute::initialize(...).
13573 void initialize(Attributor &A) override {
13574 // TODO: we don't rewrite function argument for now because it will need to
13575 // rewrite the function signature and all call sites
13576 (void)indicatePessimisticFixpoint();
13577 }
13578
13579 void trackStatistics() const override {
13580 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13581 }
13582};
13583
13584struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13585 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13586 : AAAllocationInfoImpl(IRP, A) {}
13587
13588 void trackStatistics() const override {
13589 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13590 }
13591};
13592
13593struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13594 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13595 : AAAllocationInfoImpl(IRP, A) {}
13596
13597 void trackStatistics() const override {
13598 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13599 }
13600};
13601
13602struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13603 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13604 : AAAllocationInfoImpl(IRP, A) {}
13605
13606 /// See AbstractAttribute::initialize(...).
13607 void initialize(Attributor &A) override {
13608
13609 (void)indicatePessimisticFixpoint();
13610 }
13611
13612 void trackStatistics() const override {
13613 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13614 }
13615};
13616} // namespace
13617
13618const char AANoUnwind::ID = 0;
13619const char AANoSync::ID = 0;
13620const char AANoFree::ID = 0;
13621const char AANonNull::ID = 0;
13622const char AAMustProgress::ID = 0;
13623const char AANoRecurse::ID = 0;
13624const char AANonConvergent::ID = 0;
13625const char AAWillReturn::ID = 0;
13626const char AAUndefinedBehavior::ID = 0;
13627const char AANoAlias::ID = 0;
13628const char AAIntraFnReachability::ID = 0;
13629const char AANoReturn::ID = 0;
13630const char AAIsDead::ID = 0;
13631const char AADereferenceable::ID = 0;
13632const char AAAlign::ID = 0;
13633const char AAInstanceInfo::ID = 0;
13634const char AANoCapture::ID = 0;
13635const char AAValueSimplify::ID = 0;
13636const char AAHeapToStack::ID = 0;
13637const char AAPrivatizablePtr::ID = 0;
13638const char AAMemoryBehavior::ID = 0;
13639const char AAMemoryLocation::ID = 0;
13640const char AAValueConstantRange::ID = 0;
13641const char AAPotentialConstantValues::ID = 0;
13642const char AAPotentialValues::ID = 0;
13643const char AANoUndef::ID = 0;
13644const char AANoFPClass::ID = 0;
13645const char AACallEdges::ID = 0;
13646const char AAInterFnReachability::ID = 0;
13647const char AAPointerInfo::ID = 0;
13648const char AAAssumptionInfo::ID = 0;
13649const char AAUnderlyingObjects::ID = 0;
13650const char AAInvariantLoadPointer::ID = 0;
13651const char AAAddressSpace::ID = 0;
13652const char AANoAliasAddrSpace::ID = 0;
13653const char AAAllocationInfo::ID = 0;
13654const char AAIndirectCallInfo::ID = 0;
13655const char AAGlobalValueInfo::ID = 0;
13656const char AADenormalFPMath::ID = 0;
13657
13658// Macro magic to create the static generator function for attributes that
13659// follow the naming scheme.
13660
13661#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13662 case IRPosition::PK: \
13663 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13664
13665#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13666 case IRPosition::PK: \
13667 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13668 ++NumAAs; \
13669 break;
13670
13671#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13672 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13673 CLASS *AA = nullptr; \
13674 switch (IRP.getPositionKind()) { \
13675 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13676 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13677 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13678 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13679 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13680 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13681 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13682 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13683 } \
13684 return *AA; \
13685 }
13686
13687#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13688 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13689 CLASS *AA = nullptr; \
13690 switch (IRP.getPositionKind()) { \
13691 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13692 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13693 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13694 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13695 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13696 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13697 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13698 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13699 } \
13700 return *AA; \
13701 }
13702
13703#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13704 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13705 CLASS *AA = nullptr; \
13706 switch (IRP.getPositionKind()) { \
13707 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13708 default: \
13709 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13710 " position!"); \
13711 } \
13712 return *AA; \
13713 }
13714
13715#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13716 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13717 CLASS *AA = nullptr; \
13718 switch (IRP.getPositionKind()) { \
13719 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13720 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13721 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13722 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13723 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13724 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13725 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13726 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13727 } \
13728 return *AA; \
13729 }
13730
13731#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13732 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13733 CLASS *AA = nullptr; \
13734 switch (IRP.getPositionKind()) { \
13735 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13736 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13737 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13738 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13739 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13740 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13741 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13742 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13743 } \
13744 return *AA; \
13745 }
13746
13747#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13748 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13749 CLASS *AA = nullptr; \
13750 switch (IRP.getPositionKind()) { \
13751 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13752 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13753 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13754 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13755 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13756 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13757 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13758 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13759 } \
13760 return *AA; \
13761 }
13762
13772
13790
13795
13800
13807
13809
13810#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13811#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13812#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13813#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13814#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13815#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13816#undef SWITCH_PK_CREATE
13817#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition CFG.cpp:135
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1563
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:273
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:309
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:172
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:297
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:69
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:88
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:101
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:482
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:367
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:610
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:617
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:948
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:942
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:536
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:248
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:233
Analysis pass which computes a DominatorTree.
Definition Dominators.h:284
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:807
Argument * arg_iterator
Definition Function.h:72
iterator_range< arg_iterator > args()
Definition Function.h:890
const Function & getFunction() const
Definition Function.h:164
size_t arg_size() const
Definition Function.h:899
Argument * getArg(unsigned i) const
Definition Function.h:884
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:727
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:328
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2039
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:527
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2788
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1569
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:77
static MemoryEffectsBase readOnly()
Definition ModRef.h:125
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:215
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:135
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:141
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:234
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:188
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:224
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:218
static MemoryEffectsBase writeOnly()
Definition ModRef.h:130
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:158
static MemoryEffectsBase none()
Definition ModRef.h:120
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:245
static MemoryEffectsBase unknown()
Definition ModRef.h:115
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:59
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:102
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:150
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:183
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:712
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:743
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:748
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:267
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:270
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:139
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:21
const Use & getOperandUse(unsigned i) const
Definition User.h:245
Value * getOperand(unsigned i) const
Definition User.h:232
unsigned getNumOperands() const
Definition User.h:254
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:115
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
static constexpr uint64_t MaximumAlignment
Definition Value.h:830
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:538
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1091
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:829
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:314
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h: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.
@ Undef
Value of the register doesn't matter.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
@ 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:60
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:708
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:667
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:477
@ Length
Definition DWP.cpp:477
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:362
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1725
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:1655
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:345
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:296
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1545
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:296
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h: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)
Definition STLExtras.h:364
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:24
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1732
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:1622
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:339
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:421
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
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:363
ChangeStatus
{
Definition Attributor.h:496
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:508
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:509
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:507
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:330
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:315
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
GenericCycleInfo< SSAContext > CycleInfo
Definition CycleInfo.h:23
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:241
static constexpr int64_t Unknown
Definition Attributor.h:320
static RangeTy getUnknown()
Definition Attributor.h:247
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
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 DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
static constexpr DenormalMode getInvalid()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:593
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:724
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:661
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:643
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:617
CallBase CallBaseContext
Definition Attributor.h:596
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:811
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:629
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:666
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:607
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:603
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:606
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:604
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:605
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:608
@ IRP_INVALID
An invalid position.
Definition Attributor.h:600
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:777
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:650
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:800
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:636
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:939
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:791
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:710
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:820
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:689
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:889
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:921
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:656
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:765
Data structure to hold cached (LLVM-IR) information.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
bool isValidState() const override
See AbstractState::isValidState(...)
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.