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.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
669 auto Pred = [&](const Instruction *I) {
670 if (!Visited.insert(I).second)
671 return false;
672 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
673 if (Br->isConditional())
674 BrInsts.push_back(Br);
675 return true;
676 };
677
678 // Here, accumulate conditional branch instructions in the context. We
679 // explore the child paths and collect the known states. The disjunction of
680 // those states can be merged to its own state. Let ParentState_i be a state
681 // to indicate the known information for an i-th branch instruction in the
682 // context. ChildStates are created for its successors respectively.
683 //
684 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
685 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
686 // ...
687 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
688 //
689 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
690
691 Explorer->checkForAllContext(&CtxI, Pred);
692 while (!BrInsts.empty()) {
693 const BranchInst *Br = BrInsts.pop_back_val();
694 StateType ParentState;
695
696 // The known state of the parent state is a conjunction of children's
697 // known states so it is initialized with a best state.
698 ParentState.indicateOptimisticFixpoint();
699
700 for (const BasicBlock *BB : Br->successors()) {
701 StateType ChildState;
702 size_t BeforeSize = Uses.size();
703 const Instruction *I = &BB->front();
704 followUsesInContext(AA, A, *Explorer, I, Uses, ChildState);
705
706 // Erase uses which only appear in the child.
707 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
708 It = Uses.erase(It);
709
710 ParentState &= ChildState;
711
712 // Check for recursive conditional branches.
713 Explorer->checkForAllContext(I, Pred);
714 }
715
716 // Use only known state.
717 S += ParentState;
718 }
719}
720} // namespace
721
722/// ------------------------ PointerInfo ---------------------------------------
723
724namespace llvm {
725namespace AA {
726namespace PointerInfo {
727
728struct State;
729
730} // namespace PointerInfo
731} // namespace AA
732
733/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
734template <>
737 static inline Access getEmptyKey();
738 static inline Access getTombstoneKey();
739 static unsigned getHashValue(const Access &A);
740 static bool isEqual(const Access &LHS, const Access &RHS);
741};
742
743/// Helper that allows RangeTy as a key in a DenseMap.
744template <> struct DenseMapInfo<AA::RangeTy> {
745 static inline AA::RangeTy getEmptyKey() {
746 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
747 return AA::RangeTy{EmptyKey, EmptyKey};
748 }
749
750 static inline AA::RangeTy getTombstoneKey() {
751 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
752 return AA::RangeTy{TombstoneKey, TombstoneKey};
753 }
754
760
761 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
762 return A == B;
763 }
764};
765
766/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
767/// but the instruction
768struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
771 static inline Access getEmptyKey();
772 static inline Access getTombstoneKey();
773 static unsigned getHashValue(const Access &A);
774 static bool isEqual(const Access &LHS, const Access &RHS);
775};
776
777} // namespace llvm
778
779/// A type to track pointer/struct usage and accesses for AAPointerInfo.
781 /// Return the best possible representable state.
782 static State getBestState(const State &SIS) { return State(); }
783
784 /// Return the worst possible representable state.
785 static State getWorstState(const State &SIS) {
786 State R;
787 R.indicatePessimisticFixpoint();
788 return R;
789 }
790
791 State() = default;
792 State(State &&SIS) = default;
793
794 const State &getAssumed() const { return *this; }
795
796 /// See AbstractState::isValidState().
797 bool isValidState() const override { return BS.isValidState(); }
798
799 /// See AbstractState::isAtFixpoint().
800 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
801
802 /// See AbstractState::indicateOptimisticFixpoint().
804 BS.indicateOptimisticFixpoint();
806 }
807
808 /// See AbstractState::indicatePessimisticFixpoint().
810 BS.indicatePessimisticFixpoint();
812 }
813
814 State &operator=(const State &R) {
815 if (this == &R)
816 return *this;
817 BS = R.BS;
818 AccessList = R.AccessList;
819 OffsetBins = R.OffsetBins;
820 RemoteIMap = R.RemoteIMap;
821 ReturnedOffsets = R.ReturnedOffsets;
822 return *this;
823 }
824
826 if (this == &R)
827 return *this;
828 std::swap(BS, R.BS);
829 std::swap(AccessList, R.AccessList);
830 std::swap(OffsetBins, R.OffsetBins);
831 std::swap(RemoteIMap, R.RemoteIMap);
832 std::swap(ReturnedOffsets, R.ReturnedOffsets);
833 return *this;
834 }
835
836 /// Add a new Access to the state at offset \p Offset and with size \p Size.
837 /// The access is associated with \p I, writes \p Content (if anything), and
838 /// is of kind \p Kind. If an Access already exists for the same \p I and same
839 /// \p RemoteI, the two are combined, potentially losing information about
840 /// offset and size. The resulting access must now be moved from its original
841 /// OffsetBin to the bin for its new offset.
842 ///
843 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
845 Instruction &I, std::optional<Value *> Content,
847 Instruction *RemoteI = nullptr);
848
851 int64_t numOffsetBins() const { return OffsetBins.size(); }
852
853 const AAPointerInfo::Access &getAccess(unsigned Index) const {
854 return AccessList[Index];
855 }
856
857protected:
858 // Every memory instruction results in an Access object. We maintain a list of
859 // all Access objects that we own, along with the following maps:
860 //
861 // - OffsetBins: RangeTy -> { Access }
862 // - RemoteIMap: RemoteI x LocalI -> Access
863 //
864 // A RemoteI is any instruction that accesses memory. RemoteI is different
865 // from LocalI if and only if LocalI is a call; then RemoteI is some
866 // instruction in the callgraph starting from LocalI. Multiple paths in the
867 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
868 // are all combined into a single Access object. This may result in loss of
869 // information in RangeTy in the Access object.
873
874 /// Flag to determine if the underlying pointer is reaching a return statement
875 /// in the associated function or not. Returns in other functions cause
876 /// invalidation.
878
879 /// See AAPointerInfo::forallInterferingAccesses.
880 template <typename F>
882 if (!isValidState() || !ReturnedOffsets.isUnassigned())
883 return false;
884
885 for (const auto &It : OffsetBins) {
886 AA::RangeTy ItRange = It.getFirst();
887 if (!Range.mayOverlap(ItRange))
888 continue;
889 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
890 for (auto Index : It.getSecond()) {
891 auto &Access = AccessList[Index];
892 if (!CB(Access, IsExact))
893 return false;
894 }
895 }
896 return true;
897 }
898
899 /// See AAPointerInfo::forallInterferingAccesses.
900 template <typename F>
902 AA::RangeTy &Range) const {
903 if (!isValidState() || !ReturnedOffsets.isUnassigned())
904 return false;
905
906 auto LocalList = RemoteIMap.find(&I);
907 if (LocalList == RemoteIMap.end()) {
908 return true;
909 }
910
911 for (unsigned Index : LocalList->getSecond()) {
912 for (auto &R : AccessList[Index]) {
913 Range &= R;
914 if (Range.offsetAndSizeAreUnknown())
915 break;
916 }
917 }
919 }
920
921private:
922 /// State to track fixpoint and validity.
923 BooleanState BS;
924};
925
928 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
929 Instruction *RemoteI) {
930 RemoteI = RemoteI ? RemoteI : &I;
931
932 // Check if we have an access for this instruction, if not, simply add it.
933 auto &LocalList = RemoteIMap[RemoteI];
934 bool AccExists = false;
935 unsigned AccIndex = AccessList.size();
936 for (auto Index : LocalList) {
937 auto &A = AccessList[Index];
938 if (A.getLocalInst() == &I) {
939 AccExists = true;
940 AccIndex = Index;
941 break;
942 }
943 }
944
945 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
946 LLVM_DEBUG(if (ToAdd.size()) dbgs()
947 << "[AAPointerInfo] Inserting access in new offset bins\n";);
948
949 for (auto Key : ToAdd) {
950 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
951 OffsetBins[Key].insert(AccIndex);
952 }
953 };
954
955 if (!AccExists) {
956 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
957 assert((AccessList.size() == AccIndex + 1) &&
958 "New Access should have been at AccIndex");
959 LocalList.push_back(AccIndex);
960 AddToBins(AccessList[AccIndex].getRanges());
962 }
963
964 // Combine the new Access with the existing Access, and then update the
965 // mapping in the offset bins.
966 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
967 auto &Current = AccessList[AccIndex];
968 auto Before = Current;
969 Current &= Acc;
970 if (Current == Before)
972
973 auto &ExistingRanges = Before.getRanges();
974 auto &NewRanges = Current.getRanges();
975
976 // Ranges that are in the old access but not the new access need to be removed
977 // from the offset bins.
979 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
980 LLVM_DEBUG(if (ToRemove.size()) dbgs()
981 << "[AAPointerInfo] Removing access from old offset bins\n";);
982
983 for (auto Key : ToRemove) {
984 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
985 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
986 auto &Bin = OffsetBins[Key];
987 assert(Bin.count(AccIndex) &&
988 "Expected bin to actually contain the Access.");
989 Bin.erase(AccIndex);
990 }
991
992 // Ranges that are in the new access but not the old access need to be added
993 // to the offset bins.
995 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
996 AddToBins(ToAdd);
998}
999
1000namespace {
1001
1002#ifndef NDEBUG
1004 const AAPointerInfo::OffsetInfo &OI) {
1005 OS << llvm::interleaved_array(OI);
1006 return OS;
1007}
1008#endif // NDEBUG
1009
1010struct AAPointerInfoImpl
1011 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1013 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1014
1015 /// See AbstractAttribute::getAsStr().
1016 const std::string getAsStr(Attributor *A) const override {
1017 return std::string("PointerInfo ") +
1018 (isValidState() ? (std::string("#") +
1019 std::to_string(OffsetBins.size()) + " bins")
1020 : "<invalid>") +
1021 (reachesReturn()
1022 ? (" (returned:" +
1023 join(map_range(ReturnedOffsets,
1024 [](int64_t O) { return std::to_string(O); }),
1025 ", ") +
1026 ")")
1027 : "");
1028 }
1029
1030 /// See AbstractAttribute::manifest(...).
1031 ChangeStatus manifest(Attributor &A) override {
1032 return AAPointerInfo::manifest(A);
1033 }
1034
1035 const_bin_iterator begin() const override { return State::begin(); }
1036 const_bin_iterator end() const override { return State::end(); }
1037 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1038 bool reachesReturn() const override {
1039 return !ReturnedOffsets.isUnassigned();
1040 }
1041 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1042 if (ReturnedOffsets.isUnknown()) {
1043 OI.setUnknown();
1044 return;
1045 }
1046
1047 OffsetInfo MergedOI;
1048 for (auto Offset : ReturnedOffsets) {
1049 OffsetInfo TmpOI = OI;
1050 TmpOI.addToAll(Offset);
1051 MergedOI.merge(TmpOI);
1052 }
1053 OI = std::move(MergedOI);
1054 }
1055
1056 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1057 if (ReturnedOffsets.isUnknown())
1058 return ChangeStatus::UNCHANGED;
1059 if (ReachedReturnedOffsets.isUnknown()) {
1060 ReturnedOffsets.setUnknown();
1061 return ChangeStatus::CHANGED;
1062 }
1063 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1064 return ChangeStatus::CHANGED;
1065 return ChangeStatus::UNCHANGED;
1066 }
1067
1068 bool forallInterferingAccesses(
1069 AA::RangeTy Range,
1070 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1071 const override {
1072 return State::forallInterferingAccesses(Range, CB);
1073 }
1074
1075 bool forallInterferingAccesses(
1076 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1077 bool FindInterferingWrites, bool FindInterferingReads,
1078 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1079 AA::RangeTy &Range,
1080 function_ref<bool(const Access &)> SkipCB) const override {
1081 HasBeenWrittenTo = false;
1082
1083 SmallPtrSet<const Access *, 8> DominatingWrites;
1084 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1085
1086 Function &Scope = *I.getFunction();
1087 bool IsKnownNoSync;
1088 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1089 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1090 IsKnownNoSync);
1091 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1092 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1093 bool AllInSameNoSyncFn = IsAssumedNoSync;
1094 bool InstIsExecutedByInitialThreadOnly =
1095 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1096
1097 // If the function is not ending in aligned barriers, we need the stores to
1098 // be in aligned barriers. The load being in one is not sufficient since the
1099 // store might be executed by a thread that disappears after, causing the
1100 // aligned barrier guarding the load to unblock and the load to read a value
1101 // that has no CFG path to the load.
1102 bool InstIsExecutedInAlignedRegion =
1103 FindInterferingReads && ExecDomainAA &&
1104 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1105
1106 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1107 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1108
1109 InformationCache &InfoCache = A.getInfoCache();
1110 bool IsThreadLocalObj =
1111 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1112
1113 // Helper to determine if we need to consider threading, which we cannot
1114 // right now. However, if the function is (assumed) nosync or the thread
1115 // executing all instructions is the main thread only we can ignore
1116 // threading. Also, thread-local objects do not require threading reasoning.
1117 // Finally, we can ignore threading if either access is executed in an
1118 // aligned region.
1119 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1120 if (IsThreadLocalObj || AllInSameNoSyncFn)
1121 return true;
1122 const auto *FnExecDomainAA =
1123 I.getFunction() == &Scope
1124 ? ExecDomainAA
1125 : A.lookupAAFor<AAExecutionDomain>(
1126 IRPosition::function(*I.getFunction()), &QueryingAA,
1127 DepClassTy::NONE);
1128 if (!FnExecDomainAA)
1129 return false;
1130 if (InstIsExecutedInAlignedRegion ||
1131 (FindInterferingWrites &&
1132 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1133 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1134 return true;
1135 }
1136 if (InstIsExecutedByInitialThreadOnly &&
1137 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1138 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1139 return true;
1140 }
1141 return false;
1142 };
1143
1144 // Helper to determine if the access is executed by the same thread as the
1145 // given instruction, for now it is sufficient to avoid any potential
1146 // threading effects as we cannot deal with them anyway.
1147 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1148 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1149 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1150 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1151 };
1152
1153 // TODO: Use inter-procedural reachability and dominance.
1154 bool IsKnownNoRecurse;
1156 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1157 IsKnownNoRecurse);
1158
1159 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1160 // AAExecutionDomain) such that we allow scopes other than kernels as long
1161 // as the reaching kernels are disjoint.
1162 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1163 bool ObjHasKernelLifetime = false;
1164 const bool UseDominanceReasoning =
1165 FindInterferingWrites && IsKnownNoRecurse;
1166 const DominatorTree *DT =
1167 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1168
1169 // Helper to check if a value has "kernel lifetime", that is it will not
1170 // outlive a GPU kernel. This is true for shared, constant, and local
1171 // globals on AMD and NVIDIA GPUs.
1172 auto HasKernelLifetime = [&](Value *V, Module &M) {
1173 if (!AA::isGPU(M))
1174 return false;
1175 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1176 case AA::GPUAddressSpace::Shared:
1177 case AA::GPUAddressSpace::Constant:
1178 case AA::GPUAddressSpace::Local:
1179 return true;
1180 default:
1181 return false;
1182 };
1183 };
1184
1185 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1186 // to determine if we should look at reachability from the callee. For
1187 // certain pointers we know the lifetime and we do not have to step into the
1188 // callee to determine reachability as the pointer would be dead in the
1189 // callee. See the conditional initialization below.
1190 std::function<bool(const Function &)> IsLiveInCalleeCB;
1191
1192 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1193 // If the alloca containing function is not recursive the alloca
1194 // must be dead in the callee.
1195 const Function *AIFn = AI->getFunction();
1196 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1197 bool IsKnownNoRecurse;
1199 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1200 IsKnownNoRecurse)) {
1201 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1202 }
1203 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1204 // If the global has kernel lifetime we can stop if we reach a kernel
1205 // as it is "dead" in the (unknown) callees.
1206 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1207 if (ObjHasKernelLifetime)
1208 IsLiveInCalleeCB = [&A](const Function &Fn) {
1209 return !A.getInfoCache().isKernel(Fn);
1210 };
1211 }
1212
1213 // Set of accesses/instructions that will overwrite the result and are
1214 // therefore blockers in the reachability traversal.
1215 AA::InstExclusionSetTy ExclusionSet;
1216
1217 auto AccessCB = [&](const Access &Acc, bool Exact) {
1218 Function *AccScope = Acc.getRemoteInst()->getFunction();
1219 bool AccInSameScope = AccScope == &Scope;
1220
1221 // If the object has kernel lifetime we can ignore accesses only reachable
1222 // by other kernels. For now we only skip accesses *in* other kernels.
1223 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1224 A.getInfoCache().isKernel(*AccScope))
1225 return true;
1226
1227 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1228 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1229 ExclusionSet.insert(Acc.getRemoteInst());
1230 }
1231
1232 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1233 (!FindInterferingReads || !Acc.isRead()))
1234 return true;
1235
1236 bool Dominates = FindInterferingWrites && DT && Exact &&
1237 Acc.isMustAccess() && AccInSameScope &&
1238 DT->dominates(Acc.getRemoteInst(), &I);
1239 if (Dominates)
1240 DominatingWrites.insert(&Acc);
1241
1242 // Track if all interesting accesses are in the same `nosync` function as
1243 // the given instruction.
1244 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1245
1246 InterferingAccesses.push_back({&Acc, Exact});
1247 return true;
1248 };
1249 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1250 return false;
1251
1252 HasBeenWrittenTo = !DominatingWrites.empty();
1253
1254 // Dominating writes form a chain, find the least/lowest member.
1255 Instruction *LeastDominatingWriteInst = nullptr;
1256 for (const Access *Acc : DominatingWrites) {
1257 if (!LeastDominatingWriteInst) {
1258 LeastDominatingWriteInst = Acc->getRemoteInst();
1259 } else if (DT->dominates(LeastDominatingWriteInst,
1260 Acc->getRemoteInst())) {
1261 LeastDominatingWriteInst = Acc->getRemoteInst();
1262 }
1263 }
1264
1265 // Helper to determine if we can skip a specific write access.
1266 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1267 if (SkipCB && SkipCB(Acc))
1268 return true;
1269 if (!CanIgnoreThreading(Acc))
1270 return false;
1271
1272 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1273 // If we successfully excluded all effects we are interested in, the
1274 // access can be skipped.
1275 bool ReadChecked = !FindInterferingReads;
1276 bool WriteChecked = !FindInterferingWrites;
1277
1278 // If the instruction cannot reach the access, the former does not
1279 // interfere with what the access reads.
1280 if (!ReadChecked) {
1281 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1282 &ExclusionSet, IsLiveInCalleeCB))
1283 ReadChecked = true;
1284 }
1285 // If the instruction cannot be reach from the access, the latter does not
1286 // interfere with what the instruction reads.
1287 if (!WriteChecked) {
1288 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1289 &ExclusionSet, IsLiveInCalleeCB))
1290 WriteChecked = true;
1291 }
1292
1293 // If we still might be affected by the write of the access but there are
1294 // dominating writes in the function of the instruction
1295 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1296 // by them. This would have happend above if they are all in the same
1297 // function, so we only check the inter-procedural case. Effectively, we
1298 // want to show that there is no call after the dominting write that might
1299 // reach the access, and when it returns reach the instruction with the
1300 // updated value. To this end, we iterate all call sites, check if they
1301 // might reach the instruction without going through another access
1302 // (ExclusionSet) and at the same time might reach the access. However,
1303 // that is all part of AAInterFnReachability.
1304 if (!WriteChecked && HasBeenWrittenTo &&
1305 Acc.getRemoteInst()->getFunction() != &Scope) {
1306
1307 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1308 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1309 if (FnReachabilityAA) {
1310 // Without going backwards in the call tree, can we reach the access
1311 // from the least dominating write. Do not allow to pass the
1312 // instruction itself either.
1313 bool Inserted = ExclusionSet.insert(&I).second;
1314
1315 if (!FnReachabilityAA->instructionCanReach(
1316 A, *LeastDominatingWriteInst,
1317 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1318 WriteChecked = true;
1319
1320 if (Inserted)
1321 ExclusionSet.erase(&I);
1322 }
1323 }
1324
1325 if (ReadChecked && WriteChecked)
1326 return true;
1327
1328 if (!DT || !UseDominanceReasoning)
1329 return false;
1330 if (!DominatingWrites.count(&Acc))
1331 return false;
1332 return LeastDominatingWriteInst != Acc.getRemoteInst();
1333 };
1334
1335 // Run the user callback on all accesses we cannot skip and return if
1336 // that succeeded for all or not.
1337 for (auto &It : InterferingAccesses) {
1338 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1339 !CanSkipAccess(*It.first, It.second)) {
1340 if (!UserCB(*It.first, It.second))
1341 return false;
1342 }
1343 }
1344 return true;
1345 }
1346
1347 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1348 const AAPointerInfo &OtherAA,
1349 CallBase &CB) {
1350 using namespace AA::PointerInfo;
1351 if (!OtherAA.getState().isValidState() || !isValidState())
1352 return indicatePessimisticFixpoint();
1353
1354 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1355 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1356 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1357 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1358
1359 // Combine the accesses bin by bin.
1360 const auto &State = OtherAAImpl.getState();
1361 for (const auto &It : State) {
1362 for (auto Index : It.getSecond()) {
1363 const auto &RAcc = State.getAccess(Index);
1364 if (IsByval && !RAcc.isRead())
1365 continue;
1366 bool UsedAssumedInformation = false;
1367 AccessKind AK = RAcc.getKind();
1368 auto Content = A.translateArgumentToCallSiteContent(
1369 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1370 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1371 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1372
1373 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1374 RAcc.getType(), RAcc.getRemoteInst());
1375 }
1376 }
1377 return Changed;
1378 }
1379
1380 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1381 const OffsetInfo &Offsets, CallBase &CB,
1382 bool IsMustAcc) {
1383 using namespace AA::PointerInfo;
1384 if (!OtherAA.getState().isValidState() || !isValidState())
1385 return indicatePessimisticFixpoint();
1386
1387 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1388
1389 // Combine the accesses bin by bin.
1390 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1391 const auto &State = OtherAAImpl.getState();
1392 for (const auto &It : State) {
1393 for (auto Index : It.getSecond()) {
1394 const auto &RAcc = State.getAccess(Index);
1395 if (!IsMustAcc && RAcc.isAssumption())
1396 continue;
1397 for (auto Offset : Offsets) {
1398 auto NewRanges = Offset == AA::RangeTy::Unknown
1400 : RAcc.getRanges();
1401 if (!NewRanges.isUnknown()) {
1402 NewRanges.addToAllOffsets(Offset);
1403 }
1404 AccessKind AK = RAcc.getKind();
1405 if (!IsMustAcc)
1406 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1407 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1408 RAcc.getType(), RAcc.getRemoteInst());
1409 }
1410 }
1411 }
1412 return Changed;
1413 }
1414
1415 /// Statistic tracking for all AAPointerInfo implementations.
1416 /// See AbstractAttribute::trackStatistics().
1417 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1418
1419 /// Dump the state into \p O.
1420 void dumpState(raw_ostream &O) {
1421 for (auto &It : OffsetBins) {
1422 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1423 << "] : " << It.getSecond().size() << "\n";
1424 for (auto AccIndex : It.getSecond()) {
1425 auto &Acc = AccessList[AccIndex];
1426 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1427 if (Acc.getLocalInst() != Acc.getRemoteInst())
1428 O << " --> " << *Acc.getRemoteInst()
1429 << "\n";
1430 if (!Acc.isWrittenValueYetUndetermined()) {
1431 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1432 O << " - c: func " << Acc.getWrittenValue()->getName()
1433 << "\n";
1434 else if (Acc.getWrittenValue())
1435 O << " - c: " << *Acc.getWrittenValue() << "\n";
1436 else
1437 O << " - c: <unknown>\n";
1438 }
1439 }
1440 }
1441 }
1442};
1443
1444struct AAPointerInfoFloating : public AAPointerInfoImpl {
1446 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1447 : AAPointerInfoImpl(IRP, A) {}
1448
1449 /// Deal with an access and signal if it was handled successfully.
1450 bool handleAccess(Attributor &A, Instruction &I,
1451 std::optional<Value *> Content, AccessKind Kind,
1452 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1453 Type &Ty) {
1454 using namespace AA::PointerInfo;
1456 const DataLayout &DL = A.getDataLayout();
1457 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1458 if (!AccessSize.isScalable())
1459 Size = AccessSize.getFixedValue();
1460
1461 // Make a strictly ascending list of offsets as required by addAccess()
1462 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1463 llvm::sort(OffsetsSorted);
1464
1466 if (!VT || VT->getElementCount().isScalable() ||
1467 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1468 (*Content)->getType() != VT ||
1469 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1470 Changed =
1471 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1472 } else {
1473 // Handle vector stores with constant content element-wise.
1474 // TODO: We could look for the elements or create instructions
1475 // representing them.
1476 // TODO: We need to push the Content into the range abstraction
1477 // (AA::RangeTy) to allow different content values for different
1478 // ranges. ranges. Hence, support vectors storing different values.
1479 Type *ElementType = VT->getElementType();
1480 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1481 auto *ConstContent = cast<Constant>(*Content);
1482 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1483 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1484
1485 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1486 Value *ElementContent = ConstantExpr::getExtractElement(
1487 ConstContent, ConstantInt::get(Int32Ty, i));
1488
1489 // Add the element access.
1490 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1491 ElementContent, Kind, ElementType);
1492
1493 // Advance the offsets for the next element.
1494 for (auto &ElementOffset : ElementOffsets)
1495 ElementOffset += ElementSize;
1496 }
1497 }
1498 return true;
1499 };
1500
1501 /// See AbstractAttribute::updateImpl(...).
1502 ChangeStatus updateImpl(Attributor &A) override;
1503
1504 /// If the indices to \p GEP can be traced to constants, incorporate all
1505 /// of these into \p UsrOI.
1506 ///
1507 /// \return true iff \p UsrOI is updated.
1508 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1509 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1510 const GEPOperator *GEP);
1511
1512 /// See AbstractAttribute::trackStatistics()
1513 void trackStatistics() const override {
1514 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1515 }
1516};
1517
1518bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1519 const DataLayout &DL,
1520 OffsetInfo &UsrOI,
1521 const OffsetInfo &PtrOI,
1522 const GEPOperator *GEP) {
1523 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1524 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1525 APInt ConstantOffset(BitWidth, 0);
1526
1527 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1528 "Don't look for constant values if the offset has already been "
1529 "determined to be unknown.");
1530
1531 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1532 UsrOI.setUnknown();
1533 return true;
1534 }
1535
1536 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1537 << (VariableOffsets.empty() ? "" : "not") << " constant "
1538 << *GEP << "\n");
1539
1540 auto Union = PtrOI;
1541 Union.addToAll(ConstantOffset.getSExtValue());
1542
1543 // Each VI in VariableOffsets has a set of potential constant values. Every
1544 // combination of elements, picked one each from these sets, is separately
1545 // added to the original set of offsets, thus resulting in more offsets.
1546 for (const auto &VI : VariableOffsets) {
1547 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1548 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1549 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1550 UsrOI.setUnknown();
1551 return true;
1552 }
1553
1554 // UndefValue is treated as a zero, which leaves Union as is.
1555 if (PotentialConstantsAA->undefIsContained())
1556 continue;
1557
1558 // We need at least one constant in every set to compute an actual offset.
1559 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1560 // don't actually exist. In other words, the absence of constant values
1561 // implies that the operation can be assumed dead for now.
1562 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1563 if (AssumedSet.empty())
1564 return false;
1565
1566 OffsetInfo Product;
1567 for (const auto &ConstOffset : AssumedSet) {
1568 auto CopyPerOffset = Union;
1569 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1570 VI.second.getZExtValue());
1571 Product.merge(CopyPerOffset);
1572 }
1573 Union = Product;
1574 }
1575
1576 UsrOI = std::move(Union);
1577 return true;
1578}
1579
1580ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1581 using namespace AA::PointerInfo;
1583 const DataLayout &DL = A.getDataLayout();
1584 Value &AssociatedValue = getAssociatedValue();
1585
1586 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1587 OffsetInfoMap[&AssociatedValue].insert(0);
1588
1589 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1590 // One does not simply walk into a map and assign a reference to a possibly
1591 // new location. That can cause an invalidation before the assignment
1592 // happens, like so:
1593 //
1594 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1595 //
1596 // The RHS is a reference that may be invalidated by an insertion caused by
1597 // the LHS. So we ensure that the side-effect of the LHS happens first.
1598
1599 assert(OffsetInfoMap.contains(CurPtr) &&
1600 "CurPtr does not exist in the map!");
1601
1602 auto &UsrOI = OffsetInfoMap[Usr];
1603 auto &PtrOI = OffsetInfoMap[CurPtr];
1604 assert(!PtrOI.isUnassigned() &&
1605 "Cannot pass through if the input Ptr was not visited!");
1606 UsrOI.merge(PtrOI);
1607 Follow = true;
1608 return true;
1609 };
1610
1611 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1612 Value *CurPtr = U.get();
1613 User *Usr = U.getUser();
1614 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1615 << "\n");
1616 assert(OffsetInfoMap.count(CurPtr) &&
1617 "The current pointer offset should have been seeded!");
1618 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1619 "Current pointer should be assigned");
1620
1621 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1622 if (CE->isCast())
1623 return HandlePassthroughUser(Usr, CurPtr, Follow);
1624 if (!isa<GEPOperator>(CE)) {
1625 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1626 << "\n");
1627 return false;
1628 }
1629 }
1630 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1631 // Note the order here, the Usr access might change the map, CurPtr is
1632 // already in it though.
1633 auto &UsrOI = OffsetInfoMap[Usr];
1634 auto &PtrOI = OffsetInfoMap[CurPtr];
1635
1636 if (UsrOI.isUnknown())
1637 return true;
1638
1639 if (PtrOI.isUnknown()) {
1640 Follow = true;
1641 UsrOI.setUnknown();
1642 return true;
1643 }
1644
1645 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1646 return true;
1647 }
1648 if (isa<PtrToIntInst>(Usr))
1649 return false;
1650 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1651 return HandlePassthroughUser(Usr, CurPtr, Follow);
1652 // Returns are allowed if they are in the associated functions. Users can
1653 // then check the call site return. Returns from other functions can't be
1654 // tracked and are cause for invalidation.
1655 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1656 if (RI->getFunction() == getAssociatedFunction()) {
1657 auto &PtrOI = OffsetInfoMap[CurPtr];
1658 Changed |= setReachesReturn(PtrOI);
1659 return true;
1660 }
1661 return false;
1662 }
1663
1664 // For PHIs we need to take care of the recurrence explicitly as the value
1665 // might change while we iterate through a loop. For now, we give up if
1666 // the PHI is not invariant.
1667 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1668 // Note the order here, the Usr access might change the map, CurPtr is
1669 // already in it though.
1670 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1671 auto &UsrOI = PhiIt->second;
1672 auto &PtrOI = OffsetInfoMap[CurPtr];
1673
1674 // Check if the PHI operand has already an unknown offset as we can't
1675 // improve on that anymore.
1676 if (PtrOI.isUnknown()) {
1677 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1678 << *CurPtr << " in " << *PHI << "\n");
1679 Follow = !UsrOI.isUnknown();
1680 UsrOI.setUnknown();
1681 return true;
1682 }
1683
1684 // Check if the PHI is invariant (so far).
1685 if (UsrOI == PtrOI) {
1686 assert(!PtrOI.isUnassigned() &&
1687 "Cannot assign if the current Ptr was not visited!");
1688 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1689 return true;
1690 }
1691
1692 // Check if the PHI operand can be traced back to AssociatedValue.
1693 APInt Offset(
1694 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1695 0);
1696 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1697 DL, Offset, /* AllowNonInbounds */ true);
1698 auto It = OffsetInfoMap.find(CurPtrBase);
1699 if (It == OffsetInfoMap.end()) {
1700 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1701 << *CurPtr << " in " << *PHI
1702 << " (base: " << *CurPtrBase << ")\n");
1703 UsrOI.setUnknown();
1704 Follow = true;
1705 return true;
1706 }
1707
1708 // Check if the PHI operand is not dependent on the PHI itself. Every
1709 // recurrence is a cyclic net of PHIs in the data flow, and has an
1710 // equivalent Cycle in the control flow. One of those PHIs must be in the
1711 // header of that control flow Cycle. This is independent of the choice of
1712 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1713 // every Cycle header; if such a node is marked unknown, this will
1714 // eventually propagate through the whole net of PHIs in the recurrence.
1715 const auto *CI =
1716 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1717 *PHI->getFunction());
1718 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1719 auto BaseOI = It->getSecond();
1720 BaseOI.addToAll(Offset.getZExtValue());
1721 if (IsFirstPHIUser || BaseOI == UsrOI) {
1722 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1723 << " in " << *Usr << "\n");
1724 return HandlePassthroughUser(Usr, CurPtr, Follow);
1725 }
1726
1727 LLVM_DEBUG(
1728 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1729 << *CurPtr << " in " << *PHI << "\n");
1730 UsrOI.setUnknown();
1731 Follow = true;
1732 return true;
1733 }
1734
1735 UsrOI.merge(PtrOI);
1736 Follow = true;
1737 return true;
1738 }
1739
1740 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1741 // If the access is to a pointer that may or may not be the associated
1742 // value, e.g. due to a PHI, we cannot assume it will be read.
1743 AccessKind AK = AccessKind::AK_R;
1744 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1745 AK = AccessKind(AK | AccessKind::AK_MUST);
1746 else
1747 AK = AccessKind(AK | AccessKind::AK_MAY);
1748 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1749 OffsetInfoMap[CurPtr].Offsets, Changed,
1750 *LoadI->getType()))
1751 return false;
1752
1753 auto IsAssumption = [](Instruction &I) {
1754 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1755 return II->isAssumeLikeIntrinsic();
1756 return false;
1757 };
1758
1759 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1760 // Check if the assumption and the load are executed together without
1761 // memory modification.
1762 do {
1763 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1764 return true;
1765 FromI = FromI->getNextNode();
1766 } while (FromI && FromI != ToI);
1767 return false;
1768 };
1769
1770 BasicBlock *BB = LoadI->getParent();
1771 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1772 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1773 return false;
1774 BasicBlock *IntrBB = IntrI.getParent();
1775 if (IntrI.getParent() == BB) {
1776 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1777 return false;
1778 } else {
1779 auto PredIt = pred_begin(IntrBB);
1780 if (PredIt == pred_end(IntrBB))
1781 return false;
1782 if ((*PredIt) != BB)
1783 return false;
1784 if (++PredIt != pred_end(IntrBB))
1785 return false;
1786 for (auto *SuccBB : successors(BB)) {
1787 if (SuccBB == IntrBB)
1788 continue;
1789 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1790 continue;
1791 return false;
1792 }
1793 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1794 return false;
1795 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1796 return false;
1797 }
1798 return true;
1799 };
1800
1801 std::pair<Value *, IntrinsicInst *> Assumption;
1802 for (const Use &LoadU : LoadI->uses()) {
1803 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1804 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1805 continue;
1806 for (const Use &CmpU : CmpI->uses()) {
1807 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1808 if (!IsValidAssume(*IntrI))
1809 continue;
1810 int Idx = CmpI->getOperandUse(0) == LoadU;
1811 Assumption = {CmpI->getOperand(Idx), IntrI};
1812 break;
1813 }
1814 }
1815 }
1816 if (Assumption.first)
1817 break;
1818 }
1819
1820 // Check if we found an assumption associated with this load.
1821 if (!Assumption.first || !Assumption.second)
1822 return true;
1823
1824 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1825 << *Assumption.second << ": " << *LoadI
1826 << " == " << *Assumption.first << "\n");
1827 bool UsedAssumedInformation = false;
1828 std::optional<Value *> Content = nullptr;
1829 if (Assumption.first)
1830 Content =
1831 A.getAssumedSimplified(*Assumption.first, *this,
1832 UsedAssumedInformation, AA::Interprocedural);
1833 return handleAccess(
1834 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1835 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1836 }
1837
1838 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1839 ArrayRef<Value *> OtherOps, AccessKind AK) {
1840 for (auto *OtherOp : OtherOps) {
1841 if (OtherOp == CurPtr) {
1842 LLVM_DEBUG(
1843 dbgs()
1844 << "[AAPointerInfo] Escaping use in store like instruction " << I
1845 << "\n");
1846 return false;
1847 }
1848 }
1849
1850 // If the access is to a pointer that may or may not be the associated
1851 // value, e.g. due to a PHI, we cannot assume it will be written.
1852 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1853 AK = AccessKind(AK | AccessKind::AK_MUST);
1854 else
1855 AK = AccessKind(AK | AccessKind::AK_MAY);
1856 bool UsedAssumedInformation = false;
1857 std::optional<Value *> Content = nullptr;
1858 if (ValueOp)
1859 Content = A.getAssumedSimplified(
1860 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1861 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1862 Changed, ValueTy);
1863 };
1864
1865 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1866 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1867 *StoreI->getValueOperand()->getType(),
1868 {StoreI->getValueOperand()}, AccessKind::AK_W);
1869 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1870 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1871 {RMWI->getValOperand()}, AccessKind::AK_RW);
1872 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1873 return HandleStoreLike(
1874 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1875 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1876 AccessKind::AK_RW);
1877
1878 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1879 if (CB->isLifetimeStartOrEnd())
1880 return true;
1881 const auto *TLI =
1882 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1883 if (getFreedOperand(CB, TLI) == U)
1884 return true;
1885 if (CB->isArgOperand(&U)) {
1886 unsigned ArgNo = CB->getArgOperandNo(&U);
1887 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1888 *this, IRPosition::callsite_argument(*CB, ArgNo),
1890 if (!CSArgPI)
1891 return false;
1892 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1893 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1894 IsArgMustAcc) |
1895 Changed;
1896 if (!CSArgPI->reachesReturn())
1897 return isValidState();
1898
1900 if (!Callee || Callee->arg_size() <= ArgNo)
1901 return false;
1902 bool UsedAssumedInformation = false;
1903 auto ReturnedValue = A.getAssumedSimplified(
1904 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1906 auto *ReturnedArg =
1907 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1908 auto *Arg = Callee->getArg(ArgNo);
1909 if (ReturnedArg && Arg != ReturnedArg)
1910 return true;
1911 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1912 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1914 if (!CSRetPI)
1915 return false;
1916 OffsetInfo OI = OffsetInfoMap[CurPtr];
1917 CSArgPI->addReturnedOffsetsTo(OI);
1918 Changed =
1919 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1920 return isValidState();
1921 }
1922 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1923 << "\n");
1924 return false;
1925 }
1926
1927 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1928 return false;
1929 };
1930 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1931 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1932 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1933 if (OffsetInfoMap.count(NewU)) {
1934 LLVM_DEBUG({
1935 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1936 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1937 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1938 << "\n";
1939 }
1940 });
1941 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1942 }
1943 bool Unused;
1944 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1945 };
1946 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1947 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1948 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1949 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1950 return indicatePessimisticFixpoint();
1951 }
1952
1953 LLVM_DEBUG({
1954 dbgs() << "Accesses by bin after update:\n";
1955 dumpState(dbgs());
1956 });
1957
1958 return Changed;
1959}
1960
1961struct AAPointerInfoReturned final : AAPointerInfoImpl {
1962 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1963 : AAPointerInfoImpl(IRP, A) {}
1964
1965 /// See AbstractAttribute::updateImpl(...).
1966 ChangeStatus updateImpl(Attributor &A) override {
1967 return indicatePessimisticFixpoint();
1968 }
1969
1970 /// See AbstractAttribute::trackStatistics()
1971 void trackStatistics() const override {
1972 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1973 }
1974};
1975
1976struct AAPointerInfoArgument final : AAPointerInfoFloating {
1977 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1978 : AAPointerInfoFloating(IRP, A) {}
1979
1980 /// See AbstractAttribute::trackStatistics()
1981 void trackStatistics() const override {
1982 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1983 }
1984};
1985
1986struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1987 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1988 : AAPointerInfoFloating(IRP, A) {}
1989
1990 /// See AbstractAttribute::updateImpl(...).
1991 ChangeStatus updateImpl(Attributor &A) override {
1992 using namespace AA::PointerInfo;
1993 // We handle memory intrinsics explicitly, at least the first (=
1994 // destination) and second (=source) arguments as we know how they are
1995 // accessed.
1996 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
1997 int64_t LengthVal = AA::RangeTy::Unknown;
1998 if (auto Length = MI->getLengthInBytes())
1999 LengthVal = Length->getSExtValue();
2000 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2001 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2002 if (ArgNo > 1) {
2003 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2004 << *MI << "\n");
2005 return indicatePessimisticFixpoint();
2006 } else {
2007 auto Kind =
2008 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2009 Changed =
2010 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2011 }
2012 LLVM_DEBUG({
2013 dbgs() << "Accesses by bin after update:\n";
2014 dumpState(dbgs());
2015 });
2016
2017 return Changed;
2018 }
2019
2020 // TODO: Once we have call site specific value information we can provide
2021 // call site specific liveness information and then it makes
2022 // sense to specialize attributes for call sites arguments instead of
2023 // redirecting requests to the callee argument.
2024 Argument *Arg = getAssociatedArgument();
2025 if (Arg) {
2026 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2027 auto *ArgAA =
2028 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2029 if (ArgAA && ArgAA->getState().isValidState())
2030 return translateAndAddStateFromCallee(A, *ArgAA,
2031 *cast<CallBase>(getCtxI()));
2032 if (!Arg->getParent()->isDeclaration())
2033 return indicatePessimisticFixpoint();
2034 }
2035
2036 bool IsKnownNoCapture;
2038 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2039 return indicatePessimisticFixpoint();
2040
2041 bool IsKnown = false;
2042 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2043 return ChangeStatus::UNCHANGED;
2044 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2045 auto Kind =
2046 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2047 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2048 nullptr);
2049 }
2050
2051 /// See AbstractAttribute::trackStatistics()
2052 void trackStatistics() const override {
2053 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2054 }
2055};
2056
2057struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2058 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2059 : AAPointerInfoFloating(IRP, A) {}
2060
2061 /// See AbstractAttribute::trackStatistics()
2062 void trackStatistics() const override {
2063 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2064 }
2065};
2066} // namespace
2067
2068/// -----------------------NoUnwind Function Attribute--------------------------
2069
2070namespace {
2071struct AANoUnwindImpl : AANoUnwind {
2072 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2073
2074 /// See AbstractAttribute::initialize(...).
2075 void initialize(Attributor &A) override {
2076 bool IsKnown;
2078 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2079 (void)IsKnown;
2080 }
2081
2082 const std::string getAsStr(Attributor *A) const override {
2083 return getAssumed() ? "nounwind" : "may-unwind";
2084 }
2085
2086 /// See AbstractAttribute::updateImpl(...).
2087 ChangeStatus updateImpl(Attributor &A) override {
2088 auto Opcodes = {
2089 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2090 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2091 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2092
2093 auto CheckForNoUnwind = [&](Instruction &I) {
2094 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2095 return true;
2096
2097 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2098 bool IsKnownNoUnwind;
2100 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2101 IsKnownNoUnwind);
2102 }
2103 return false;
2104 };
2105
2106 bool UsedAssumedInformation = false;
2107 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2108 UsedAssumedInformation))
2109 return indicatePessimisticFixpoint();
2110
2111 return ChangeStatus::UNCHANGED;
2112 }
2113};
2114
2115struct AANoUnwindFunction final : public AANoUnwindImpl {
2116 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2117 : AANoUnwindImpl(IRP, A) {}
2118
2119 /// See AbstractAttribute::trackStatistics()
2120 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2121};
2122
2123/// NoUnwind attribute deduction for a call sites.
2124struct AANoUnwindCallSite final
2125 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2126 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2127 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2128
2129 /// See AbstractAttribute::trackStatistics()
2130 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2131};
2132} // namespace
2133
2134/// ------------------------ NoSync Function Attribute -------------------------
2135
2136bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2137 switch (CB.getIntrinsicID()) {
2138 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2139 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2140 case Intrinsic::nvvm_barrier0_and:
2141 case Intrinsic::nvvm_barrier0_or:
2142 case Intrinsic::nvvm_barrier0_popc:
2143 return true;
2144 case Intrinsic::amdgcn_s_barrier:
2145 if (ExecutedAligned)
2146 return true;
2147 break;
2148 default:
2149 break;
2150 }
2151 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2152}
2153
2155 if (!I->isAtomic())
2156 return false;
2157
2158 if (auto *FI = dyn_cast<FenceInst>(I))
2159 // All legal orderings for fence are stronger than monotonic.
2160 return FI->getSyncScopeID() != SyncScope::SingleThread;
2161 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2162 // Unordered is not a legal ordering for cmpxchg.
2163 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2164 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2165 }
2166
2167 AtomicOrdering Ordering;
2168 switch (I->getOpcode()) {
2169 case Instruction::AtomicRMW:
2170 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2171 break;
2172 case Instruction::Store:
2173 Ordering = cast<StoreInst>(I)->getOrdering();
2174 break;
2175 case Instruction::Load:
2176 Ordering = cast<LoadInst>(I)->getOrdering();
2177 break;
2178 default:
2180 "New atomic operations need to be known in the attributor.");
2181 }
2182
2183 return (Ordering != AtomicOrdering::Unordered &&
2184 Ordering != AtomicOrdering::Monotonic);
2185}
2186
2187/// Return true if this intrinsic is nosync. This is only used for intrinsics
2188/// which would be nosync except that they have a volatile flag. All other
2189/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2191 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2192 return !MI->isVolatile();
2193 return false;
2194}
2195
2196namespace {
2197struct AANoSyncImpl : AANoSync {
2198 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2199
2200 /// See AbstractAttribute::initialize(...).
2201 void initialize(Attributor &A) override {
2202 bool IsKnown;
2203 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2204 DepClassTy::NONE, IsKnown));
2205 (void)IsKnown;
2206 }
2207
2208 const std::string getAsStr(Attributor *A) const override {
2209 return getAssumed() ? "nosync" : "may-sync";
2210 }
2211
2212 /// See AbstractAttribute::updateImpl(...).
2213 ChangeStatus updateImpl(Attributor &A) override;
2214};
2215
2216ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2217
2218 auto CheckRWInstForNoSync = [&](Instruction &I) {
2219 return AA::isNoSyncInst(A, I, *this);
2220 };
2221
2222 auto CheckForNoSync = [&](Instruction &I) {
2223 // At this point we handled all read/write effects and they are all
2224 // nosync, so they can be skipped.
2225 if (I.mayReadOrWriteMemory())
2226 return true;
2227
2228 bool IsKnown;
2229 CallBase &CB = cast<CallBase>(I);
2232 IsKnown))
2233 return true;
2234
2235 // non-convergent and readnone imply nosync.
2236 return !CB.isConvergent();
2237 };
2238
2239 bool UsedAssumedInformation = false;
2240 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2241 UsedAssumedInformation) ||
2242 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2243 UsedAssumedInformation))
2244 return indicatePessimisticFixpoint();
2245
2247}
2248
2249struct AANoSyncFunction final : public AANoSyncImpl {
2250 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2251 : AANoSyncImpl(IRP, A) {}
2252
2253 /// See AbstractAttribute::trackStatistics()
2254 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2255};
2256
2257/// NoSync attribute deduction for a call sites.
2258struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2259 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2260 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2261
2262 /// See AbstractAttribute::trackStatistics()
2263 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2264};
2265} // namespace
2266
2267/// ------------------------ No-Free Attributes ----------------------------
2268
2269namespace {
2270struct AANoFreeImpl : public AANoFree {
2271 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2272
2273 /// See AbstractAttribute::initialize(...).
2274 void initialize(Attributor &A) override {
2275 bool IsKnown;
2276 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2277 DepClassTy::NONE, IsKnown));
2278 (void)IsKnown;
2279 }
2280
2281 /// See AbstractAttribute::updateImpl(...).
2282 ChangeStatus updateImpl(Attributor &A) override {
2283 auto CheckForNoFree = [&](Instruction &I) {
2284 bool IsKnown;
2287 DepClassTy::REQUIRED, IsKnown);
2288 };
2289
2290 bool UsedAssumedInformation = false;
2291 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2292 UsedAssumedInformation))
2293 return indicatePessimisticFixpoint();
2294 return ChangeStatus::UNCHANGED;
2295 }
2296
2297 /// See AbstractAttribute::getAsStr().
2298 const std::string getAsStr(Attributor *A) const override {
2299 return getAssumed() ? "nofree" : "may-free";
2300 }
2301};
2302
2303struct AANoFreeFunction final : public AANoFreeImpl {
2304 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2305 : AANoFreeImpl(IRP, A) {}
2306
2307 /// See AbstractAttribute::trackStatistics()
2308 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2309};
2310
2311/// NoFree attribute deduction for a call sites.
2312struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2313 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2314 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2315
2316 /// See AbstractAttribute::trackStatistics()
2317 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2318};
2319
2320/// NoFree attribute for floating values.
2321struct AANoFreeFloating : AANoFreeImpl {
2322 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2323 : AANoFreeImpl(IRP, A) {}
2324
2325 /// See AbstractAttribute::trackStatistics()
2326 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2327
2328 /// See Abstract Attribute::updateImpl(...).
2329 ChangeStatus updateImpl(Attributor &A) override {
2330 const IRPosition &IRP = getIRPosition();
2331
2332 bool IsKnown;
2335 DepClassTy::OPTIONAL, IsKnown))
2336 return ChangeStatus::UNCHANGED;
2337
2338 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2339 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2340 Instruction *UserI = cast<Instruction>(U.getUser());
2341 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2342 if (CB->isBundleOperand(&U))
2343 return false;
2344 if (!CB->isArgOperand(&U))
2345 return true;
2346 unsigned ArgNo = CB->getArgOperandNo(&U);
2347
2348 bool IsKnown;
2350 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2351 DepClassTy::REQUIRED, IsKnown);
2352 }
2353
2354 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2355 isa<SelectInst>(UserI)) {
2356 Follow = true;
2357 return true;
2358 }
2359 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2360 return true;
2361
2362 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2363 return true;
2364
2365 // Unknown user.
2366 return false;
2367 };
2368 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2369 return indicatePessimisticFixpoint();
2370
2371 return ChangeStatus::UNCHANGED;
2372 }
2373};
2374
2375/// NoFree attribute for a call site argument.
2376struct AANoFreeArgument final : AANoFreeFloating {
2377 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2378 : AANoFreeFloating(IRP, A) {}
2379
2380 /// See AbstractAttribute::trackStatistics()
2381 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2382};
2383
2384/// NoFree attribute for call site arguments.
2385struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2386 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2387 : AANoFreeFloating(IRP, A) {}
2388
2389 /// See AbstractAttribute::updateImpl(...).
2390 ChangeStatus updateImpl(Attributor &A) override {
2391 // TODO: Once we have call site specific value information we can provide
2392 // call site specific liveness information and then it makes
2393 // sense to specialize attributes for call sites arguments instead of
2394 // redirecting requests to the callee argument.
2395 Argument *Arg = getAssociatedArgument();
2396 if (!Arg)
2397 return indicatePessimisticFixpoint();
2398 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2399 bool IsKnown;
2401 DepClassTy::REQUIRED, IsKnown))
2402 return ChangeStatus::UNCHANGED;
2403 return indicatePessimisticFixpoint();
2404 }
2405
2406 /// See AbstractAttribute::trackStatistics()
2407 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2408};
2409
2410/// NoFree attribute for function return value.
2411struct AANoFreeReturned final : AANoFreeFloating {
2412 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2413 : AANoFreeFloating(IRP, A) {
2414 llvm_unreachable("NoFree is not applicable to function returns!");
2415 }
2416
2417 /// See AbstractAttribute::initialize(...).
2418 void initialize(Attributor &A) override {
2419 llvm_unreachable("NoFree is not applicable to function returns!");
2420 }
2421
2422 /// See AbstractAttribute::updateImpl(...).
2423 ChangeStatus updateImpl(Attributor &A) override {
2424 llvm_unreachable("NoFree is not applicable to function returns!");
2425 }
2426
2427 /// See AbstractAttribute::trackStatistics()
2428 void trackStatistics() const override {}
2429};
2430
2431/// NoFree attribute deduction for a call site return value.
2432struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2433 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2434 : AANoFreeFloating(IRP, A) {}
2435
2436 ChangeStatus manifest(Attributor &A) override {
2437 return ChangeStatus::UNCHANGED;
2438 }
2439 /// See AbstractAttribute::trackStatistics()
2440 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2441};
2442} // namespace
2443
2444/// ------------------------ NonNull Argument Attribute ------------------------
2445
2447 Attribute::AttrKind ImpliedAttributeKind,
2448 bool IgnoreSubsumingPositions) {
2450 AttrKinds.push_back(Attribute::NonNull);
2453 AttrKinds.push_back(Attribute::Dereferenceable);
2454 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2455 return true;
2456
2457 DominatorTree *DT = nullptr;
2458 AssumptionCache *AC = nullptr;
2459 InformationCache &InfoCache = A.getInfoCache();
2460 if (const Function *Fn = IRP.getAnchorScope()) {
2461 if (!Fn->isDeclaration()) {
2464 }
2465 }
2466
2468 if (IRP.getPositionKind() != IRP_RETURNED) {
2469 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2470 } else {
2471 bool UsedAssumedInformation = false;
2472 if (!A.checkForAllInstructions(
2473 [&](Instruction &I) {
2474 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2475 return true;
2476 },
2477 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2478 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2479 return false;
2480 }
2481
2482 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2483 return !isKnownNonZero(
2484 VAC.getValue(),
2485 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2486 }))
2487 return false;
2488
2489 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2490 Attribute::NonNull)});
2491 return true;
2492}
2493
2494namespace {
2495static int64_t getKnownNonNullAndDerefBytesForUse(
2496 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2497 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2498 TrackUse = false;
2499
2500 const Value *UseV = U->get();
2501 if (!UseV->getType()->isPointerTy())
2502 return 0;
2503
2504 // We need to follow common pointer manipulation uses to the accesses they
2505 // feed into. We can try to be smart to avoid looking through things we do not
2506 // like for now, e.g., non-inbounds GEPs.
2507 if (isa<CastInst>(I)) {
2508 TrackUse = true;
2509 return 0;
2510 }
2511
2513 TrackUse = true;
2514 return 0;
2515 }
2516
2517 Type *PtrTy = UseV->getType();
2518 const Function *F = I->getFunction();
2521 const DataLayout &DL = A.getInfoCache().getDL();
2522 if (const auto *CB = dyn_cast<CallBase>(I)) {
2523 if (CB->isBundleOperand(U)) {
2524 if (RetainedKnowledge RK = getKnowledgeFromUse(
2525 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2526 IsNonNull |=
2527 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2528 return RK.ArgValue;
2529 }
2530 return 0;
2531 }
2532
2533 if (CB->isCallee(U)) {
2534 IsNonNull |= !NullPointerIsDefined;
2535 return 0;
2536 }
2537
2538 unsigned ArgNo = CB->getArgOperandNo(U);
2539 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2540 // As long as we only use known information there is no need to track
2541 // dependences here.
2542 bool IsKnownNonNull;
2544 DepClassTy::NONE, IsKnownNonNull);
2545 IsNonNull |= IsKnownNonNull;
2546 auto *DerefAA =
2547 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2548 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2549 }
2550
2551 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2552 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2553 Loc->Size.isScalable() || I->isVolatile())
2554 return 0;
2555
2556 int64_t Offset;
2557 const Value *Base =
2558 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2559 if (Base && Base == &AssociatedValue) {
2560 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2561 IsNonNull |= !NullPointerIsDefined;
2562 return std::max(int64_t(0), DerefBytes);
2563 }
2564
2565 /// Corner case when an offset is 0.
2567 /*AllowNonInbounds*/ true);
2568 if (Base && Base == &AssociatedValue && Offset == 0) {
2569 int64_t DerefBytes = Loc->Size.getValue();
2570 IsNonNull |= !NullPointerIsDefined;
2571 return std::max(int64_t(0), DerefBytes);
2572 }
2573
2574 return 0;
2575}
2576
2577struct AANonNullImpl : AANonNull {
2578 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2579
2580 /// See AbstractAttribute::initialize(...).
2581 void initialize(Attributor &A) override {
2582 Value &V = *getAssociatedValue().stripPointerCasts();
2583 if (isa<ConstantPointerNull>(V)) {
2584 indicatePessimisticFixpoint();
2585 return;
2586 }
2587
2588 if (Instruction *CtxI = getCtxI())
2589 followUsesInMBEC(*this, A, getState(), *CtxI);
2590 }
2591
2592 /// See followUsesInMBEC
2593 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2594 AANonNull::StateType &State) {
2595 bool IsNonNull = false;
2596 bool TrackUse = false;
2597 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2598 IsNonNull, TrackUse);
2599 State.setKnown(IsNonNull);
2600 return TrackUse;
2601 }
2602
2603 /// See AbstractAttribute::getAsStr().
2604 const std::string getAsStr(Attributor *A) const override {
2605 return getAssumed() ? "nonnull" : "may-null";
2606 }
2607};
2608
2609/// NonNull attribute for a floating value.
2610struct AANonNullFloating : public AANonNullImpl {
2611 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2612 : AANonNullImpl(IRP, A) {}
2613
2614 /// See AbstractAttribute::updateImpl(...).
2615 ChangeStatus updateImpl(Attributor &A) override {
2616 auto CheckIRP = [&](const IRPosition &IRP) {
2617 bool IsKnownNonNull;
2619 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2620 };
2621
2622 bool Stripped;
2623 bool UsedAssumedInformation = false;
2624 Value *AssociatedValue = &getAssociatedValue();
2626 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2627 AA::AnyScope, UsedAssumedInformation))
2628 Stripped = false;
2629 else
2630 Stripped =
2631 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2632
2633 if (!Stripped) {
2634 bool IsKnown;
2635 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2636 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2637 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2638 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2639 IsKnown);
2640 }))
2641 return ChangeStatus::UNCHANGED;
2642 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2644 A, this, IRPosition::value(*Select->getFalseValue()),
2645 DepClassTy::OPTIONAL, IsKnown) &&
2647 A, this, IRPosition::value(*Select->getTrueValue()),
2648 DepClassTy::OPTIONAL, IsKnown))
2649 return ChangeStatus::UNCHANGED;
2650
2651 // If we haven't stripped anything we might still be able to use a
2652 // different AA, but only if the IRP changes. Effectively when we
2653 // interpret this not as a call site value but as a floating/argument
2654 // value.
2655 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2656 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2657 return indicatePessimisticFixpoint();
2658 return ChangeStatus::UNCHANGED;
2659 }
2660
2661 for (const auto &VAC : Values)
2662 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2663 return indicatePessimisticFixpoint();
2664
2665 return ChangeStatus::UNCHANGED;
2666 }
2667
2668 /// See AbstractAttribute::trackStatistics()
2669 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2670};
2671
2672/// NonNull attribute for function return value.
2673struct AANonNullReturned final
2674 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2675 false, AANonNull::IRAttributeKind, false> {
2676 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2677 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2678 false, Attribute::NonNull, false>(IRP, A) {
2679 }
2680
2681 /// See AbstractAttribute::getAsStr().
2682 const std::string getAsStr(Attributor *A) const override {
2683 return getAssumed() ? "nonnull" : "may-null";
2684 }
2685
2686 /// See AbstractAttribute::trackStatistics()
2687 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2688};
2689
2690/// NonNull attribute for function argument.
2691struct AANonNullArgument final
2692 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2693 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2694 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2695
2696 /// See AbstractAttribute::trackStatistics()
2697 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2698};
2699
2700struct AANonNullCallSiteArgument final : AANonNullFloating {
2701 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2702 : AANonNullFloating(IRP, A) {}
2703
2704 /// See AbstractAttribute::trackStatistics()
2705 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2706};
2707
2708/// NonNull attribute for a call site return position.
2709struct AANonNullCallSiteReturned final
2710 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2711 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2712 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2713
2714 /// See AbstractAttribute::trackStatistics()
2715 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2716};
2717} // namespace
2718
2719/// ------------------------ Must-Progress Attributes --------------------------
2720namespace {
2721struct AAMustProgressImpl : public AAMustProgress {
2722 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2723 : AAMustProgress(IRP, A) {}
2724
2725 /// See AbstractAttribute::initialize(...).
2726 void initialize(Attributor &A) override {
2727 bool IsKnown;
2729 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2730 (void)IsKnown;
2731 }
2732
2733 /// See AbstractAttribute::getAsStr()
2734 const std::string getAsStr(Attributor *A) const override {
2735 return getAssumed() ? "mustprogress" : "may-not-progress";
2736 }
2737};
2738
2739struct AAMustProgressFunction final : AAMustProgressImpl {
2740 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2741 : AAMustProgressImpl(IRP, A) {}
2742
2743 /// See AbstractAttribute::updateImpl(...).
2744 ChangeStatus updateImpl(Attributor &A) override {
2745 bool IsKnown;
2747 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2748 if (IsKnown)
2749 return indicateOptimisticFixpoint();
2750 return ChangeStatus::UNCHANGED;
2751 }
2752
2753 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2754 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2755 bool IsKnownMustProgress;
2757 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2758 /* IgnoreSubsumingPositions */ true);
2759 };
2760
2761 bool AllCallSitesKnown = true;
2762 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2763 /* RequireAllCallSites */ true,
2764 AllCallSitesKnown))
2765 return indicatePessimisticFixpoint();
2766
2767 return ChangeStatus::UNCHANGED;
2768 }
2769
2770 /// See AbstractAttribute::trackStatistics()
2771 void trackStatistics() const override {
2772 STATS_DECLTRACK_FN_ATTR(mustprogress)
2773 }
2774};
2775
2776/// MustProgress attribute deduction for a call sites.
2777struct AAMustProgressCallSite final : AAMustProgressImpl {
2778 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2779 : AAMustProgressImpl(IRP, A) {}
2780
2781 /// See AbstractAttribute::updateImpl(...).
2782 ChangeStatus updateImpl(Attributor &A) override {
2783 // TODO: Once we have call site specific value information we can provide
2784 // call site specific liveness information and then it makes
2785 // sense to specialize attributes for call sites arguments instead of
2786 // redirecting requests to the callee argument.
2787 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2788 bool IsKnownMustProgress;
2790 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2791 return indicatePessimisticFixpoint();
2792 return ChangeStatus::UNCHANGED;
2793 }
2794
2795 /// See AbstractAttribute::trackStatistics()
2796 void trackStatistics() const override {
2797 STATS_DECLTRACK_CS_ATTR(mustprogress);
2798 }
2799};
2800} // namespace
2801
2802/// ------------------------ No-Recurse Attributes ----------------------------
2803
2804namespace {
2805struct AANoRecurseImpl : public AANoRecurse {
2806 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2807
2808 /// See AbstractAttribute::initialize(...).
2809 void initialize(Attributor &A) override {
2810 bool IsKnown;
2812 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2813 (void)IsKnown;
2814 }
2815
2816 /// See AbstractAttribute::getAsStr()
2817 const std::string getAsStr(Attributor *A) const override {
2818 return getAssumed() ? "norecurse" : "may-recurse";
2819 }
2820};
2821
2822struct AANoRecurseFunction final : AANoRecurseImpl {
2823 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2824 : AANoRecurseImpl(IRP, A) {}
2825
2826 /// See AbstractAttribute::updateImpl(...).
2827 ChangeStatus updateImpl(Attributor &A) override {
2828
2829 // If all live call sites are known to be no-recurse, we are as well.
2830 auto CallSitePred = [&](AbstractCallSite ACS) {
2831 bool IsKnownNoRecurse;
2833 A, this,
2834 IRPosition::function(*ACS.getInstruction()->getFunction()),
2835 DepClassTy::NONE, IsKnownNoRecurse))
2836 return false;
2837 return IsKnownNoRecurse;
2838 };
2839 bool UsedAssumedInformation = false;
2840 if (A.checkForAllCallSites(CallSitePred, *this, true,
2841 UsedAssumedInformation)) {
2842 // If we know all call sites and all are known no-recurse, we are done.
2843 // If all known call sites, which might not be all that exist, are known
2844 // to be no-recurse, we are not done but we can continue to assume
2845 // no-recurse. If one of the call sites we have not visited will become
2846 // live, another update is triggered.
2847 if (!UsedAssumedInformation)
2848 indicateOptimisticFixpoint();
2849 return ChangeStatus::UNCHANGED;
2850 }
2851
2852 const AAInterFnReachability *EdgeReachability =
2853 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2854 DepClassTy::REQUIRED);
2855 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2856 return indicatePessimisticFixpoint();
2857 return ChangeStatus::UNCHANGED;
2858 }
2859
2860 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2861};
2862
2863/// NoRecurse attribute deduction for a call sites.
2864struct AANoRecurseCallSite final
2865 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2866 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2867 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2868
2869 /// See AbstractAttribute::trackStatistics()
2870 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2871};
2872} // namespace
2873
2874/// ------------------------ No-Convergent Attribute --------------------------
2875
2876namespace {
2877struct AANonConvergentImpl : public AANonConvergent {
2878 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2879 : AANonConvergent(IRP, A) {}
2880
2881 /// See AbstractAttribute::getAsStr()
2882 const std::string getAsStr(Attributor *A) const override {
2883 return getAssumed() ? "non-convergent" : "may-be-convergent";
2884 }
2885};
2886
2887struct AANonConvergentFunction final : AANonConvergentImpl {
2888 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2889 : AANonConvergentImpl(IRP, A) {}
2890
2891 /// See AbstractAttribute::updateImpl(...).
2892 ChangeStatus updateImpl(Attributor &A) override {
2893 // If all function calls are known to not be convergent, we are not
2894 // convergent.
2895 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2896 CallBase &CB = cast<CallBase>(Inst);
2898 if (!Callee || Callee->isIntrinsic()) {
2899 return false;
2900 }
2901 if (Callee->isDeclaration()) {
2902 return !Callee->hasFnAttribute(Attribute::Convergent);
2903 }
2904 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2905 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2906 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2907 };
2908
2909 bool UsedAssumedInformation = false;
2910 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2911 UsedAssumedInformation)) {
2912 return indicatePessimisticFixpoint();
2913 }
2914 return ChangeStatus::UNCHANGED;
2915 }
2916
2917 ChangeStatus manifest(Attributor &A) override {
2918 if (isKnownNotConvergent() &&
2919 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2920 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2921 return ChangeStatus::CHANGED;
2922 }
2923 return ChangeStatus::UNCHANGED;
2924 }
2925
2926 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2927};
2928} // namespace
2929
2930/// -------------------- Undefined-Behavior Attributes ------------------------
2931
2932namespace {
2933struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2934 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2935 : AAUndefinedBehavior(IRP, A) {}
2936
2937 /// See AbstractAttribute::updateImpl(...).
2938 // through a pointer (i.e. also branches etc.)
2939 ChangeStatus updateImpl(Attributor &A) override {
2940 const size_t UBPrevSize = KnownUBInsts.size();
2941 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2942
2943 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2944 // Lang ref now states volatile store is not UB, let's skip them.
2945 if (I.isVolatile() && I.mayWriteToMemory())
2946 return true;
2947
2948 // Skip instructions that are already saved.
2949 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2950 return true;
2951
2952 // If we reach here, we know we have an instruction
2953 // that accesses memory through a pointer operand,
2954 // for which getPointerOperand() should give it to us.
2955 Value *PtrOp =
2956 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2957 assert(PtrOp &&
2958 "Expected pointer operand of memory accessing instruction");
2959
2960 // Either we stopped and the appropriate action was taken,
2961 // or we got back a simplified value to continue.
2962 std::optional<Value *> SimplifiedPtrOp =
2963 stopOnUndefOrAssumed(A, PtrOp, &I);
2964 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2965 return true;
2966 const Value *PtrOpVal = *SimplifiedPtrOp;
2967
2968 // A memory access through a pointer is considered UB
2969 // only if the pointer has constant null value.
2970 // TODO: Expand it to not only check constant values.
2971 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2972 AssumedNoUBInsts.insert(&I);
2973 return true;
2974 }
2975 const Type *PtrTy = PtrOpVal->getType();
2976
2977 // Because we only consider instructions inside functions,
2978 // assume that a parent function exists.
2979 const Function *F = I.getFunction();
2980
2981 // A memory access using constant null pointer is only considered UB
2982 // if null pointer is _not_ defined for the target platform.
2984 AssumedNoUBInsts.insert(&I);
2985 else
2986 KnownUBInsts.insert(&I);
2987 return true;
2988 };
2989
2990 auto InspectBrInstForUB = [&](Instruction &I) {
2991 // A conditional branch instruction is considered UB if it has `undef`
2992 // condition.
2993
2994 // Skip instructions that are already saved.
2995 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2996 return true;
2997
2998 // We know we have a branch instruction.
2999 auto *BrInst = cast<BranchInst>(&I);
3000
3001 // Unconditional branches are never considered UB.
3002 if (BrInst->isUnconditional())
3003 return true;
3004
3005 // Either we stopped and the appropriate action was taken,
3006 // or we got back a simplified value to continue.
3007 std::optional<Value *> SimplifiedCond =
3008 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3009 if (!SimplifiedCond || !*SimplifiedCond)
3010 return true;
3011 AssumedNoUBInsts.insert(&I);
3012 return true;
3013 };
3014
3015 auto InspectCallSiteForUB = [&](Instruction &I) {
3016 // Check whether a callsite always cause UB or not
3017
3018 // Skip instructions that are already saved.
3019 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3020 return true;
3021
3022 // Check nonnull and noundef argument attribute violation for each
3023 // callsite.
3024 CallBase &CB = cast<CallBase>(I);
3026 if (!Callee)
3027 return true;
3028 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3029 // If current argument is known to be simplified to null pointer and the
3030 // corresponding argument position is known to have nonnull attribute,
3031 // the argument is poison. Furthermore, if the argument is poison and
3032 // the position is known to have noundef attriubte, this callsite is
3033 // considered UB.
3034 if (idx >= Callee->arg_size())
3035 break;
3036 Value *ArgVal = CB.getArgOperand(idx);
3037 if (!ArgVal)
3038 continue;
3039 // Here, we handle three cases.
3040 // (1) Not having a value means it is dead. (we can replace the value
3041 // with undef)
3042 // (2) Simplified to undef. The argument violate noundef attriubte.
3043 // (3) Simplified to null pointer where known to be nonnull.
3044 // The argument is a poison value and violate noundef attribute.
3045 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3046 bool IsKnownNoUndef;
3048 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3049 if (!IsKnownNoUndef)
3050 continue;
3051 bool UsedAssumedInformation = false;
3052 std::optional<Value *> SimplifiedVal =
3053 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3054 UsedAssumedInformation, AA::Interprocedural);
3055 if (UsedAssumedInformation)
3056 continue;
3057 if (SimplifiedVal && !*SimplifiedVal)
3058 return true;
3059 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3060 KnownUBInsts.insert(&I);
3061 continue;
3062 }
3063 if (!ArgVal->getType()->isPointerTy() ||
3064 !isa<ConstantPointerNull>(**SimplifiedVal))
3065 continue;
3066 bool IsKnownNonNull;
3068 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3069 if (IsKnownNonNull)
3070 KnownUBInsts.insert(&I);
3071 }
3072 return true;
3073 };
3074
3075 auto InspectReturnInstForUB = [&](Instruction &I) {
3076 auto &RI = cast<ReturnInst>(I);
3077 // Either we stopped and the appropriate action was taken,
3078 // or we got back a simplified return value to continue.
3079 std::optional<Value *> SimplifiedRetValue =
3080 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3081 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3082 return true;
3083
3084 // Check if a return instruction always cause UB or not
3085 // Note: It is guaranteed that the returned position of the anchor
3086 // scope has noundef attribute when this is called.
3087 // We also ensure the return position is not "assumed dead"
3088 // because the returned value was then potentially simplified to
3089 // `undef` in AAReturnedValues without removing the `noundef`
3090 // attribute yet.
3091
3092 // When the returned position has noundef attriubte, UB occurs in the
3093 // following cases.
3094 // (1) Returned value is known to be undef.
3095 // (2) The value is known to be a null pointer and the returned
3096 // position has nonnull attribute (because the returned value is
3097 // poison).
3098 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3099 bool IsKnownNonNull;
3101 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3102 IsKnownNonNull);
3103 if (IsKnownNonNull)
3104 KnownUBInsts.insert(&I);
3105 }
3106
3107 return true;
3108 };
3109
3110 bool UsedAssumedInformation = false;
3111 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3112 {Instruction::Load, Instruction::Store,
3113 Instruction::AtomicCmpXchg,
3114 Instruction::AtomicRMW},
3115 UsedAssumedInformation,
3116 /* CheckBBLivenessOnly */ true);
3117 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3118 UsedAssumedInformation,
3119 /* CheckBBLivenessOnly */ true);
3120 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3121 UsedAssumedInformation);
3122
3123 // If the returned position of the anchor scope has noundef attriubte, check
3124 // all returned instructions.
3125 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3126 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3127 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3128 bool IsKnownNoUndef;
3130 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3131 if (IsKnownNoUndef)
3132 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3133 {Instruction::Ret}, UsedAssumedInformation,
3134 /* CheckBBLivenessOnly */ true);
3135 }
3136 }
3137
3138 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3139 UBPrevSize != KnownUBInsts.size())
3140 return ChangeStatus::CHANGED;
3141 return ChangeStatus::UNCHANGED;
3142 }
3143
3144 bool isKnownToCauseUB(Instruction *I) const override {
3145 return KnownUBInsts.count(I);
3146 }
3147
3148 bool isAssumedToCauseUB(Instruction *I) const override {
3149 // In simple words, if an instruction is not in the assumed to _not_
3150 // cause UB, then it is assumed UB (that includes those
3151 // in the KnownUBInsts set). The rest is boilerplate
3152 // is to ensure that it is one of the instructions we test
3153 // for UB.
3154
3155 switch (I->getOpcode()) {
3156 case Instruction::Load:
3157 case Instruction::Store:
3158 case Instruction::AtomicCmpXchg:
3159 case Instruction::AtomicRMW:
3160 return !AssumedNoUBInsts.count(I);
3161 case Instruction::Br: {
3162 auto *BrInst = cast<BranchInst>(I);
3163 if (BrInst->isUnconditional())
3164 return false;
3165 return !AssumedNoUBInsts.count(I);
3166 } break;
3167 default:
3168 return false;
3169 }
3170 return false;
3171 }
3172
3173 ChangeStatus manifest(Attributor &A) override {
3174 if (KnownUBInsts.empty())
3175 return ChangeStatus::UNCHANGED;
3176 for (Instruction *I : KnownUBInsts)
3177 A.changeToUnreachableAfterManifest(I);
3178 return ChangeStatus::CHANGED;
3179 }
3180
3181 /// See AbstractAttribute::getAsStr()
3182 const std::string getAsStr(Attributor *A) const override {
3183 return getAssumed() ? "undefined-behavior" : "no-ub";
3184 }
3185
3186 /// Note: The correctness of this analysis depends on the fact that the
3187 /// following 2 sets will stop changing after some point.
3188 /// "Change" here means that their size changes.
3189 /// The size of each set is monotonically increasing
3190 /// (we only add items to them) and it is upper bounded by the number of
3191 /// instructions in the processed function (we can never save more
3192 /// elements in either set than this number). Hence, at some point,
3193 /// they will stop increasing.
3194 /// Consequently, at some point, both sets will have stopped
3195 /// changing, effectively making the analysis reach a fixpoint.
3196
3197 /// Note: These 2 sets are disjoint and an instruction can be considered
3198 /// one of 3 things:
3199 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3200 /// the KnownUBInsts set.
3201 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3202 /// has a reason to assume it).
3203 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3204 /// could not find a reason to assume or prove that it can cause UB,
3205 /// hence it assumes it doesn't. We have a set for these instructions
3206 /// so that we don't reprocess them in every update.
3207 /// Note however that instructions in this set may cause UB.
3208
3209protected:
3210 /// A set of all live instructions _known_ to cause UB.
3211 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3212
3213private:
3214 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3215 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3216
3217 // Should be called on updates in which if we're processing an instruction
3218 // \p I that depends on a value \p V, one of the following has to happen:
3219 // - If the value is assumed, then stop.
3220 // - If the value is known but undef, then consider it UB.
3221 // - Otherwise, do specific processing with the simplified value.
3222 // We return std::nullopt in the first 2 cases to signify that an appropriate
3223 // action was taken and the caller should stop.
3224 // Otherwise, we return the simplified value that the caller should
3225 // use for specific processing.
3226 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3227 Instruction *I) {
3228 bool UsedAssumedInformation = false;
3229 std::optional<Value *> SimplifiedV =
3230 A.getAssumedSimplified(IRPosition::value(*V), *this,
3231 UsedAssumedInformation, AA::Interprocedural);
3232 if (!UsedAssumedInformation) {
3233 // Don't depend on assumed values.
3234 if (!SimplifiedV) {
3235 // If it is known (which we tested above) but it doesn't have a value,
3236 // then we can assume `undef` and hence the instruction is UB.
3237 KnownUBInsts.insert(I);
3238 return std::nullopt;
3239 }
3240 if (!*SimplifiedV)
3241 return nullptr;
3242 V = *SimplifiedV;
3243 }
3244 if (isa<UndefValue>(V)) {
3245 KnownUBInsts.insert(I);
3246 return std::nullopt;
3247 }
3248 return V;
3249 }
3250};
3251
3252struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3253 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3254 : AAUndefinedBehaviorImpl(IRP, A) {}
3255
3256 /// See AbstractAttribute::trackStatistics()
3257 void trackStatistics() const override {
3258 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3259 "Number of instructions known to have UB");
3260 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3261 KnownUBInsts.size();
3262 }
3263};
3264} // namespace
3265
3266/// ------------------------ Will-Return Attributes ----------------------------
3267
3268namespace {
3269// Helper function that checks whether a function has any cycle which we don't
3270// know if it is bounded or not.
3271// Loops with maximum trip count are considered bounded, any other cycle not.
3272static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3273 ScalarEvolution *SE =
3274 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3275 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3276 // If either SCEV or LoopInfo is not available for the function then we assume
3277 // any cycle to be unbounded cycle.
3278 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3279 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3280 if (!SE || !LI) {
3281 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3282 if (SCCI.hasCycle())
3283 return true;
3284 return false;
3285 }
3286
3287 // If there's irreducible control, the function may contain non-loop cycles.
3289 return true;
3290
3291 // Any loop that does not have a max trip count is considered unbounded cycle.
3292 for (auto *L : LI->getLoopsInPreorder()) {
3293 if (!SE->getSmallConstantMaxTripCount(L))
3294 return true;
3295 }
3296 return false;
3297}
3298
3299struct AAWillReturnImpl : public AAWillReturn {
3300 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3301 : AAWillReturn(IRP, A) {}
3302
3303 /// See AbstractAttribute::initialize(...).
3304 void initialize(Attributor &A) override {
3305 bool IsKnown;
3307 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3308 (void)IsKnown;
3309 }
3310
3311 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3312 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3313 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3314 return false;
3315
3316 bool IsKnown;
3317 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3318 return IsKnown || !KnownOnly;
3319 return false;
3320 }
3321
3322 /// See AbstractAttribute::updateImpl(...).
3323 ChangeStatus updateImpl(Attributor &A) override {
3324 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3325 return ChangeStatus::UNCHANGED;
3326
3327 auto CheckForWillReturn = [&](Instruction &I) {
3329 bool IsKnown;
3331 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3332 if (IsKnown)
3333 return true;
3334 } else {
3335 return false;
3336 }
3337 bool IsKnownNoRecurse;
3339 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3340 };
3341
3342 bool UsedAssumedInformation = false;
3343 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3344 UsedAssumedInformation))
3345 return indicatePessimisticFixpoint();
3346
3347 return ChangeStatus::UNCHANGED;
3348 }
3349
3350 /// See AbstractAttribute::getAsStr()
3351 const std::string getAsStr(Attributor *A) const override {
3352 return getAssumed() ? "willreturn" : "may-noreturn";
3353 }
3354};
3355
3356struct AAWillReturnFunction final : AAWillReturnImpl {
3357 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3358 : AAWillReturnImpl(IRP, A) {}
3359
3360 /// See AbstractAttribute::initialize(...).
3361 void initialize(Attributor &A) override {
3362 AAWillReturnImpl::initialize(A);
3363
3364 Function *F = getAnchorScope();
3365 assert(F && "Did expect an anchor function");
3366 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3367 indicatePessimisticFixpoint();
3368 }
3369
3370 /// See AbstractAttribute::trackStatistics()
3371 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3372};
3373
3374/// WillReturn attribute deduction for a call sites.
3375struct AAWillReturnCallSite final
3376 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3377 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3378 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3379
3380 /// See AbstractAttribute::updateImpl(...).
3381 ChangeStatus updateImpl(Attributor &A) override {
3382 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3383 return ChangeStatus::UNCHANGED;
3384
3385 return AACalleeToCallSite::updateImpl(A);
3386 }
3387
3388 /// See AbstractAttribute::trackStatistics()
3389 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3390};
3391} // namespace
3392
3393/// -------------------AAIntraFnReachability Attribute--------------------------
3394
3395/// All information associated with a reachability query. This boilerplate code
3396/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3397/// different \p ToTy values.
3398template <typename ToTy> struct ReachabilityQueryInfo {
3399 enum class Reachable {
3402 };
3403
3404 /// Start here,
3405 const Instruction *From = nullptr;
3406 /// reach this place,
3407 const ToTy *To = nullptr;
3408 /// without going through any of these instructions,
3410 /// and remember if it worked:
3412
3413 /// Precomputed hash for this RQI.
3414 unsigned Hash = 0;
3415
3416 unsigned computeHashValue() const {
3417 assert(Hash == 0 && "Computed hash twice!");
3420 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3421 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3422 InstSetDMI::getHashValue(ExclusionSet));
3423 }
3424
3426 : From(From), To(To) {}
3427
3428 /// Constructor replacement to ensure unique and stable sets are used for the
3429 /// cache.
3431 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3432 : From(&From), To(&To), ExclusionSet(ES) {
3433
3434 if (!ES || ES->empty()) {
3435 ExclusionSet = nullptr;
3436 } else if (MakeUnique) {
3437 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3438 }
3439 }
3440
3443};
3444
3445namespace llvm {
3446template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3449
3452
3455 return &TombstoneKey;
3456 }
3457 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3458 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3459 }
3460 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3461 const ReachabilityQueryInfo<ToTy> *RHS) {
3462 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3463 return false;
3464 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3465 }
3466};
3467
3468#define DefineKeys(ToTy) \
3469 template <> \
3470 ReachabilityQueryInfo<ToTy> \
3471 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3472 ReachabilityQueryInfo<ToTy>( \
3473 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3474 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3475 template <> \
3476 ReachabilityQueryInfo<ToTy> \
3477 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3478 ReachabilityQueryInfo<ToTy>( \
3479 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3480 DenseMapInfo<const ToTy *>::getTombstoneKey());
3481
3483#undef DefineKeys
3484
3485} // namespace llvm
3486
3487namespace {
3488
3489template <typename BaseTy, typename ToTy>
3490struct CachedReachabilityAA : public BaseTy {
3491 using RQITy = ReachabilityQueryInfo<ToTy>;
3492
3493 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3494
3495 /// See AbstractAttribute::isQueryAA.
3496 bool isQueryAA() const override { return true; }
3497
3498 /// See AbstractAttribute::updateImpl(...).
3499 ChangeStatus updateImpl(Attributor &A) override {
3500 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3501 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3502 RQITy *RQI = QueryVector[u];
3503 if (RQI->Result == RQITy::Reachable::No &&
3504 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3505 Changed = ChangeStatus::CHANGED;
3506 }
3507 return Changed;
3508 }
3509
3510 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3511 bool IsTemporaryRQI) = 0;
3512
3513 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3514 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3515 RQI.Result = Result;
3516
3517 // Remove the temporary RQI from the cache.
3518 if (IsTemporaryRQI)
3519 QueryCache.erase(&RQI);
3520
3521 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3522 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3523 // this query. 2) We did not use the exclusion set, potentially because
3524 // there is none.
3525 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3526 RQITy PlainRQI(RQI.From, RQI.To);
3527 if (!QueryCache.count(&PlainRQI)) {
3528 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3529 RQIPtr->Result = Result;
3530 QueryVector.push_back(RQIPtr);
3531 QueryCache.insert(RQIPtr);
3532 }
3533 }
3534
3535 // Check if we need to insert a new permanent RQI with the exclusion set.
3536 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3537 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3538 "Did not expect empty set!");
3539 RQITy *RQIPtr = new (A.Allocator)
3540 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3541 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3542 RQIPtr->Result = Result;
3543 assert(!QueryCache.count(RQIPtr));
3544 QueryVector.push_back(RQIPtr);
3545 QueryCache.insert(RQIPtr);
3546 }
3547
3548 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3549 A.registerForUpdate(*this);
3550 return Result == RQITy::Reachable::Yes;
3551 }
3552
3553 const std::string getAsStr(Attributor *A) const override {
3554 // TODO: Return the number of reachable queries.
3555 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3556 }
3557
3558 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3559 typename RQITy::Reachable &Result) {
3560 if (!this->getState().isValidState()) {
3561 Result = RQITy::Reachable::Yes;
3562 return true;
3563 }
3564
3565 // If we have an exclusion set we might be able to find our answer by
3566 // ignoring it first.
3567 if (StackRQI.ExclusionSet) {
3568 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3569 auto It = QueryCache.find(&PlainRQI);
3570 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3571 Result = RQITy::Reachable::No;
3572 return true;
3573 }
3574 }
3575
3576 auto It = QueryCache.find(&StackRQI);
3577 if (It != QueryCache.end()) {
3578 Result = (*It)->Result;
3579 return true;
3580 }
3581
3582 // Insert a temporary for recursive queries. We will replace it with a
3583 // permanent entry later.
3584 QueryCache.insert(&StackRQI);
3585 return false;
3586 }
3587
3588private:
3589 SmallVector<RQITy *> QueryVector;
3590 DenseSet<RQITy *> QueryCache;
3591};
3592
3593struct AAIntraFnReachabilityFunction final
3594 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3595 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3596 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3597 : Base(IRP, A) {
3598 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3599 *IRP.getAssociatedFunction());
3600 }
3601
3602 bool isAssumedReachable(
3603 Attributor &A, const Instruction &From, const Instruction &To,
3604 const AA::InstExclusionSetTy *ExclusionSet) const override {
3605 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3606 if (&From == &To)
3607 return true;
3608
3609 RQITy StackRQI(A, From, To, ExclusionSet, false);
3610 RQITy::Reachable Result;
3611 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3612 return NonConstThis->isReachableImpl(A, StackRQI,
3613 /*IsTemporaryRQI=*/true);
3614 return Result == RQITy::Reachable::Yes;
3615 }
3616
3617 ChangeStatus updateImpl(Attributor &A) override {
3618 // We only depend on liveness. DeadEdges is all we care about, check if any
3619 // of them changed.
3620 auto *LivenessAA =
3621 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3622 if (LivenessAA &&
3623 llvm::all_of(DeadEdges,
3624 [&](const auto &DeadEdge) {
3625 return LivenessAA->isEdgeDead(DeadEdge.first,
3626 DeadEdge.second);
3627 }) &&
3628 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3629 return LivenessAA->isAssumedDead(BB);
3630 })) {
3631 return ChangeStatus::UNCHANGED;
3632 }
3633 DeadEdges.clear();
3634 DeadBlocks.clear();
3635 return Base::updateImpl(A);
3636 }
3637
3638 bool isReachableImpl(Attributor &A, RQITy &RQI,
3639 bool IsTemporaryRQI) override {
3640 const Instruction *Origin = RQI.From;
3641 bool UsedExclusionSet = false;
3642
3643 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3644 const AA::InstExclusionSetTy *ExclusionSet) {
3645 const Instruction *IP = &From;
3646 while (IP && IP != &To) {
3647 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3648 UsedExclusionSet = true;
3649 break;
3650 }
3651 IP = IP->getNextNode();
3652 }
3653 return IP == &To;
3654 };
3655
3656 const BasicBlock *FromBB = RQI.From->getParent();
3657 const BasicBlock *ToBB = RQI.To->getParent();
3658 assert(FromBB->getParent() == ToBB->getParent() &&
3659 "Not an intra-procedural query!");
3660
3661 // Check intra-block reachability, however, other reaching paths are still
3662 // possible.
3663 if (FromBB == ToBB &&
3664 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3665 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3666 IsTemporaryRQI);
3667
3668 // Check if reaching the ToBB block is sufficient or if even that would not
3669 // ensure reaching the target. In the latter case we are done.
3670 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3671 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3672 IsTemporaryRQI);
3673
3674 const Function *Fn = FromBB->getParent();
3675 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3676 if (RQI.ExclusionSet)
3677 for (auto *I : *RQI.ExclusionSet)
3678 if (I->getFunction() == Fn)
3679 ExclusionBlocks.insert(I->getParent());
3680
3681 // Check if we make it out of the FromBB block at all.
3682 if (ExclusionBlocks.count(FromBB) &&
3683 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3684 RQI.ExclusionSet))
3685 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3686
3687 auto *LivenessAA =
3688 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3689 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3690 DeadBlocks.insert(ToBB);
3691 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3692 IsTemporaryRQI);
3693 }
3694
3695 SmallPtrSet<const BasicBlock *, 16> Visited;
3697 Worklist.push_back(FromBB);
3698
3699 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3700 while (!Worklist.empty()) {
3701 const BasicBlock *BB = Worklist.pop_back_val();
3702 if (!Visited.insert(BB).second)
3703 continue;
3704 for (const BasicBlock *SuccBB : successors(BB)) {
3705 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3706 LocalDeadEdges.insert({BB, SuccBB});
3707 continue;
3708 }
3709 // We checked before if we just need to reach the ToBB block.
3710 if (SuccBB == ToBB)
3711 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3712 IsTemporaryRQI);
3713 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3714 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3715 IsTemporaryRQI);
3716
3717 if (ExclusionBlocks.count(SuccBB)) {
3718 UsedExclusionSet = true;
3719 continue;
3720 }
3721 Worklist.push_back(SuccBB);
3722 }
3723 }
3724
3725 DeadEdges.insert_range(LocalDeadEdges);
3726 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3727 IsTemporaryRQI);
3728 }
3729
3730 /// See AbstractAttribute::trackStatistics()
3731 void trackStatistics() const override {}
3732
3733private:
3734 // Set of assumed dead blocks we used in the last query. If any changes we
3735 // update the state.
3736 DenseSet<const BasicBlock *> DeadBlocks;
3737
3738 // Set of assumed dead edges we used in the last query. If any changes we
3739 // update the state.
3740 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3741
3742 /// The dominator tree of the function to short-circuit reasoning.
3743 const DominatorTree *DT = nullptr;
3744};
3745} // namespace
3746
3747/// ------------------------ NoAlias Argument Attribute ------------------------
3748
3750 Attribute::AttrKind ImpliedAttributeKind,
3751 bool IgnoreSubsumingPositions) {
3752 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3753 "Unexpected attribute kind");
3754 Value *Val = &IRP.getAssociatedValue();
3756 if (isa<AllocaInst>(Val))
3757 return true;
3758 } else {
3759 IgnoreSubsumingPositions = true;
3760 }
3761
3762 if (isa<UndefValue>(Val))
3763 return true;
3764
3765 if (isa<ConstantPointerNull>(Val) &&
3768 return true;
3769
3770 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3771 IgnoreSubsumingPositions, Attribute::NoAlias))
3772 return true;
3773
3774 return false;
3775}
3776
3777namespace {
3778struct AANoAliasImpl : AANoAlias {
3779 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3780 assert(getAssociatedType()->isPointerTy() &&
3781 "Noalias is a pointer attribute");
3782 }
3783
3784 const std::string getAsStr(Attributor *A) const override {
3785 return getAssumed() ? "noalias" : "may-alias";
3786 }
3787};
3788
3789/// NoAlias attribute for a floating value.
3790struct AANoAliasFloating final : AANoAliasImpl {
3791 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3792 : AANoAliasImpl(IRP, A) {}
3793
3794 /// See AbstractAttribute::updateImpl(...).
3795 ChangeStatus updateImpl(Attributor &A) override {
3796 // TODO: Implement this.
3797 return indicatePessimisticFixpoint();
3798 }
3799
3800 /// See AbstractAttribute::trackStatistics()
3801 void trackStatistics() const override {
3803 }
3804};
3805
3806/// NoAlias attribute for an argument.
3807struct AANoAliasArgument final
3808 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3809 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3810 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3811
3812 /// See AbstractAttribute::update(...).
3813 ChangeStatus updateImpl(Attributor &A) override {
3814 // We have to make sure no-alias on the argument does not break
3815 // synchronization when this is a callback argument, see also [1] below.
3816 // If synchronization cannot be affected, we delegate to the base updateImpl
3817 // function, otherwise we give up for now.
3818
3819 // If the function is no-sync, no-alias cannot break synchronization.
3820 bool IsKnownNoSycn;
3822 A, this, IRPosition::function_scope(getIRPosition()),
3823 DepClassTy::OPTIONAL, IsKnownNoSycn))
3824 return Base::updateImpl(A);
3825
3826 // If the argument is read-only, no-alias cannot break synchronization.
3827 bool IsKnown;
3828 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3829 return Base::updateImpl(A);
3830
3831 // If the argument is never passed through callbacks, no-alias cannot break
3832 // synchronization.
3833 bool UsedAssumedInformation = false;
3834 if (A.checkForAllCallSites(
3835 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3836 true, UsedAssumedInformation))
3837 return Base::updateImpl(A);
3838
3839 // TODO: add no-alias but make sure it doesn't break synchronization by
3840 // introducing fake uses. See:
3841 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3842 // International Workshop on OpenMP 2018,
3843 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3844
3845 return indicatePessimisticFixpoint();
3846 }
3847
3848 /// See AbstractAttribute::trackStatistics()
3849 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3850};
3851
3852struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3853 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3854 : AANoAliasImpl(IRP, A) {}
3855
3856 /// Determine if the underlying value may alias with the call site argument
3857 /// \p OtherArgNo of \p ICS (= the underlying call site).
3858 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3859 const AAMemoryBehavior &MemBehaviorAA,
3860 const CallBase &CB, unsigned OtherArgNo) {
3861 // We do not need to worry about aliasing with the underlying IRP.
3862 if (this->getCalleeArgNo() == (int)OtherArgNo)
3863 return false;
3864
3865 // If it is not a pointer or pointer vector we do not alias.
3866 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3867 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3868 return false;
3869
3870 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3871 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3872
3873 // If the argument is readnone, there is no read-write aliasing.
3874 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3875 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3876 return false;
3877 }
3878
3879 // If the argument is readonly and the underlying value is readonly, there
3880 // is no read-write aliasing.
3881 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3882 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3883 IsReadOnly) {
3884 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3885 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3886 return false;
3887 }
3888
3889 // We have to utilize actual alias analysis queries so we need the object.
3890 if (!AAR)
3891 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3892 *getAnchorScope());
3893
3894 // Try to rule it out at the call site.
3895 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3896 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3897 "callsite arguments: "
3898 << getAssociatedValue() << " " << *ArgOp << " => "
3899 << (IsAliasing ? "" : "no-") << "alias \n");
3900
3901 return IsAliasing;
3902 }
3903
3904 bool isKnownNoAliasDueToNoAliasPreservation(
3905 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3906 // We can deduce "noalias" if the following conditions hold.
3907 // (i) Associated value is assumed to be noalias in the definition.
3908 // (ii) Associated value is assumed to be no-capture in all the uses
3909 // possibly executed before this callsite.
3910 // (iii) There is no other pointer argument which could alias with the
3911 // value.
3912
3913 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3914 const Function *ScopeFn = VIRP.getAnchorScope();
3915 // Check whether the value is captured in the scope using AANoCapture.
3916 // Look at CFG and check only uses possibly executed before this
3917 // callsite.
3918 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3919 Instruction *UserI = cast<Instruction>(U.getUser());
3920
3921 // If UserI is the curr instruction and there is a single potential use of
3922 // the value in UserI we allow the use.
3923 // TODO: We should inspect the operands and allow those that cannot alias
3924 // with the value.
3925 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3926 return true;
3927
3928 if (ScopeFn) {
3929 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3930 if (CB->isArgOperand(&U)) {
3931
3932 unsigned ArgNo = CB->getArgOperandNo(&U);
3933
3934 bool IsKnownNoCapture;
3936 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3937 DepClassTy::OPTIONAL, IsKnownNoCapture))
3938 return true;
3939 }
3940 }
3941
3943 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3944 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3945 return true;
3946 }
3947
3948 // TODO: We should track the capturing uses in AANoCapture but the problem
3949 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3950 // a value in the module slice.
3951 // TODO(captures): Make this more precise.
3952 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3953 if (capturesNothing(CI))
3954 return true;
3955 if (CI.isPassthrough()) {
3956 Follow = true;
3957 return true;
3958 }
3959 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3960 return false;
3961 };
3962
3963 bool IsKnownNoCapture;
3964 const AANoCapture *NoCaptureAA = nullptr;
3965 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3966 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3967 if (!IsAssumedNoCapture &&
3968 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3969 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3970 LLVM_DEBUG(
3971 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3972 << " cannot be noalias as it is potentially captured\n");
3973 return false;
3974 }
3975 }
3976 if (NoCaptureAA)
3977 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3978
3979 // Check there is no other pointer argument which could alias with the
3980 // value passed at this call site.
3981 // TODO: AbstractCallSite
3982 const auto &CB = cast<CallBase>(getAnchorValue());
3983 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3984 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3985 return false;
3986
3987 return true;
3988 }
3989
3990 /// See AbstractAttribute::updateImpl(...).
3991 ChangeStatus updateImpl(Attributor &A) override {
3992 // If the argument is readnone we are done as there are no accesses via the
3993 // argument.
3994 auto *MemBehaviorAA =
3995 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
3996 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
3997 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3998 return ChangeStatus::UNCHANGED;
3999 }
4000
4001 bool IsKnownNoAlias;
4002 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4004 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4005 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4006 << " is not no-alias at the definition\n");
4007 return indicatePessimisticFixpoint();
4008 }
4009
4010 AAResults *AAR = nullptr;
4011 if (MemBehaviorAA &&
4012 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4013 LLVM_DEBUG(
4014 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4015 return ChangeStatus::UNCHANGED;
4016 }
4017
4018 return indicatePessimisticFixpoint();
4019 }
4020
4021 /// See AbstractAttribute::trackStatistics()
4022 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4023};
4024
4025/// NoAlias attribute for function return value.
4026struct AANoAliasReturned final : AANoAliasImpl {
4027 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4028 : AANoAliasImpl(IRP, A) {}
4029
4030 /// See AbstractAttribute::updateImpl(...).
4031 ChangeStatus updateImpl(Attributor &A) override {
4032
4033 auto CheckReturnValue = [&](Value &RV) -> bool {
4034 if (Constant *C = dyn_cast<Constant>(&RV))
4035 if (C->isNullValue() || isa<UndefValue>(C))
4036 return true;
4037
4038 /// For now, we can only deduce noalias if we have call sites.
4039 /// FIXME: add more support.
4040 if (!isa<CallBase>(&RV))
4041 return false;
4042
4043 const IRPosition &RVPos = IRPosition::value(RV);
4044 bool IsKnownNoAlias;
4046 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4047 return false;
4048
4049 bool IsKnownNoCapture;
4050 const AANoCapture *NoCaptureAA = nullptr;
4051 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4052 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4053 &NoCaptureAA);
4054 return IsAssumedNoCapture ||
4055 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4056 };
4057
4058 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4059 return indicatePessimisticFixpoint();
4060
4061 return ChangeStatus::UNCHANGED;
4062 }
4063
4064 /// See AbstractAttribute::trackStatistics()
4065 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4066};
4067
4068/// NoAlias attribute deduction for a call site return value.
4069struct AANoAliasCallSiteReturned final
4070 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4071 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4072 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4073
4074 /// See AbstractAttribute::trackStatistics()
4075 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4076};
4077} // namespace
4078
4079/// -------------------AAIsDead Function Attribute-----------------------
4080
4081namespace {
4082struct AAIsDeadValueImpl : public AAIsDead {
4083 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4084
4085 /// See AAIsDead::isAssumedDead().
4086 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4087
4088 /// See AAIsDead::isKnownDead().
4089 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4090
4091 /// See AAIsDead::isAssumedDead(BasicBlock *).
4092 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4093
4094 /// See AAIsDead::isKnownDead(BasicBlock *).
4095 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4096
4097 /// See AAIsDead::isAssumedDead(Instruction *I).
4098 bool isAssumedDead(const Instruction *I) const override {
4099 return I == getCtxI() && isAssumedDead();
4100 }
4101
4102 /// See AAIsDead::isKnownDead(Instruction *I).
4103 bool isKnownDead(const Instruction *I) const override {
4104 return isAssumedDead(I) && isKnownDead();
4105 }
4106
4107 /// See AbstractAttribute::getAsStr().
4108 const std::string getAsStr(Attributor *A) const override {
4109 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4110 }
4111
4112 /// Check if all uses are assumed dead.
4113 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4114 // Callers might not check the type, void has no uses.
4115 if (V.getType()->isVoidTy() || V.use_empty())
4116 return true;
4117
4118 // If we replace a value with a constant there are no uses left afterwards.
4119 if (!isa<Constant>(V)) {
4120 if (auto *I = dyn_cast<Instruction>(&V))
4121 if (!A.isRunOn(*I->getFunction()))
4122 return false;
4123 bool UsedAssumedInformation = false;
4124 std::optional<Constant *> C =
4125 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4126 if (!C || *C)
4127 return true;
4128 }
4129
4130 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4131 // Explicitly set the dependence class to required because we want a long
4132 // chain of N dependent instructions to be considered live as soon as one is
4133 // without going through N update cycles. This is not required for
4134 // correctness.
4135 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4136 DepClassTy::REQUIRED,
4137 /* IgnoreDroppableUses */ false);
4138 }
4139
4140 /// Determine if \p I is assumed to be side-effect free.
4141 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4143 return true;
4144
4145 auto *CB = dyn_cast<CallBase>(I);
4146 if (!CB || isa<IntrinsicInst>(CB))
4147 return false;
4148
4149 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4150
4151 bool IsKnownNoUnwind;
4153 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4154 return false;
4155
4156 bool IsKnown;
4157 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4158 }
4159};
4160
4161struct AAIsDeadFloating : public AAIsDeadValueImpl {
4162 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4163 : AAIsDeadValueImpl(IRP, A) {}
4164
4165 /// See AbstractAttribute::initialize(...).
4166 void initialize(Attributor &A) override {
4167 AAIsDeadValueImpl::initialize(A);
4168
4169 if (isa<UndefValue>(getAssociatedValue())) {
4170 indicatePessimisticFixpoint();
4171 return;
4172 }
4173
4174 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4175 if (!isAssumedSideEffectFree(A, I)) {
4177 indicatePessimisticFixpoint();
4178 else
4179 removeAssumedBits(HAS_NO_EFFECT);
4180 }
4181 }
4182
4183 bool isDeadFence(Attributor &A, FenceInst &FI) {
4184 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4185 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4186 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4187 return false;
4188 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4189 return true;
4190 }
4191
4192 bool isDeadStore(Attributor &A, StoreInst &SI,
4193 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4194 // Lang ref now states volatile store is not UB/dead, let's skip them.
4195 if (SI.isVolatile())
4196 return false;
4197
4198 // If we are collecting assumes to be deleted we are in the manifest stage.
4199 // It's problematic to collect the potential copies again now so we use the
4200 // cached ones.
4201 bool UsedAssumedInformation = false;
4202 if (!AssumeOnlyInst) {
4203 PotentialCopies.clear();
4204 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4205 UsedAssumedInformation)) {
4206 LLVM_DEBUG(
4207 dbgs()
4208 << "[AAIsDead] Could not determine potential copies of store!\n");
4209 return false;
4210 }
4211 }
4212 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4213 << " potential copies.\n");
4214
4215 InformationCache &InfoCache = A.getInfoCache();
4216 return llvm::all_of(PotentialCopies, [&](Value *V) {
4217 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4218 UsedAssumedInformation))
4219 return true;
4220 if (auto *LI = dyn_cast<LoadInst>(V)) {
4221 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4222 auto &UserI = cast<Instruction>(*U.getUser());
4223 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4224 if (AssumeOnlyInst)
4225 AssumeOnlyInst->insert(&UserI);
4226 return true;
4227 }
4228 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4229 })) {
4230 return true;
4231 }
4232 }
4233 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4234 << " is assumed live!\n");
4235 return false;
4236 });
4237 }
4238
4239 /// See AbstractAttribute::getAsStr().
4240 const std::string getAsStr(Attributor *A) const override {
4241 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4243 if (isValidState())
4244 return "assumed-dead-store";
4246 if (isValidState())
4247 return "assumed-dead-fence";
4248 return AAIsDeadValueImpl::getAsStr(A);
4249 }
4250
4251 /// See AbstractAttribute::updateImpl(...).
4252 ChangeStatus updateImpl(Attributor &A) override {
4253 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4254 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4255 if (!isDeadStore(A, *SI))
4256 return indicatePessimisticFixpoint();
4257 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4258 if (!isDeadFence(A, *FI))
4259 return indicatePessimisticFixpoint();
4260 } else {
4261 if (!isAssumedSideEffectFree(A, I))
4262 return indicatePessimisticFixpoint();
4263 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4264 return indicatePessimisticFixpoint();
4265 }
4267 }
4268
4269 bool isRemovableStore() const override {
4270 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4271 }
4272
4273 /// See AbstractAttribute::manifest(...).
4274 ChangeStatus manifest(Attributor &A) override {
4275 Value &V = getAssociatedValue();
4276 if (auto *I = dyn_cast<Instruction>(&V)) {
4277 // If we get here we basically know the users are all dead. We check if
4278 // isAssumedSideEffectFree returns true here again because it might not be
4279 // the case and only the users are dead but the instruction (=call) is
4280 // still needed.
4281 if (auto *SI = dyn_cast<StoreInst>(I)) {
4282 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4283 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4284 (void)IsDead;
4285 assert(IsDead && "Store was assumed to be dead!");
4286 A.deleteAfterManifest(*I);
4287 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4288 Instruction *AOI = AssumeOnlyInst[i];
4289 for (auto *Usr : AOI->users())
4290 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4291 A.deleteAfterManifest(*AOI);
4292 }
4293 return ChangeStatus::CHANGED;
4294 }
4295 if (auto *FI = dyn_cast<FenceInst>(I)) {
4296 assert(isDeadFence(A, *FI));
4297 A.deleteAfterManifest(*FI);
4298 return ChangeStatus::CHANGED;
4299 }
4300 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4301 A.deleteAfterManifest(*I);
4302 return ChangeStatus::CHANGED;
4303 }
4304 }
4306 }
4307
4308 /// See AbstractAttribute::trackStatistics()
4309 void trackStatistics() const override {
4311 }
4312
4313private:
4314 // The potential copies of a dead store, used for deletion during manifest.
4315 SmallSetVector<Value *, 4> PotentialCopies;
4316};
4317
4318struct AAIsDeadArgument : public AAIsDeadFloating {
4319 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4320 : AAIsDeadFloating(IRP, A) {}
4321
4322 /// See AbstractAttribute::manifest(...).
4323 ChangeStatus manifest(Attributor &A) override {
4324 Argument &Arg = *getAssociatedArgument();
4325 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4326 if (A.registerFunctionSignatureRewrite(
4327 Arg, /* ReplacementTypes */ {},
4330 return ChangeStatus::CHANGED;
4331 }
4332 return ChangeStatus::UNCHANGED;
4333 }
4334
4335 /// See AbstractAttribute::trackStatistics()
4336 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4337};
4338
4339struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4340 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4341 : AAIsDeadValueImpl(IRP, A) {}
4342
4343 /// See AbstractAttribute::initialize(...).
4344 void initialize(Attributor &A) override {
4345 AAIsDeadValueImpl::initialize(A);
4346 if (isa<UndefValue>(getAssociatedValue()))
4347 indicatePessimisticFixpoint();
4348 }
4349
4350 /// See AbstractAttribute::updateImpl(...).
4351 ChangeStatus updateImpl(Attributor &A) override {
4352 // TODO: Once we have call site specific value information we can provide
4353 // call site specific liveness information and then it makes
4354 // sense to specialize attributes for call sites arguments instead of
4355 // redirecting requests to the callee argument.
4356 Argument *Arg = getAssociatedArgument();
4357 if (!Arg)
4358 return indicatePessimisticFixpoint();
4359 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4360 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4361 if (!ArgAA)
4362 return indicatePessimisticFixpoint();
4363 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4364 }
4365
4366 /// See AbstractAttribute::manifest(...).
4367 ChangeStatus manifest(Attributor &A) override {
4368 CallBase &CB = cast<CallBase>(getAnchorValue());
4369 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4370 assert(!isa<UndefValue>(U.get()) &&
4371 "Expected undef values to be filtered out!");
4372 UndefValue &UV = *UndefValue::get(U->getType());
4373 if (A.changeUseAfterManifest(U, UV))
4374 return ChangeStatus::CHANGED;
4375 return ChangeStatus::UNCHANGED;
4376 }
4377
4378 /// See AbstractAttribute::trackStatistics()
4379 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4380};
4381
4382struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4383 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4384 : AAIsDeadFloating(IRP, A) {}
4385
4386 /// See AAIsDead::isAssumedDead().
4387 bool isAssumedDead() const override {
4388 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4389 }
4390
4391 /// See AbstractAttribute::initialize(...).
4392 void initialize(Attributor &A) override {
4393 AAIsDeadFloating::initialize(A);
4394 if (isa<UndefValue>(getAssociatedValue())) {
4395 indicatePessimisticFixpoint();
4396 return;
4397 }
4398
4399 // We track this separately as a secondary state.
4400 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4401 }
4402
4403 /// See AbstractAttribute::updateImpl(...).
4404 ChangeStatus updateImpl(Attributor &A) override {
4405 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4406 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4407 IsAssumedSideEffectFree = false;
4408 Changed = ChangeStatus::CHANGED;
4409 }
4410 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4411 return indicatePessimisticFixpoint();
4412 return Changed;
4413 }
4414
4415 /// See AbstractAttribute::trackStatistics()
4416 void trackStatistics() const override {
4417 if (IsAssumedSideEffectFree)
4419 else
4420 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4421 }
4422
4423 /// See AbstractAttribute::getAsStr().
4424 const std::string getAsStr(Attributor *A) const override {
4425 return isAssumedDead()
4426 ? "assumed-dead"
4427 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4428 }
4429
4430private:
4431 bool IsAssumedSideEffectFree = true;
4432};
4433
4434struct AAIsDeadReturned : public AAIsDeadValueImpl {
4435 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4436 : AAIsDeadValueImpl(IRP, A) {}
4437
4438 /// See AbstractAttribute::updateImpl(...).
4439 ChangeStatus updateImpl(Attributor &A) override {
4440
4441 bool UsedAssumedInformation = false;
4442 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4443 {Instruction::Ret}, UsedAssumedInformation);
4444
4445 auto PredForCallSite = [&](AbstractCallSite ACS) {
4446 if (ACS.isCallbackCall() || !ACS.getInstruction())
4447 return false;
4448 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4449 };
4450
4451 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4452 UsedAssumedInformation))
4453 return indicatePessimisticFixpoint();
4454
4455 return ChangeStatus::UNCHANGED;
4456 }
4457
4458 /// See AbstractAttribute::manifest(...).
4459 ChangeStatus manifest(Attributor &A) override {
4460 // TODO: Rewrite the signature to return void?
4461 bool AnyChange = false;
4462 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4463 auto RetInstPred = [&](Instruction &I) {
4464 ReturnInst &RI = cast<ReturnInst>(I);
4466 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4467 return true;
4468 };
4469 bool UsedAssumedInformation = false;
4470 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4471 UsedAssumedInformation);
4472 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4473 }
4474
4475 /// See AbstractAttribute::trackStatistics()
4476 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4477};
4478
4479struct AAIsDeadFunction : public AAIsDead {
4480 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4481
4482 /// See AbstractAttribute::initialize(...).
4483 void initialize(Attributor &A) override {
4484 Function *F = getAnchorScope();
4485 assert(F && "Did expect an anchor function");
4486 if (!isAssumedDeadInternalFunction(A)) {
4487 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4488 assumeLive(A, F->getEntryBlock());
4489 }
4490 }
4491
4492 bool isAssumedDeadInternalFunction(Attributor &A) {
4493 if (!getAnchorScope()->hasLocalLinkage())
4494 return false;
4495 bool UsedAssumedInformation = false;
4496 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4497 true, UsedAssumedInformation);
4498 }
4499
4500 /// See AbstractAttribute::getAsStr().
4501 const std::string getAsStr(Attributor *A) const override {
4502 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4503 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4504 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4505 std::to_string(KnownDeadEnds.size()) + "]";
4506 }
4507
4508 /// See AbstractAttribute::manifest(...).
4509 ChangeStatus manifest(Attributor &A) override {
4510 assert(getState().isValidState() &&
4511 "Attempted to manifest an invalid state!");
4512
4513 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4514 Function &F = *getAnchorScope();
4515
4516 if (AssumedLiveBlocks.empty()) {
4517 A.deleteAfterManifest(F);
4518 return ChangeStatus::CHANGED;
4519 }
4520
4521 // Flag to determine if we can change an invoke to a call assuming the
4522 // callee is nounwind. This is not possible if the personality of the
4523 // function allows to catch asynchronous exceptions.
4524 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4525
4526 KnownDeadEnds.set_union(ToBeExploredFrom);
4527 for (const Instruction *DeadEndI : KnownDeadEnds) {
4528 auto *CB = dyn_cast<CallBase>(DeadEndI);
4529 if (!CB)
4530 continue;
4531 bool IsKnownNoReturn;
4533 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4534 IsKnownNoReturn);
4535 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4536 continue;
4537
4538 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4539 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4540 else
4541 A.changeToUnreachableAfterManifest(
4542 const_cast<Instruction *>(DeadEndI->getNextNode()));
4543 HasChanged = ChangeStatus::CHANGED;
4544 }
4545
4546 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4547 for (BasicBlock &BB : F)
4548 if (!AssumedLiveBlocks.count(&BB)) {
4549 A.deleteAfterManifest(BB);
4550 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4551 HasChanged = ChangeStatus::CHANGED;
4552 }
4553
4554 return HasChanged;
4555 }
4556
4557 /// See AbstractAttribute::updateImpl(...).
4558 ChangeStatus updateImpl(Attributor &A) override;
4559
4560 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4561 assert(From->getParent() == getAnchorScope() &&
4562 To->getParent() == getAnchorScope() &&
4563 "Used AAIsDead of the wrong function");
4564 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4565 }
4566
4567 /// See AbstractAttribute::trackStatistics()
4568 void trackStatistics() const override {}
4569
4570 /// Returns true if the function is assumed dead.
4571 bool isAssumedDead() const override { return false; }
4572
4573 /// See AAIsDead::isKnownDead().
4574 bool isKnownDead() const override { return false; }
4575
4576 /// See AAIsDead::isAssumedDead(BasicBlock *).
4577 bool isAssumedDead(const BasicBlock *BB) const override {
4578 assert(BB->getParent() == getAnchorScope() &&
4579 "BB must be in the same anchor scope function.");
4580
4581 if (!getAssumed())
4582 return false;
4583 return !AssumedLiveBlocks.count(BB);
4584 }
4585
4586 /// See AAIsDead::isKnownDead(BasicBlock *).
4587 bool isKnownDead(const BasicBlock *BB) const override {
4588 return getKnown() && isAssumedDead(BB);
4589 }
4590
4591 /// See AAIsDead::isAssumed(Instruction *I).
4592 bool isAssumedDead(const Instruction *I) const override {
4593 assert(I->getParent()->getParent() == getAnchorScope() &&
4594 "Instruction must be in the same anchor scope function.");
4595
4596 if (!getAssumed())
4597 return false;
4598
4599 // If it is not in AssumedLiveBlocks then it for sure dead.
4600 // Otherwise, it can still be after noreturn call in a live block.
4601 if (!AssumedLiveBlocks.count(I->getParent()))
4602 return true;
4603
4604 // If it is not after a liveness barrier it is live.
4605 const Instruction *PrevI = I->getPrevNode();
4606 while (PrevI) {
4607 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4608 return true;
4609 PrevI = PrevI->getPrevNode();
4610 }
4611 return false;
4612 }
4613
4614 /// See AAIsDead::isKnownDead(Instruction *I).
4615 bool isKnownDead(const Instruction *I) const override {
4616 return getKnown() && isAssumedDead(I);
4617 }
4618
4619 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4620 /// that internal function called from \p BB should now be looked at.
4621 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4622 if (!AssumedLiveBlocks.insert(&BB).second)
4623 return false;
4624
4625 // We assume that all of BB is (probably) live now and if there are calls to
4626 // internal functions we will assume that those are now live as well. This
4627 // is a performance optimization for blocks with calls to a lot of internal
4628 // functions. It can however cause dead functions to be treated as live.
4629 for (const Instruction &I : BB)
4630 if (const auto *CB = dyn_cast<CallBase>(&I))
4632 if (F->hasLocalLinkage())
4633 A.markLiveInternalFunction(*F);
4634 return true;
4635 }
4636
4637 /// Collection of instructions that need to be explored again, e.g., we
4638 /// did assume they do not transfer control to (one of their) successors.
4639 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4640
4641 /// Collection of instructions that are known to not transfer control.
4642 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4643
4644 /// Collection of all assumed live edges
4645 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4646
4647 /// Collection of all assumed live BasicBlocks.
4648 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4649};
4650
4651static bool
4652identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4653 AbstractAttribute &AA,
4654 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4655 const IRPosition &IPos = IRPosition::callsite_function(CB);
4656
4657 bool IsKnownNoReturn;
4659 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4660 return !IsKnownNoReturn;
4661 if (CB.isTerminator())
4662 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4663 else
4664 AliveSuccessors.push_back(CB.getNextNode());
4665 return false;
4666}
4667
4668static bool
4669identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4670 AbstractAttribute &AA,
4671 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4672 bool UsedAssumedInformation =
4673 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4674
4675 // First, determine if we can change an invoke to a call assuming the
4676 // callee is nounwind. This is not possible if the personality of the
4677 // function allows to catch asynchronous exceptions.
4678 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4679 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4680 } else {
4681 const IRPosition &IPos = IRPosition::callsite_function(II);
4682
4683 bool IsKnownNoUnwind;
4685 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4686 UsedAssumedInformation |= !IsKnownNoUnwind;
4687 } else {
4688 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4689 }
4690 }
4691 return UsedAssumedInformation;
4692}
4693
4694static bool
4695identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4696 AbstractAttribute &AA,
4697 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4698 bool UsedAssumedInformation = false;
4699 if (BI.getNumSuccessors() == 1) {
4700 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4701 } else {
4702 std::optional<Constant *> C =
4703 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4704 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4705 // No value yet, assume both edges are dead.
4706 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4707 const BasicBlock *SuccBB =
4708 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4709 AliveSuccessors.push_back(&SuccBB->front());
4710 } else {
4711 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4712 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4713 UsedAssumedInformation = false;
4714 }
4715 }
4716 return UsedAssumedInformation;
4717}
4718
4719static bool
4720identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4721 AbstractAttribute &AA,
4722 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4723 bool UsedAssumedInformation = false;
4725 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4726 Values, AA::AnyScope,
4727 UsedAssumedInformation)) {
4728 // Something went wrong, assume all successors are live.
4729 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4730 AliveSuccessors.push_back(&SuccBB->front());
4731 return false;
4732 }
4733
4734 if (Values.empty() ||
4735 (Values.size() == 1 &&
4736 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4737 // No valid value yet, assume all edges are dead.
4738 return UsedAssumedInformation;
4739 }
4740
4741 Type &Ty = *SI.getCondition()->getType();
4742 SmallPtrSet<ConstantInt *, 8> Constants;
4743 auto CheckForConstantInt = [&](Value *V) {
4744 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4745 Constants.insert(CI);
4746 return true;
4747 }
4748 return false;
4749 };
4750
4751 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4752 return CheckForConstantInt(VAC.getValue());
4753 })) {
4754 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4755 AliveSuccessors.push_back(&SuccBB->front());
4756 return UsedAssumedInformation;
4757 }
4758
4759 unsigned MatchedCases = 0;
4760 for (const auto &CaseIt : SI.cases()) {
4761 if (Constants.count(CaseIt.getCaseValue())) {
4762 ++MatchedCases;
4763 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4764 }
4765 }
4766
4767 // If all potential values have been matched, we will not visit the default
4768 // case.
4769 if (MatchedCases < Constants.size())
4770 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4771 return UsedAssumedInformation;
4772}
4773
4774ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4776
4777 if (AssumedLiveBlocks.empty()) {
4778 if (isAssumedDeadInternalFunction(A))
4780
4781 Function *F = getAnchorScope();
4782 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4783 assumeLive(A, F->getEntryBlock());
4784 Change = ChangeStatus::CHANGED;
4785 }
4786
4787 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4788 << getAnchorScope()->size() << "] BBs and "
4789 << ToBeExploredFrom.size() << " exploration points and "
4790 << KnownDeadEnds.size() << " known dead ends\n");
4791
4792 // Copy and clear the list of instructions we need to explore from. It is
4793 // refilled with instructions the next update has to look at.
4794 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4795 ToBeExploredFrom.end());
4796 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4797
4799 while (!Worklist.empty()) {
4800 const Instruction *I = Worklist.pop_back_val();
4801 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4802
4803 // Fast forward for uninteresting instructions. We could look for UB here
4804 // though.
4805 while (!I->isTerminator() && !isa<CallBase>(I))
4806 I = I->getNextNode();
4807
4808 AliveSuccessors.clear();
4809
4810 bool UsedAssumedInformation = false;
4811 switch (I->getOpcode()) {
4812 // TODO: look for (assumed) UB to backwards propagate "deadness".
4813 default:
4814 assert(I->isTerminator() &&
4815 "Expected non-terminators to be handled already!");
4816 for (const BasicBlock *SuccBB : successors(I->getParent()))
4817 AliveSuccessors.push_back(&SuccBB->front());
4818 break;
4819 case Instruction::Call:
4820 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4821 *this, AliveSuccessors);
4822 break;
4823 case Instruction::Invoke:
4824 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4825 *this, AliveSuccessors);
4826 break;
4827 case Instruction::Br:
4828 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4829 *this, AliveSuccessors);
4830 break;
4831 case Instruction::Switch:
4832 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4833 *this, AliveSuccessors);
4834 break;
4835 }
4836
4837 if (UsedAssumedInformation) {
4838 NewToBeExploredFrom.insert(I);
4839 } else if (AliveSuccessors.empty() ||
4840 (I->isTerminator() &&
4841 AliveSuccessors.size() < I->getNumSuccessors())) {
4842 if (KnownDeadEnds.insert(I))
4843 Change = ChangeStatus::CHANGED;
4844 }
4845
4846 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4847 << AliveSuccessors.size() << " UsedAssumedInformation: "
4848 << UsedAssumedInformation << "\n");
4849
4850 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4851 if (!I->isTerminator()) {
4852 assert(AliveSuccessors.size() == 1 &&
4853 "Non-terminator expected to have a single successor!");
4854 Worklist.push_back(AliveSuccessor);
4855 } else {
4856 // record the assumed live edge
4857 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4858 if (AssumedLiveEdges.insert(Edge).second)
4859 Change = ChangeStatus::CHANGED;
4860 if (assumeLive(A, *AliveSuccessor->getParent()))
4861 Worklist.push_back(AliveSuccessor);
4862 }
4863 }
4864 }
4865
4866 // Check if the content of ToBeExploredFrom changed, ignore the order.
4867 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4868 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4869 return !ToBeExploredFrom.count(I);
4870 })) {
4871 Change = ChangeStatus::CHANGED;
4872 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4873 }
4874
4875 // If we know everything is live there is no need to query for liveness.
4876 // Instead, indicating a pessimistic fixpoint will cause the state to be
4877 // "invalid" and all queries to be answered conservatively without lookups.
4878 // To be in this state we have to (1) finished the exploration and (3) not
4879 // discovered any non-trivial dead end and (2) not ruled unreachable code
4880 // dead.
4881 if (ToBeExploredFrom.empty() &&
4882 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4883 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4884 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4885 }))
4886 return indicatePessimisticFixpoint();
4887 return Change;
4888}
4889
4890/// Liveness information for a call sites.
4891struct AAIsDeadCallSite final : AAIsDeadFunction {
4892 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4893 : AAIsDeadFunction(IRP, A) {}
4894
4895 /// See AbstractAttribute::initialize(...).
4896 void initialize(Attributor &A) override {
4897 // TODO: Once we have call site specific value information we can provide
4898 // call site specific liveness information and then it makes
4899 // sense to specialize attributes for call sites instead of
4900 // redirecting requests to the callee.
4901 llvm_unreachable("Abstract attributes for liveness are not "
4902 "supported for call sites yet!");
4903 }
4904
4905 /// See AbstractAttribute::updateImpl(...).
4906 ChangeStatus updateImpl(Attributor &A) override {
4907 return indicatePessimisticFixpoint();
4908 }
4909
4910 /// See AbstractAttribute::trackStatistics()
4911 void trackStatistics() const override {}
4912};
4913} // namespace
4914
4915/// -------------------- Dereferenceable Argument Attribute --------------------
4916
4917namespace {
4918struct AADereferenceableImpl : AADereferenceable {
4919 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4920 : AADereferenceable(IRP, A) {}
4921 using StateType = DerefState;
4922
4923 /// See AbstractAttribute::initialize(...).
4924 void initialize(Attributor &A) override {
4925 Value &V = *getAssociatedValue().stripPointerCasts();
4927 A.getAttrs(getIRPosition(),
4928 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4929 Attrs, /* IgnoreSubsumingPositions */ false);
4930 for (const Attribute &Attr : Attrs)
4931 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4932
4933 // Ensure we initialize the non-null AA (if necessary).
4934 bool IsKnownNonNull;
4936 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4937
4938 bool CanBeNull, CanBeFreed;
4939 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4940 A.getDataLayout(), CanBeNull, CanBeFreed));
4941
4942 if (Instruction *CtxI = getCtxI())
4943 followUsesInMBEC(*this, A, getState(), *CtxI);
4944 }
4945
4946 /// See AbstractAttribute::getState()
4947 /// {
4948 StateType &getState() override { return *this; }
4949 const StateType &getState() const override { return *this; }
4950 /// }
4951
4952 /// Helper function for collecting accessed bytes in must-be-executed-context
4953 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4954 DerefState &State) {
4955 const Value *UseV = U->get();
4956 if (!UseV->getType()->isPointerTy())
4957 return;
4958
4959 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4960 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4961 return;
4962
4963 int64_t Offset;
4965 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4966 if (Base && Base == &getAssociatedValue())
4967 State.addAccessedBytes(Offset, Loc->Size.getValue());
4968 }
4969
4970 /// See followUsesInMBEC
4971 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4972 AADereferenceable::StateType &State) {
4973 bool IsNonNull = false;
4974 bool TrackUse = false;
4975 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4976 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4977 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4978 << " for instruction " << *I << "\n");
4979
4980 addAccessedBytesForUse(A, U, I, State);
4981 State.takeKnownDerefBytesMaximum(DerefBytes);
4982 return TrackUse;
4983 }
4984
4985 /// See AbstractAttribute::manifest(...).
4986 ChangeStatus manifest(Attributor &A) override {
4987 ChangeStatus Change = AADereferenceable::manifest(A);
4988 bool IsKnownNonNull;
4989 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
4990 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
4991 if (IsAssumedNonNull &&
4992 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
4993 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
4994 return ChangeStatus::CHANGED;
4995 }
4996 return Change;
4997 }
4998
4999 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5000 SmallVectorImpl<Attribute> &Attrs) const override {
5001 // TODO: Add *_globally support
5002 bool IsKnownNonNull;
5003 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5004 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5005 if (IsAssumedNonNull)
5006 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5007 Ctx, getAssumedDereferenceableBytes()));
5008 else
5009 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5010 Ctx, getAssumedDereferenceableBytes()));
5011 }
5012
5013 /// See AbstractAttribute::getAsStr().
5014 const std::string getAsStr(Attributor *A) const override {
5015 if (!getAssumedDereferenceableBytes())
5016 return "unknown-dereferenceable";
5017 bool IsKnownNonNull;
5018 bool IsAssumedNonNull = false;
5019 if (A)
5021 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5022 return std::string("dereferenceable") +
5023 (IsAssumedNonNull ? "" : "_or_null") +
5024 (isAssumedGlobal() ? "_globally" : "") + "<" +
5025 std::to_string(getKnownDereferenceableBytes()) + "-" +
5026 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5027 (!A ? " [non-null is unknown]" : "");
5028 }
5029};
5030
5031/// Dereferenceable attribute for a floating value.
5032struct AADereferenceableFloating : AADereferenceableImpl {
5033 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5034 : AADereferenceableImpl(IRP, A) {}
5035
5036 /// See AbstractAttribute::updateImpl(...).
5037 ChangeStatus updateImpl(Attributor &A) override {
5038 bool Stripped;
5039 bool UsedAssumedInformation = false;
5041 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5042 AA::AnyScope, UsedAssumedInformation)) {
5043 Values.push_back({getAssociatedValue(), getCtxI()});
5044 Stripped = false;
5045 } else {
5046 Stripped = Values.size() != 1 ||
5047 Values.front().getValue() != &getAssociatedValue();
5048 }
5049
5050 const DataLayout &DL = A.getDataLayout();
5051 DerefState T;
5052
5053 auto VisitValueCB = [&](const Value &V) -> bool {
5054 unsigned IdxWidth =
5055 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5056 APInt Offset(IdxWidth, 0);
5058 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5059 /* AllowNonInbounds */ true);
5060
5061 const auto *AA = A.getAAFor<AADereferenceable>(
5062 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5063 int64_t DerefBytes = 0;
5064 if (!AA || (!Stripped && this == AA)) {
5065 // Use IR information if we did not strip anything.
5066 // TODO: track globally.
5067 bool CanBeNull, CanBeFreed;
5068 DerefBytes =
5069 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5070 T.GlobalState.indicatePessimisticFixpoint();
5071 } else {
5072 const DerefState &DS = AA->getState();
5073 DerefBytes = DS.DerefBytesState.getAssumed();
5074 T.GlobalState &= DS.GlobalState;
5075 }
5076
5077 // For now we do not try to "increase" dereferenceability due to negative
5078 // indices as we first have to come up with code to deal with loops and
5079 // for overflows of the dereferenceable bytes.
5080 int64_t OffsetSExt = Offset.getSExtValue();
5081 if (OffsetSExt < 0)
5082 OffsetSExt = 0;
5083
5084 T.takeAssumedDerefBytesMinimum(
5085 std::max(int64_t(0), DerefBytes - OffsetSExt));
5086
5087 if (this == AA) {
5088 if (!Stripped) {
5089 // If nothing was stripped IR information is all we got.
5090 T.takeKnownDerefBytesMaximum(
5091 std::max(int64_t(0), DerefBytes - OffsetSExt));
5092 T.indicatePessimisticFixpoint();
5093 } else if (OffsetSExt > 0) {
5094 // If something was stripped but there is circular reasoning we look
5095 // for the offset. If it is positive we basically decrease the
5096 // dereferenceable bytes in a circular loop now, which will simply
5097 // drive them down to the known value in a very slow way which we
5098 // can accelerate.
5099 T.indicatePessimisticFixpoint();
5100 }
5101 }
5102
5103 return T.isValidState();
5104 };
5105
5106 for (const auto &VAC : Values)
5107 if (!VisitValueCB(*VAC.getValue()))
5108 return indicatePessimisticFixpoint();
5109
5110 return clampStateAndIndicateChange(getState(), T);
5111 }
5112
5113 /// See AbstractAttribute::trackStatistics()
5114 void trackStatistics() const override {
5115 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5116 }
5117};
5118
5119/// Dereferenceable attribute for a return value.
5120struct AADereferenceableReturned final
5121 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5122 using Base =
5123 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5124 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5125 : Base(IRP, A) {}
5126
5127 /// See AbstractAttribute::trackStatistics()
5128 void trackStatistics() const override {
5129 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5130 }
5131};
5132
5133/// Dereferenceable attribute for an argument
5134struct AADereferenceableArgument final
5135 : AAArgumentFromCallSiteArguments<AADereferenceable,
5136 AADereferenceableImpl> {
5137 using Base =
5138 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5139 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5140 : Base(IRP, A) {}
5141
5142 /// See AbstractAttribute::trackStatistics()
5143 void trackStatistics() const override {
5144 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5145 }
5146};
5147
5148/// Dereferenceable attribute for a call site argument.
5149struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5150 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5151 : AADereferenceableFloating(IRP, A) {}
5152
5153 /// See AbstractAttribute::trackStatistics()
5154 void trackStatistics() const override {
5155 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5156 }
5157};
5158
5159/// Dereferenceable attribute deduction for a call site return value.
5160struct AADereferenceableCallSiteReturned final
5161 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5162 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5163 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5164 : Base(IRP, A) {}
5165
5166 /// See AbstractAttribute::trackStatistics()
5167 void trackStatistics() const override {
5168 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5169 }
5170};
5171} // namespace
5172
5173// ------------------------ Align Argument Attribute ------------------------
5174
5175namespace {
5176
5177static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5178 Value &AssociatedValue, const Use *U,
5179 const Instruction *I, bool &TrackUse) {
5180 // We need to follow common pointer manipulation uses to the accesses they
5181 // feed into.
5182 if (isa<CastInst>(I)) {
5183 // Follow all but ptr2int casts.
5184 TrackUse = !isa<PtrToIntInst>(I);
5185 return 0;
5186 }
5187 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5188 if (GEP->hasAllConstantIndices())
5189 TrackUse = true;
5190 return 0;
5191 }
5192 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5193 switch (II->getIntrinsicID()) {
5194 case Intrinsic::ptrmask: {
5195 // Is it appropriate to pull attribute in initialization?
5196 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5197 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5198 const auto *AlignAA = A.getAAFor<AAAlign>(
5199 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5200 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5201 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5203 Align ConstAlign(UINT64_C(1) << ShiftValue);
5204 if (ConstAlign >= AlignAA->getKnownAlign())
5205 return Align(1).value();
5206 }
5207 if (AlignAA)
5208 return AlignAA->getKnownAlign().value();
5209 break;
5210 }
5211 default:
5212 break;
5213 }
5214
5215 MaybeAlign MA;
5216 if (const auto *CB = dyn_cast<CallBase>(I)) {
5217 if (CB->isBundleOperand(U) || CB->isCallee(U))
5218 return 0;
5219
5220 unsigned ArgNo = CB->getArgOperandNo(U);
5221 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5222 // As long as we only use known information there is no need to track
5223 // dependences here.
5224 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5225 if (AlignAA)
5226 MA = MaybeAlign(AlignAA->getKnownAlign());
5227 }
5228
5229 const DataLayout &DL = A.getDataLayout();
5230 const Value *UseV = U->get();
5231 if (auto *SI = dyn_cast<StoreInst>(I)) {
5232 if (SI->getPointerOperand() == UseV)
5233 MA = SI->getAlign();
5234 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5235 if (LI->getPointerOperand() == UseV)
5236 MA = LI->getAlign();
5237 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5238 if (AI->getPointerOperand() == UseV)
5239 MA = AI->getAlign();
5240 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5241 if (AI->getPointerOperand() == UseV)
5242 MA = AI->getAlign();
5243 }
5244
5245 if (!MA || *MA <= QueryingAA.getKnownAlign())
5246 return 0;
5247
5248 unsigned Alignment = MA->value();
5249 int64_t Offset;
5250
5251 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5252 if (Base == &AssociatedValue) {
5253 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5254 // So we can say that the maximum power of two which is a divisor of
5255 // gcd(Offset, Alignment) is an alignment.
5256
5257 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5258 Alignment = llvm::bit_floor(gcd);
5259 }
5260 }
5261
5262 return Alignment;
5263}
5264
5265struct AAAlignImpl : AAAlign {
5266 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5267
5268 /// See AbstractAttribute::initialize(...).
5269 void initialize(Attributor &A) override {
5271 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5272 for (const Attribute &Attr : Attrs)
5273 takeKnownMaximum(Attr.getValueAsInt());
5274
5275 Value &V = *getAssociatedValue().stripPointerCasts();
5276 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5277
5278 if (Instruction *CtxI = getCtxI())
5279 followUsesInMBEC(*this, A, getState(), *CtxI);
5280 }
5281
5282 /// See AbstractAttribute::manifest(...).
5283 ChangeStatus manifest(Attributor &A) override {
5284 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5285
5286 // Check for users that allow alignment annotations.
5287 Value &AssociatedValue = getAssociatedValue();
5288 if (isa<ConstantData>(AssociatedValue))
5289 return ChangeStatus::UNCHANGED;
5290
5291 for (const Use &U : AssociatedValue.uses()) {
5292 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5293 if (SI->getPointerOperand() == &AssociatedValue)
5294 if (SI->getAlign() < getAssumedAlign()) {
5295 STATS_DECLTRACK(AAAlign, Store,
5296 "Number of times alignment added to a store");
5297 SI->setAlignment(getAssumedAlign());
5298 InstrChanged = ChangeStatus::CHANGED;
5299 }
5300 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5301 if (LI->getPointerOperand() == &AssociatedValue)
5302 if (LI->getAlign() < getAssumedAlign()) {
5303 LI->setAlignment(getAssumedAlign());
5304 STATS_DECLTRACK(AAAlign, Load,
5305 "Number of times alignment added to a load");
5306 InstrChanged = ChangeStatus::CHANGED;
5307 }
5308 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5309 if (RMW->getPointerOperand() == &AssociatedValue) {
5310 if (RMW->getAlign() < getAssumedAlign()) {
5311 STATS_DECLTRACK(AAAlign, AtomicRMW,
5312 "Number of times alignment added to atomicrmw");
5313
5314 RMW->setAlignment(getAssumedAlign());
5315 InstrChanged = ChangeStatus::CHANGED;
5316 }
5317 }
5318 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5319 if (CAS->getPointerOperand() == &AssociatedValue) {
5320 if (CAS->getAlign() < getAssumedAlign()) {
5321 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5322 "Number of times alignment added to cmpxchg");
5323 CAS->setAlignment(getAssumedAlign());
5324 InstrChanged = ChangeStatus::CHANGED;
5325 }
5326 }
5327 }
5328 }
5329
5330 ChangeStatus Changed = AAAlign::manifest(A);
5331
5332 Align InheritAlign =
5333 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5334 if (InheritAlign >= getAssumedAlign())
5335 return InstrChanged;
5336 return Changed | InstrChanged;
5337 }
5338
5339 // TODO: Provide a helper to determine the implied ABI alignment and check in
5340 // the existing manifest method and a new one for AAAlignImpl that value
5341 // to avoid making the alignment explicit if it did not improve.
5342
5343 /// See AbstractAttribute::getDeducedAttributes
5344 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5345 SmallVectorImpl<Attribute> &Attrs) const override {
5346 if (getAssumedAlign() > 1)
5347 Attrs.emplace_back(
5348 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5349 }
5350
5351 /// See followUsesInMBEC
5352 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5353 AAAlign::StateType &State) {
5354 bool TrackUse = false;
5355
5356 unsigned int KnownAlign =
5357 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5358 State.takeKnownMaximum(KnownAlign);
5359
5360 return TrackUse;
5361 }
5362
5363 /// See AbstractAttribute::getAsStr().
5364 const std::string getAsStr(Attributor *A) const override {
5365 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5366 std::to_string(getAssumedAlign().value()) + ">";
5367 }
5368};
5369
5370/// Align attribute for a floating value.
5371struct AAAlignFloating : AAAlignImpl {
5372 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5373
5374 /// See AbstractAttribute::updateImpl(...).
5375 ChangeStatus updateImpl(Attributor &A) override {
5376 const DataLayout &DL = A.getDataLayout();
5377
5378 bool Stripped;
5379 bool UsedAssumedInformation = false;
5381 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5382 AA::AnyScope, UsedAssumedInformation)) {
5383 Values.push_back({getAssociatedValue(), getCtxI()});
5384 Stripped = false;
5385 } else {
5386 Stripped = Values.size() != 1 ||
5387 Values.front().getValue() != &getAssociatedValue();
5388 }
5389
5390 StateType T;
5391 auto VisitValueCB = [&](Value &V) -> bool {
5393 return true;
5394 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5395 DepClassTy::REQUIRED);
5396 if (!AA || (!Stripped && this == AA)) {
5397 int64_t Offset;
5398 unsigned Alignment = 1;
5399 if (const Value *Base =
5401 // TODO: Use AAAlign for the base too.
5402 Align PA = Base->getPointerAlignment(DL);
5403 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5404 // So we can say that the maximum power of two which is a divisor of
5405 // gcd(Offset, Alignment) is an alignment.
5406
5407 uint32_t gcd =
5408 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5409 Alignment = llvm::bit_floor(gcd);
5410 } else {
5411 Alignment = V.getPointerAlignment(DL).value();
5412 }
5413 // Use only IR information if we did not strip anything.
5414 T.takeKnownMaximum(Alignment);
5415 T.indicatePessimisticFixpoint();
5416 } else {
5417 // Use abstract attribute information.
5418 const AAAlign::StateType &DS = AA->getState();
5419 T ^= DS;
5420 }
5421 return T.isValidState();
5422 };
5423
5424 for (const auto &VAC : Values) {
5425 if (!VisitValueCB(*VAC.getValue()))
5426 return indicatePessimisticFixpoint();
5427 }
5428
5429 // TODO: If we know we visited all incoming values, thus no are assumed
5430 // dead, we can take the known information from the state T.
5431 return clampStateAndIndicateChange(getState(), T);
5432 }
5433
5434 /// See AbstractAttribute::trackStatistics()
5435 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5436};
5437
5438/// Align attribute for function return value.
5439struct AAAlignReturned final
5440 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5441 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5442 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5443
5444 /// See AbstractAttribute::trackStatistics()
5445 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5446};
5447
5448/// Align attribute for function argument.
5449struct AAAlignArgument final
5450 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5451 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5452 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5453
5454 /// See AbstractAttribute::manifest(...).
5455 ChangeStatus manifest(Attributor &A) override {
5456 // If the associated argument is involved in a must-tail call we give up
5457 // because we would need to keep the argument alignments of caller and
5458 // callee in-sync. Just does not seem worth the trouble right now.
5459 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5460 return ChangeStatus::UNCHANGED;
5461 return Base::manifest(A);
5462 }
5463
5464 /// See AbstractAttribute::trackStatistics()
5465 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5466};
5467
5468struct AAAlignCallSiteArgument final : AAAlignFloating {
5469 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5470 : AAAlignFloating(IRP, A) {}
5471
5472 /// See AbstractAttribute::manifest(...).
5473 ChangeStatus manifest(Attributor &A) override {
5474 // If the associated argument is involved in a must-tail call we give up
5475 // because we would need to keep the argument alignments of caller and
5476 // callee in-sync. Just does not seem worth the trouble right now.
5477 if (Argument *Arg = getAssociatedArgument())
5478 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5479 return ChangeStatus::UNCHANGED;
5480 ChangeStatus Changed = AAAlignImpl::manifest(A);
5481 Align InheritAlign =
5482 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5483 if (InheritAlign >= getAssumedAlign())
5484 Changed = ChangeStatus::UNCHANGED;
5485 return Changed;
5486 }
5487
5488 /// See AbstractAttribute::updateImpl(Attributor &A).
5489 ChangeStatus updateImpl(Attributor &A) override {
5490 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5491 if (Argument *Arg = getAssociatedArgument()) {
5492 // We only take known information from the argument
5493 // so we do not need to track a dependence.
5494 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5495 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5496 if (ArgAlignAA)
5497 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5498 }
5499 return Changed;
5500 }
5501
5502 /// See AbstractAttribute::trackStatistics()
5503 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5504};
5505
5506/// Align attribute deduction for a call site return value.
5507struct AAAlignCallSiteReturned final
5508 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5509 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5510 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5511 : Base(IRP, A) {}
5512
5513 ChangeStatus updateImpl(Attributor &A) override {
5514 Instruction *I = getIRPosition().getCtxI();
5515 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5516 switch (II->getIntrinsicID()) {
5517 case Intrinsic::ptrmask: {
5518 Align Alignment;
5519 bool Valid = false;
5520
5521 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5522 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5523 if (ConstVals && ConstVals->isValidState()) {
5524 unsigned ShiftValue =
5525 std::min(ConstVals->getAssumedMinTrailingZeros(),
5526 Value::MaxAlignmentExponent);
5527 Alignment = Align(UINT64_C(1) << ShiftValue);
5528 Valid = true;
5529 }
5530
5531 const auto *AlignAA =
5532 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5533 DepClassTy::REQUIRED);
5534 if (AlignAA && AlignAA->isValidState()) {
5535 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5536 Valid = true;
5537 }
5538
5539 if (Valid)
5541 this->getState(),
5542 std::min(this->getAssumedAlign(), Alignment).value());
5543 break;
5544 }
5545 default:
5546 break;
5547 }
5548 }
5549 return Base::updateImpl(A);
5550 };
5551 /// See AbstractAttribute::trackStatistics()
5552 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5553};
5554} // namespace
5555
5556/// ------------------ Function No-Return Attribute ----------------------------
5557namespace {
5558struct AANoReturnImpl : public AANoReturn {
5559 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5560
5561 /// See AbstractAttribute::initialize(...).
5562 void initialize(Attributor &A) override {
5563 bool IsKnown;
5565 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5566 (void)IsKnown;
5567 }
5568
5569 /// See AbstractAttribute::getAsStr().
5570 const std::string getAsStr(Attributor *A) const override {
5571 return getAssumed() ? "noreturn" : "may-return";
5572 }
5573
5574 /// See AbstractAttribute::updateImpl(Attributor &A).
5575 ChangeStatus updateImpl(Attributor &A) override {
5576 auto CheckForNoReturn = [](Instruction &) { return false; };
5577 bool UsedAssumedInformation = false;
5578 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5579 {(unsigned)Instruction::Ret},
5580 UsedAssumedInformation))
5581 return indicatePessimisticFixpoint();
5582 return ChangeStatus::UNCHANGED;
5583 }
5584};
5585
5586struct AANoReturnFunction final : AANoReturnImpl {
5587 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5588 : AANoReturnImpl(IRP, A) {}
5589
5590 /// See AbstractAttribute::trackStatistics()
5591 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5592};
5593
5594/// NoReturn attribute deduction for a call sites.
5595struct AANoReturnCallSite final
5596 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5597 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5598 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5599
5600 /// See AbstractAttribute::trackStatistics()
5601 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5602};
5603} // namespace
5604
5605/// ----------------------- Instance Info ---------------------------------
5606
5607namespace {
5608/// A class to hold the state of for no-capture attributes.
5609struct AAInstanceInfoImpl : public AAInstanceInfo {
5610 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5611 : AAInstanceInfo(IRP, A) {}
5612
5613 /// See AbstractAttribute::initialize(...).
5614 void initialize(Attributor &A) override {
5615 Value &V = getAssociatedValue();
5616 if (auto *C = dyn_cast<Constant>(&V)) {
5617 if (C->isThreadDependent())
5618 indicatePessimisticFixpoint();
5619 else
5620 indicateOptimisticFixpoint();
5621 return;
5622 }
5623 if (auto *CB = dyn_cast<CallBase>(&V))
5624 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5625 !CB->mayReadFromMemory()) {
5626 indicateOptimisticFixpoint();
5627 return;
5628 }
5629 if (auto *I = dyn_cast<Instruction>(&V)) {
5630 const auto *CI =
5631 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5632 *I->getFunction());
5633 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5634 indicatePessimisticFixpoint();
5635 return;
5636 }
5637 }
5638 }
5639
5640 /// See AbstractAttribute::updateImpl(...).
5641 ChangeStatus updateImpl(Attributor &A) override {
5642 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5643
5644 Value &V = getAssociatedValue();
5645 const Function *Scope = nullptr;
5646 if (auto *I = dyn_cast<Instruction>(&V))
5647 Scope = I->getFunction();
5648 if (auto *A = dyn_cast<Argument>(&V)) {
5649 Scope = A->getParent();
5650 if (!Scope->hasLocalLinkage())
5651 return Changed;
5652 }
5653 if (!Scope)
5654 return indicateOptimisticFixpoint();
5655
5656 bool IsKnownNoRecurse;
5658 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5659 IsKnownNoRecurse))
5660 return Changed;
5661
5662 auto UsePred = [&](const Use &U, bool &Follow) {
5663 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5664 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5665 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5666 Follow = true;
5667 return true;
5668 }
5669 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5670 (isa<StoreInst>(UserI) &&
5671 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5672 return true;
5673 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5674 // This check is not guaranteeing uniqueness but for now that we cannot
5675 // end up with two versions of \p U thinking it was one.
5677 if (!Callee || !Callee->hasLocalLinkage())
5678 return true;
5679 if (!CB->isArgOperand(&U))
5680 return false;
5681 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5683 DepClassTy::OPTIONAL);
5684 if (!ArgInstanceInfoAA ||
5685 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5686 return false;
5687 // If this call base might reach the scope again we might forward the
5688 // argument back here. This is very conservative.
5690 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5691 [Scope](const Function &Fn) { return &Fn != Scope; }))
5692 return false;
5693 return true;
5694 }
5695 return false;
5696 };
5697
5698 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5699 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5700 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5701 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5702 AA::isDynamicallyUnique(A, *this, *Ptr))
5703 return true;
5704 }
5705 return false;
5706 };
5707
5708 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5709 DepClassTy::OPTIONAL,
5710 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5711 return indicatePessimisticFixpoint();
5712
5713 return Changed;
5714 }
5715
5716 /// See AbstractState::getAsStr().
5717 const std::string getAsStr(Attributor *A) const override {
5718 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5719 }
5720
5721 /// See AbstractAttribute::trackStatistics()
5722 void trackStatistics() const override {}
5723};
5724
5725/// InstanceInfo attribute for floating values.
5726struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5727 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5728 : AAInstanceInfoImpl(IRP, A) {}
5729};
5730
5731/// NoCapture attribute for function arguments.
5732struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5733 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5734 : AAInstanceInfoFloating(IRP, A) {}
5735};
5736
5737/// InstanceInfo attribute for call site arguments.
5738struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5739 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5740 : AAInstanceInfoImpl(IRP, A) {}
5741
5742 /// See AbstractAttribute::updateImpl(...).
5743 ChangeStatus updateImpl(Attributor &A) override {
5744 // TODO: Once we have call site specific value information we can provide
5745 // call site specific liveness information and then it makes
5746 // sense to specialize attributes for call sites arguments instead of
5747 // redirecting requests to the callee argument.
5748 Argument *Arg = getAssociatedArgument();
5749 if (!Arg)
5750 return indicatePessimisticFixpoint();
5751 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5752 auto *ArgAA =
5753 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5754 if (!ArgAA)
5755 return indicatePessimisticFixpoint();
5756 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5757 }
5758};
5759
5760/// InstanceInfo attribute for function return value.
5761struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5762 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5763 : AAInstanceInfoImpl(IRP, A) {
5764 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5765 }
5766
5767 /// See AbstractAttribute::initialize(...).
5768 void initialize(Attributor &A) override {
5769 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5770 }
5771
5772 /// See AbstractAttribute::updateImpl(...).
5773 ChangeStatus updateImpl(Attributor &A) override {
5774 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5775 }
5776};
5777
5778/// InstanceInfo attribute deduction for a call site return value.
5779struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5780 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5781 : AAInstanceInfoFloating(IRP, A) {}
5782};
5783} // namespace
5784
5785/// ----------------------- Variable Capturing ---------------------------------
5787 Attribute::AttrKind ImpliedAttributeKind,
5788 bool IgnoreSubsumingPositions) {
5789 assert(ImpliedAttributeKind == Attribute::Captures &&
5790 "Unexpected attribute kind");
5791 Value &V = IRP.getAssociatedValue();
5792 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5793 return V.use_empty();
5794
5795 // You cannot "capture" null in the default address space.
5796 //
5797 // FIXME: This should use NullPointerIsDefined to account for the function
5798 // attribute.
5800 V.getType()->getPointerAddressSpace() == 0)) {
5801 return true;
5802 }
5803
5805 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5806 /* IgnoreSubsumingPositions */ true);
5807 for (const Attribute &Attr : Attrs)
5808 if (capturesNothing(Attr.getCaptureInfo()))
5809 return true;
5810
5812 if (Argument *Arg = IRP.getAssociatedArgument()) {
5814 A.getAttrs(IRPosition::argument(*Arg),
5815 {Attribute::Captures, Attribute::ByVal}, Attrs,
5816 /* IgnoreSubsumingPositions */ true);
5817 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5818 return Attr.getKindAsEnum() == Attribute::ByVal ||
5820 });
5821 if (ArgNoCapture) {
5822 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5823 V.getContext(), CaptureInfo::none()));
5824 return true;
5825 }
5826 }
5827
5828 if (const Function *F = IRP.getAssociatedFunction()) {
5829 // Check what state the associated function can actually capture.
5832 if (State.isKnown(NO_CAPTURE)) {
5833 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5835 return true;
5836 }
5837 }
5838
5839 return false;
5840}
5841
5842/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5843/// depending on the ability of the function associated with \p IRP to capture
5844/// state in memory and through "returning/throwing", respectively.
5846 const Function &F,
5847 BitIntegerState &State) {
5848 // TODO: Once we have memory behavior attributes we should use them here.
5849
5850 // If we know we cannot communicate or write to memory, we do not care about
5851 // ptr2int anymore.
5852 bool ReadOnly = F.onlyReadsMemory();
5853 bool NoThrow = F.doesNotThrow();
5854 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5855 if (ReadOnly && NoThrow && IsVoidReturn) {
5856 State.addKnownBits(NO_CAPTURE);
5857 return;
5858 }
5859
5860 // A function cannot capture state in memory if it only reads memory, it can
5861 // however return/throw state and the state might be influenced by the
5862 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5863 if (ReadOnly)
5864 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5865
5866 // A function cannot communicate state back if it does not through
5867 // exceptions and doesn not return values.
5868 if (NoThrow && IsVoidReturn)
5869 State.addKnownBits(NOT_CAPTURED_IN_RET);
5870
5871 // Check existing "returned" attributes.
5872 int ArgNo = IRP.getCalleeArgNo();
5873 if (!NoThrow || ArgNo < 0 ||
5874 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5875 return;
5876
5877 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5878 if (F.hasParamAttribute(U, Attribute::Returned)) {
5879 if (U == unsigned(ArgNo))
5880 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5881 else if (ReadOnly)
5882 State.addKnownBits(NO_CAPTURE);
5883 else
5884 State.addKnownBits(NOT_CAPTURED_IN_RET);
5885 break;
5886 }
5887}
5888
5889namespace {
5890/// A class to hold the state of for no-capture attributes.
5891struct AANoCaptureImpl : public AANoCapture {
5892 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5893
5894 /// See AbstractAttribute::initialize(...).
5895 void initialize(Attributor &A) override {
5896 bool IsKnown;
5898 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5899 (void)IsKnown;
5900 }
5901
5902 /// See AbstractAttribute::updateImpl(...).
5903 ChangeStatus updateImpl(Attributor &A) override;
5904
5905 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5906 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5907 SmallVectorImpl<Attribute> &Attrs) const override {
5908 if (!isAssumedNoCaptureMaybeReturned())
5909 return;
5910
5911 if (isArgumentPosition()) {
5912 if (isAssumedNoCapture())
5913 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5914 else if (ManifestInternal)
5915 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5916 }
5917 }
5918
5919 /// See AbstractState::getAsStr().
5920 const std::string getAsStr(Attributor *A) const override {
5921 if (isKnownNoCapture())
5922 return "known not-captured";
5923 if (isAssumedNoCapture())
5924 return "assumed not-captured";
5925 if (isKnownNoCaptureMaybeReturned())
5926 return "known not-captured-maybe-returned";
5927 if (isAssumedNoCaptureMaybeReturned())
5928 return "assumed not-captured-maybe-returned";
5929 return "assumed-captured";
5930 }
5931
5932 /// Check the use \p U and update \p State accordingly. Return true if we
5933 /// should continue to update the state.
5934 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5935 bool &Follow) {
5936 Instruction *UInst = cast<Instruction>(U.getUser());
5937 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5938 << *UInst << "\n");
5939
5940 // Deal with ptr2int by following uses.
5941 if (isa<PtrToIntInst>(UInst)) {
5942 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5943 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5944 /* Return */ true);
5945 }
5946
5947 // For stores we already checked if we can follow them, if they make it
5948 // here we give up.
5949 if (isa<StoreInst>(UInst))
5950 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5951 /* Return */ true);
5952
5953 // Explicitly catch return instructions.
5954 if (isa<ReturnInst>(UInst)) {
5955 if (UInst->getFunction() == getAnchorScope())
5956 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5957 /* Return */ true);
5958 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5959 /* Return */ true);
5960 }
5961
5962 // For now we only use special logic for call sites. However, the tracker
5963 // itself knows about a lot of other non-capturing cases already.
5964 auto *CB = dyn_cast<CallBase>(UInst);
5965 if (!CB || !CB->isArgOperand(&U))
5966 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5967 /* Return */ true);
5968
5969 unsigned ArgNo = CB->getArgOperandNo(&U);
5970 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5971 // If we have a abstract no-capture attribute for the argument we can use
5972 // it to justify a non-capture attribute here. This allows recursion!
5973 bool IsKnownNoCapture;
5974 const AANoCapture *ArgNoCaptureAA = nullptr;
5975 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
5976 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5977 &ArgNoCaptureAA);
5978 if (IsAssumedNoCapture)
5979 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5980 /* Return */ false);
5981 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5982 Follow = true;
5983 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5984 /* Return */ false);
5985 }
5986
5987 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5988 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5989 /* Return */ true);
5990 }
5991
5992 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5993 /// \p CapturedInRet, then return true if we should continue updating the
5994 /// state.
5995 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
5996 bool CapturedInInt, bool CapturedInRet) {
5997 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
5998 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
5999 if (CapturedInMem)
6000 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6001 if (CapturedInInt)
6002 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6003 if (CapturedInRet)
6004 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6005 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6006 }
6007};
6008
6009ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6010 const IRPosition &IRP = getIRPosition();
6011 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6012 : &IRP.getAssociatedValue();
6013 if (!V)
6014 return indicatePessimisticFixpoint();
6015
6016 const Function *F =
6017 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6018
6019 // TODO: Is the checkForAllUses below useful for constants?
6020 if (!F)
6021 return indicatePessimisticFixpoint();
6022
6024 const IRPosition &FnPos = IRPosition::function(*F);
6025
6026 // Readonly means we cannot capture through memory.
6027 bool IsKnown;
6028 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6029 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6030 if (IsKnown)
6031 addKnownBits(NOT_CAPTURED_IN_MEM);
6032 }
6033
6034 // Make sure all returned values are different than the underlying value.
6035 // TODO: we could do this in a more sophisticated way inside
6036 // AAReturnedValues, e.g., track all values that escape through returns
6037 // directly somehow.
6038 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6040 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6042 UsedAssumedInformation))
6043 return false;
6044 bool SeenConstant = false;
6045 for (const AA::ValueAndContext &VAC : Values) {
6046 if (isa<Constant>(VAC.getValue())) {
6047 if (SeenConstant)
6048 return false;
6049 SeenConstant = true;
6050 } else if (!isa<Argument>(VAC.getValue()) ||
6051 VAC.getValue() == getAssociatedArgument())
6052 return false;
6053 }
6054 return true;
6055 };
6056
6057 bool IsKnownNoUnwind;
6059 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6060 bool IsVoidTy = F->getReturnType()->isVoidTy();
6061 bool UsedAssumedInformation = false;
6062 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6063 T.addKnownBits(NOT_CAPTURED_IN_RET);
6064 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6066 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6067 addKnownBits(NOT_CAPTURED_IN_RET);
6068 if (isKnown(NOT_CAPTURED_IN_MEM))
6069 return indicateOptimisticFixpoint();
6070 }
6071 }
6072 }
6073
6074 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6075 // TODO(captures): Make this more precise.
6076 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6077 if (capturesNothing(CI))
6078 return true;
6079 if (CI.isPassthrough()) {
6080 Follow = true;
6081 return true;
6082 }
6083 return checkUse(A, T, U, Follow);
6084 };
6085
6086 if (!A.checkForAllUses(UseCheck, *this, *V))
6087 return indicatePessimisticFixpoint();
6088
6089 AANoCapture::StateType &S = getState();
6090 auto Assumed = S.getAssumed();
6091 S.intersectAssumedBits(T.getAssumed());
6092 if (!isAssumedNoCaptureMaybeReturned())
6093 return indicatePessimisticFixpoint();
6094 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6096}
6097
6098/// NoCapture attribute for function arguments.
6099struct AANoCaptureArgument final : AANoCaptureImpl {
6100 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6101 : AANoCaptureImpl(IRP, A) {}
6102
6103 /// See AbstractAttribute::trackStatistics()
6104 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6105};
6106
6107/// NoCapture attribute for call site arguments.
6108struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6109 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6110 : AANoCaptureImpl(IRP, A) {}
6111
6112 /// See AbstractAttribute::updateImpl(...).
6113 ChangeStatus updateImpl(Attributor &A) override {
6114 // TODO: Once we have call site specific value information we can provide
6115 // call site specific liveness information and then it makes
6116 // sense to specialize attributes for call sites arguments instead of
6117 // redirecting requests to the callee argument.
6118 Argument *Arg = getAssociatedArgument();
6119 if (!Arg)
6120 return indicatePessimisticFixpoint();
6121 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6122 bool IsKnownNoCapture;
6123 const AANoCapture *ArgAA = nullptr;
6125 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6126 &ArgAA))
6127 return ChangeStatus::UNCHANGED;
6128 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6129 return indicatePessimisticFixpoint();
6130 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6131 }
6132
6133 /// See AbstractAttribute::trackStatistics()
6134 void trackStatistics() const override {
6136 };
6137};
6138
6139/// NoCapture attribute for floating values.
6140struct AANoCaptureFloating final : AANoCaptureImpl {
6141 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6142 : AANoCaptureImpl(IRP, A) {}
6143
6144 /// See AbstractAttribute::trackStatistics()
6145 void trackStatistics() const override {
6147 }
6148};
6149
6150/// NoCapture attribute for function return value.
6151struct AANoCaptureReturned final : AANoCaptureImpl {
6152 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6153 : AANoCaptureImpl(IRP, A) {
6154 llvm_unreachable("NoCapture is not applicable to function returns!");
6155 }
6156
6157 /// See AbstractAttribute::initialize(...).
6158 void initialize(Attributor &A) override {
6159 llvm_unreachable("NoCapture is not applicable to function returns!");
6160 }
6161
6162 /// See AbstractAttribute::updateImpl(...).
6163 ChangeStatus updateImpl(Attributor &A) override {
6164 llvm_unreachable("NoCapture is not applicable to function returns!");
6165 }
6166
6167 /// See AbstractAttribute::trackStatistics()
6168 void trackStatistics() const override {}
6169};
6170
6171/// NoCapture attribute deduction for a call site return value.
6172struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6173 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6174 : AANoCaptureImpl(IRP, A) {}
6175
6176 /// See AbstractAttribute::initialize(...).
6177 void initialize(Attributor &A) override {
6178 const Function *F = getAnchorScope();
6179 // Check what state the associated function can actually capture.
6180 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6181 }
6182
6183 /// See AbstractAttribute::trackStatistics()
6184 void trackStatistics() const override {
6186 }
6187};
6188} // namespace
6189
6190/// ------------------ Value Simplify Attribute ----------------------------
6191
6192bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6193 // FIXME: Add a typecast support.
6196 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6197 return false;
6198
6199 LLVM_DEBUG({
6201 dbgs() << "[ValueSimplify] is assumed to be "
6202 << **SimplifiedAssociatedValue << "\n";
6203 else
6204 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6205 });
6206 return true;
6207}
6208
6209namespace {
6210struct AAValueSimplifyImpl : AAValueSimplify {
6211 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6212 : AAValueSimplify(IRP, A) {}
6213
6214 /// See AbstractAttribute::initialize(...).
6215 void initialize(Attributor &A) override {
6216 if (getAssociatedValue().getType()->isVoidTy())
6217 indicatePessimisticFixpoint();
6218 if (A.hasSimplificationCallback(getIRPosition()))
6219 indicatePessimisticFixpoint();
6220 }
6221
6222 /// See AbstractAttribute::getAsStr().
6223 const std::string getAsStr(Attributor *A) const override {
6224 LLVM_DEBUG({
6225 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6226 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6227 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6228 });
6229 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6230 : "not-simple";
6231 }
6232
6233 /// See AbstractAttribute::trackStatistics()
6234 void trackStatistics() const override {}
6235
6236 /// See AAValueSimplify::getAssumedSimplifiedValue()
6237 std::optional<Value *>
6238 getAssumedSimplifiedValue(Attributor &A) const override {
6239 return SimplifiedAssociatedValue;
6240 }
6241
6242 /// Ensure the return value is \p V with type \p Ty, if not possible return
6243 /// nullptr. If \p Check is true we will only verify such an operation would
6244 /// suceed and return a non-nullptr value if that is the case. No IR is
6245 /// generated or modified.
6246 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6247 bool Check) {
6248 if (auto *TypedV = AA::getWithType(V, Ty))
6249 return TypedV;
6250 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6251 return Check ? &V
6252 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6253 &V, &Ty, "", CtxI->getIterator());
6254 return nullptr;
6255 }
6256
6257 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6258 /// If \p Check is true we will only verify such an operation would suceed and
6259 /// return a non-nullptr value if that is the case. No IR is generated or
6260 /// modified.
6261 static Value *reproduceInst(Attributor &A,
6262 const AbstractAttribute &QueryingAA,
6263 Instruction &I, Type &Ty, Instruction *CtxI,
6264 bool Check, ValueToValueMapTy &VMap) {
6265 assert(CtxI && "Cannot reproduce an instruction without context!");
6266 if (Check && (I.mayReadFromMemory() ||
6267 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6268 /* TLI */ nullptr)))
6269 return nullptr;
6270 for (Value *Op : I.operands()) {
6271 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6272 if (!NewOp) {
6273 assert(Check && "Manifest of new value unexpectedly failed!");
6274 return nullptr;
6275 }
6276 if (!Check)
6277 VMap[Op] = NewOp;
6278 }
6279 if (Check)
6280 return &I;
6281
6282 Instruction *CloneI = I.clone();
6283 // TODO: Try to salvage debug information here.
6284 CloneI->setDebugLoc(DebugLoc());
6285 VMap[&I] = CloneI;
6286 CloneI->insertBefore(CtxI->getIterator());
6287 RemapInstruction(CloneI, VMap);
6288 return CloneI;
6289 }
6290
6291 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6292 /// If \p Check is true we will only verify such an operation would suceed and
6293 /// return a non-nullptr value if that is the case. No IR is generated or
6294 /// modified.
6295 static Value *reproduceValue(Attributor &A,
6296 const AbstractAttribute &QueryingAA, Value &V,
6297 Type &Ty, Instruction *CtxI, bool Check,
6298 ValueToValueMapTy &VMap) {
6299 if (const auto &NewV = VMap.lookup(&V))
6300 return NewV;
6301 bool UsedAssumedInformation = false;
6302 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6303 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6304 if (!SimpleV.has_value())
6305 return PoisonValue::get(&Ty);
6306 Value *EffectiveV = &V;
6307 if (*SimpleV)
6308 EffectiveV = *SimpleV;
6309 if (auto *C = dyn_cast<Constant>(EffectiveV))
6310 return C;
6311 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6312 A.getInfoCache()))
6313 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6314 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6315 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6316 return ensureType(A, *NewV, Ty, CtxI, Check);
6317 return nullptr;
6318 }
6319
6320 /// Return a value we can use as replacement for the associated one, or
6321 /// nullptr if we don't have one that makes sense.
6322 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6323 Value *NewV = SimplifiedAssociatedValue
6324 ? *SimplifiedAssociatedValue
6325 : UndefValue::get(getAssociatedType());
6326 if (NewV && NewV != &getAssociatedValue()) {
6327 ValueToValueMapTy VMap;
6328 // First verify we can reprduce the value with the required type at the
6329 // context location before we actually start modifying the IR.
6330 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6331 /* CheckOnly */ true, VMap))
6332 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6333 /* CheckOnly */ false, VMap);
6334 }
6335 return nullptr;
6336 }
6337
6338 /// Helper function for querying AAValueSimplify and updating candidate.
6339 /// \param IRP The value position we are trying to unify with SimplifiedValue
6340 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6341 const IRPosition &IRP, bool Simplify = true) {
6342 bool UsedAssumedInformation = false;
6343 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6344 if (Simplify)
6345 QueryingValueSimplified = A.getAssumedSimplified(
6346 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6347 return unionAssumed(QueryingValueSimplified);
6348 }
6349
6350 /// Returns a candidate is found or not
6351 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6352 if (!getAssociatedValue().getType()->isIntegerTy())
6353 return false;
6354
6355 // This will also pass the call base context.
6356 const auto *AA =
6357 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6358 if (!AA)
6359 return false;
6360
6361 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6362
6363 if (!COpt) {
6364 SimplifiedAssociatedValue = std::nullopt;
6365 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6366 return true;
6367 }
6368 if (auto *C = *COpt) {
6369 SimplifiedAssociatedValue = C;
6370 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6371 return true;
6372 }
6373 return false;
6374 }
6375
6376 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6377 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6378 return true;
6379 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6380 return true;
6381 return false;
6382 }
6383
6384 /// See AbstractAttribute::manifest(...).
6385 ChangeStatus manifest(Attributor &A) override {
6386 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6387 for (auto &U : getAssociatedValue().uses()) {
6388 // Check if we need to adjust the insertion point to make sure the IR is
6389 // valid.
6390 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6391 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6392 IP = PHI->getIncomingBlock(U)->getTerminator();
6393 if (auto *NewV = manifestReplacementValue(A, IP)) {
6394 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6395 << " -> " << *NewV << " :: " << *this << "\n");
6396 if (A.changeUseAfterManifest(U, *NewV))
6397 Changed = ChangeStatus::CHANGED;
6398 }
6399 }
6400
6401 return Changed | AAValueSimplify::manifest(A);
6402 }
6403
6404 /// See AbstractState::indicatePessimisticFixpoint(...).
6405 ChangeStatus indicatePessimisticFixpoint() override {
6406 SimplifiedAssociatedValue = &getAssociatedValue();
6407 return AAValueSimplify::indicatePessimisticFixpoint();
6408 }
6409};
6410
6411struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6412 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6413 : AAValueSimplifyImpl(IRP, A) {}
6414
6415 void initialize(Attributor &A) override {
6416 AAValueSimplifyImpl::initialize(A);
6417 if (A.hasAttr(getIRPosition(),
6418 {Attribute::InAlloca, Attribute::Preallocated,
6419 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6420 /* IgnoreSubsumingPositions */ true))
6421 indicatePessimisticFixpoint();
6422 }
6423
6424 /// See AbstractAttribute::updateImpl(...).
6425 ChangeStatus updateImpl(Attributor &A) override {
6426 // Byval is only replacable if it is readonly otherwise we would write into
6427 // the replaced value and not the copy that byval creates implicitly.
6428 Argument *Arg = getAssociatedArgument();
6429 if (Arg->hasByValAttr()) {
6430 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6431 // there is no race by not copying a constant byval.
6432 bool IsKnown;
6433 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6434 return indicatePessimisticFixpoint();
6435 }
6436
6437 auto Before = SimplifiedAssociatedValue;
6438
6439 auto PredForCallSite = [&](AbstractCallSite ACS) {
6440 const IRPosition &ACSArgPos =
6441 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6442 // Check if a coresponding argument was found or if it is on not
6443 // associated (which can happen for callback calls).
6444 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6445 return false;
6446
6447 // Simplify the argument operand explicitly and check if the result is
6448 // valid in the current scope. This avoids refering to simplified values
6449 // in other functions, e.g., we don't want to say a an argument in a
6450 // static function is actually an argument in a different function.
6451 bool UsedAssumedInformation = false;
6452 std::optional<Constant *> SimpleArgOp =
6453 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6454 if (!SimpleArgOp)
6455 return true;
6456 if (!*SimpleArgOp)
6457 return false;
6458 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6459 return false;
6460 return unionAssumed(*SimpleArgOp);
6461 };
6462
6463 // Generate a answer specific to a call site context.
6464 bool Success;
6465 bool UsedAssumedInformation = false;
6466 if (hasCallBaseContext() &&
6467 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6468 Success = PredForCallSite(
6469 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6470 else
6471 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6472 UsedAssumedInformation);
6473
6474 if (!Success)
6475 if (!askSimplifiedValueForOtherAAs(A))
6476 return indicatePessimisticFixpoint();
6477
6478 // If a candidate was found in this update, return CHANGED.
6479 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6480 : ChangeStatus ::CHANGED;
6481 }
6482
6483 /// See AbstractAttribute::trackStatistics()
6484 void trackStatistics() const override {
6485 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6486 }
6487};
6488
6489struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6490 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6491 : AAValueSimplifyImpl(IRP, A) {}
6492
6493 /// See AAValueSimplify::getAssumedSimplifiedValue()
6494 std::optional<Value *>
6495 getAssumedSimplifiedValue(Attributor &A) const override {
6496 if (!isValidState())
6497 return nullptr;
6498 return SimplifiedAssociatedValue;
6499 }
6500
6501 /// See AbstractAttribute::updateImpl(...).
6502 ChangeStatus updateImpl(Attributor &A) override {
6503 auto Before = SimplifiedAssociatedValue;
6504
6505 auto ReturnInstCB = [&](Instruction &I) {
6506 auto &RI = cast<ReturnInst>(I);
6507 return checkAndUpdate(
6508 A, *this,
6509 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6510 };
6511
6512 bool UsedAssumedInformation = false;
6513 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6514 UsedAssumedInformation))
6515 if (!askSimplifiedValueForOtherAAs(A))
6516 return indicatePessimisticFixpoint();
6517
6518 // If a candidate was found in this update, return CHANGED.
6519 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6520 : ChangeStatus ::CHANGED;
6521 }
6522
6523 ChangeStatus manifest(Attributor &A) override {
6524 // We queried AAValueSimplify for the returned values so they will be
6525 // replaced if a simplified form was found. Nothing to do here.
6526 return ChangeStatus::UNCHANGED;
6527 }
6528
6529 /// See AbstractAttribute::trackStatistics()
6530 void trackStatistics() const override {
6531 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6532 }
6533};
6534
6535struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6536 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6537 : AAValueSimplifyImpl(IRP, A) {}
6538
6539 /// See AbstractAttribute::initialize(...).
6540 void initialize(Attributor &A) override {
6541 AAValueSimplifyImpl::initialize(A);
6542 Value &V = getAnchorValue();
6543
6544 // TODO: add other stuffs
6545 if (isa<Constant>(V))
6546 indicatePessimisticFixpoint();
6547 }
6548
6549 /// See AbstractAttribute::updateImpl(...).
6550 ChangeStatus updateImpl(Attributor &A) override {
6551 auto Before = SimplifiedAssociatedValue;
6552 if (!askSimplifiedValueForOtherAAs(A))
6553 return indicatePessimisticFixpoint();
6554
6555 // If a candidate was found in this update, return CHANGED.
6556 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6557 : ChangeStatus ::CHANGED;
6558 }
6559
6560 /// See AbstractAttribute::trackStatistics()
6561 void trackStatistics() const override {
6562 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6563 }
6564};
6565
6566struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6567 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6568 : AAValueSimplifyImpl(IRP, A) {}
6569
6570 /// See AbstractAttribute::initialize(...).
6571 void initialize(Attributor &A) override {
6572 SimplifiedAssociatedValue = nullptr;
6573 indicateOptimisticFixpoint();
6574 }
6575 /// See AbstractAttribute::initialize(...).
6576 ChangeStatus updateImpl(Attributor &A) override {
6578 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6579 }
6580 /// See AbstractAttribute::trackStatistics()
6581 void trackStatistics() const override {
6582 STATS_DECLTRACK_FN_ATTR(value_simplify)
6583 }
6584};
6585
6586struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6587 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6588 : AAValueSimplifyFunction(IRP, A) {}
6589 /// See AbstractAttribute::trackStatistics()
6590 void trackStatistics() const override {
6591 STATS_DECLTRACK_CS_ATTR(value_simplify)
6592 }
6593};
6594
6595struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6596 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6597 : AAValueSimplifyImpl(IRP, A) {}
6598
6599 void initialize(Attributor &A) override {
6600 AAValueSimplifyImpl::initialize(A);
6601 Function *Fn = getAssociatedFunction();
6602 assert(Fn && "Did expect an associted function");
6603 for (Argument &Arg : Fn->args()) {
6604 if (Arg.hasReturnedAttr()) {
6605 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6606 Arg.getArgNo());
6608 checkAndUpdate(A, *this, IRP))
6609 indicateOptimisticFixpoint();
6610 else
6611 indicatePessimisticFixpoint();
6612 return;
6613 }
6614 }
6615 }
6616
6617 /// See AbstractAttribute::updateImpl(...).
6618 ChangeStatus updateImpl(Attributor &A) override {
6619 return indicatePessimisticFixpoint();
6620 }
6621
6622 void trackStatistics() const override {
6623 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6624 }
6625};
6626
6627struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6628 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6629 : AAValueSimplifyFloating(IRP, A) {}
6630
6631 /// See AbstractAttribute::manifest(...).
6632 ChangeStatus manifest(Attributor &A) override {
6633 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6634 // TODO: We should avoid simplification duplication to begin with.
6635 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6636 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6637 if (FloatAA && FloatAA->getState().isValidState())
6638 return Changed;
6639
6640 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6641 Use &U = cast<CallBase>(&getAnchorValue())
6642 ->getArgOperandUse(getCallSiteArgNo());
6643 if (A.changeUseAfterManifest(U, *NewV))
6644 Changed = ChangeStatus::CHANGED;
6645 }
6646
6647 return Changed | AAValueSimplify::manifest(A);
6648 }
6649
6650 void trackStatistics() const override {
6651 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6652 }
6653};
6654} // namespace
6655
6656/// ----------------------- Heap-To-Stack Conversion ---------------------------
6657namespace {
6658struct AAHeapToStackFunction final : public AAHeapToStack {
6659
6660 struct AllocationInfo {
6661 /// The call that allocates the memory.
6662 CallBase *const CB;
6663
6664 /// The library function id for the allocation.
6665 LibFunc LibraryFunctionId = NotLibFunc;
6666
6667 /// The status wrt. a rewrite.
6668 enum {
6669 STACK_DUE_TO_USE,
6670 STACK_DUE_TO_FREE,
6671 INVALID,
6672 } Status = STACK_DUE_TO_USE;
6673
6674 /// Flag to indicate if we encountered a use that might free this allocation
6675 /// but which is not in the deallocation infos.
6676 bool HasPotentiallyFreeingUnknownUses = false;
6677
6678 /// Flag to indicate that we should place the new alloca in the function
6679 /// entry block rather than where the call site (CB) is.
6680 bool MoveAllocaIntoEntry = true;
6681
6682 /// The set of free calls that use this allocation.
6683 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6684 };
6685
6686 struct DeallocationInfo {
6687 /// The call that deallocates the memory.
6688 CallBase *const CB;
6689 /// The value freed by the call.
6690 Value *FreedOp;
6691
6692 /// Flag to indicate if we don't know all objects this deallocation might
6693 /// free.
6694 bool MightFreeUnknownObjects = false;
6695
6696 /// The set of allocation calls that are potentially freed.
6697 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6698 };
6699
6700 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6701 : AAHeapToStack(IRP, A) {}
6702
6703 ~AAHeapToStackFunction() override {
6704 // Ensure we call the destructor so we release any memory allocated in the
6705 // sets.
6706 for (auto &It : AllocationInfos)
6707 It.second->~AllocationInfo();
6708 for (auto &It : DeallocationInfos)
6709 It.second->~DeallocationInfo();
6710 }
6711
6712 void initialize(Attributor &A) override {
6713 AAHeapToStack::initialize(A);
6714
6715 const Function *F = getAnchorScope();
6716 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6717
6718 auto AllocationIdentifierCB = [&](Instruction &I) {
6719 CallBase *CB = dyn_cast<CallBase>(&I);
6720 if (!CB)
6721 return true;
6722 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6723 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6724 return true;
6725 }
6726 // To do heap to stack, we need to know that the allocation itself is
6727 // removable once uses are rewritten, and that we can initialize the
6728 // alloca to the same pattern as the original allocation result.
6729 if (isRemovableAlloc(CB, TLI)) {
6730 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6731 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6732 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6733 AllocationInfos[CB] = AI;
6734 if (TLI)
6735 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6736 }
6737 }
6738 return true;
6739 };
6740
6741 bool UsedAssumedInformation = false;
6742 bool Success = A.checkForAllCallLikeInstructions(
6743 AllocationIdentifierCB, *this, UsedAssumedInformation,
6744 /* CheckBBLivenessOnly */ false,
6745 /* CheckPotentiallyDead */ true);
6746 (void)Success;
6747 assert(Success && "Did not expect the call base visit callback to fail!");
6748
6750 [](const IRPosition &, const AbstractAttribute *,
6751 bool &) -> std::optional<Value *> { return nullptr; };
6752 for (const auto &It : AllocationInfos)
6753 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6754 SCB);
6755 for (const auto &It : DeallocationInfos)
6756 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6757 SCB);
6758 }
6759
6760 const std::string getAsStr(Attributor *A) const override {
6761 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6762 for (const auto &It : AllocationInfos) {
6763 if (It.second->Status == AllocationInfo::INVALID)
6764 ++NumInvalidMallocs;
6765 else
6766 ++NumH2SMallocs;
6767 }
6768 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6769 std::to_string(NumInvalidMallocs);
6770 }
6771
6772 /// See AbstractAttribute::trackStatistics().
6773 void trackStatistics() const override {
6774 STATS_DECL(
6775 MallocCalls, Function,
6776 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6777 for (const auto &It : AllocationInfos)
6778 if (It.second->Status != AllocationInfo::INVALID)
6779 ++BUILD_STAT_NAME(MallocCalls, Function);
6780 }
6781
6782 bool isAssumedHeapToStack(const CallBase &CB) const override {
6783 if (isValidState())
6784 if (AllocationInfo *AI =
6785 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6786 return AI->Status != AllocationInfo::INVALID;
6787 return false;
6788 }
6789
6790 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6791 if (!isValidState())
6792 return false;
6793
6794 for (const auto &It : AllocationInfos) {
6795 AllocationInfo &AI = *It.second;
6796 if (AI.Status == AllocationInfo::INVALID)
6797 continue;
6798
6799 if (AI.PotentialFreeCalls.count(&CB))
6800 return true;
6801 }
6802
6803 return false;
6804 }
6805
6806 ChangeStatus manifest(Attributor &A) override {
6807 assert(getState().isValidState() &&
6808 "Attempted to manifest an invalid state!");
6809
6810 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6811 Function *F = getAnchorScope();
6812 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6813
6814 for (auto &It : AllocationInfos) {
6815 AllocationInfo &AI = *It.second;
6816 if (AI.Status == AllocationInfo::INVALID)
6817 continue;
6818
6819 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6820 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6821 A.deleteAfterManifest(*FreeCall);
6822 HasChanged = ChangeStatus::CHANGED;
6823 }
6824
6825 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6826 << "\n");
6827
6828 auto Remark = [&](OptimizationRemark OR) {
6829 LibFunc IsAllocShared;
6830 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6831 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6832 return OR << "Moving globalized variable to the stack.";
6833 return OR << "Moving memory allocation from the heap to the stack.";
6834 };
6835 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6836 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6837 else
6838 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6839
6840 const DataLayout &DL = A.getInfoCache().getDL();
6841 Value *Size;
6842 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6843 if (SizeAPI) {
6844 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6845 } else {
6846 LLVMContext &Ctx = AI.CB->getContext();
6847 ObjectSizeOpts Opts;
6848 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6849 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6850 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6851 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6852 Size = SizeOffsetPair.Size;
6853 }
6854
6855 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6856 ? F->getEntryBlock().begin()
6857 : AI.CB->getIterator();
6858
6859 Align Alignment(1);
6860 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6861 Alignment = std::max(Alignment, *RetAlign);
6862 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6863 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6864 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6865 "Expected an alignment during manifest!");
6866 Alignment =
6867 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6868 }
6869
6870 // TODO: Hoist the alloca towards the function entry.
6871 unsigned AS = DL.getAllocaAddrSpace();
6872 Instruction *Alloca =
6873 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6874 AI.CB->getName() + ".h2s", IP);
6875
6876 if (Alloca->getType() != AI.CB->getType())
6877 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6878 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6879
6880 auto *I8Ty = Type::getInt8Ty(F->getContext());
6881 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6882 assert(InitVal &&
6883 "Must be able to materialize initial memory state of allocation");
6884
6885 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6886
6887 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6888 auto *NBB = II->getNormalDest();
6889 BranchInst::Create(NBB, AI.CB->getParent());
6890 A.deleteAfterManifest(*AI.CB);
6891 } else {
6892 A.deleteAfterManifest(*AI.CB);
6893 }
6894
6895 // Initialize the alloca with the same value as used by the allocation
6896 // function. We can skip undef as the initial value of an alloc is
6897 // undef, and the memset would simply end up being DSEd.
6898 if (!isa<UndefValue>(InitVal)) {
6899 IRBuilder<> Builder(Alloca->getNextNode());
6900 // TODO: Use alignment above if align!=1
6901 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6902 }
6903 HasChanged = ChangeStatus::CHANGED;
6904 }
6905
6906 return HasChanged;
6907 }
6908
6909 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6910 Value &V) {
6911 bool UsedAssumedInformation = false;
6912 std::optional<Constant *> SimpleV =
6913 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6914 if (!SimpleV)
6915 return APInt(64, 0);
6916 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6917 return CI->getValue();
6918 return std::nullopt;
6919 }
6920
6921 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6922 AllocationInfo &AI) {
6923 auto Mapper = [&](const Value *V) -> const Value * {
6924 bool UsedAssumedInformation = false;
6925 if (std::optional<Constant *> SimpleV =
6926 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6927 if (*SimpleV)
6928 return *SimpleV;
6929 return V;
6930 };
6931
6932 const Function *F = getAnchorScope();
6933 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6934 return getAllocSize(AI.CB, TLI, Mapper);
6935 }
6936
6937 /// Collection of all malloc-like calls in a function with associated
6938 /// information.
6939 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6940
6941 /// Collection of all free-like calls in a function with associated
6942 /// information.
6943 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6944
6945 ChangeStatus updateImpl(Attributor &A) override;
6946};
6947
6948ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6950 const Function *F = getAnchorScope();
6951 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6952
6953 const auto *LivenessAA =
6954 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6955
6956 MustBeExecutedContextExplorer *Explorer =
6957 A.getInfoCache().getMustBeExecutedContextExplorer();
6958
6959 bool StackIsAccessibleByOtherThreads =
6960 A.getInfoCache().stackIsAccessibleByOtherThreads();
6961
6962 LoopInfo *LI =
6963 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6964 std::optional<bool> MayContainIrreducibleControl;
6965 auto IsInLoop = [&](BasicBlock &BB) {
6966 if (&F->getEntryBlock() == &BB)
6967 return false;
6968 if (!MayContainIrreducibleControl.has_value())
6969 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6970 if (*MayContainIrreducibleControl)
6971 return true;
6972 if (!LI)
6973 return true;
6974 return LI->getLoopFor(&BB) != nullptr;
6975 };
6976
6977 // Flag to ensure we update our deallocation information at most once per
6978 // updateImpl call and only if we use the free check reasoning.
6979 bool HasUpdatedFrees = false;
6980
6981 auto UpdateFrees = [&]() {
6982 HasUpdatedFrees = true;
6983
6984 for (auto &It : DeallocationInfos) {
6985 DeallocationInfo &DI = *It.second;
6986 // For now we cannot use deallocations that have unknown inputs, skip
6987 // them.
6988 if (DI.MightFreeUnknownObjects)
6989 continue;
6990
6991 // No need to analyze dead calls, ignore them instead.
6992 bool UsedAssumedInformation = false;
6993 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
6994 /* CheckBBLivenessOnly */ true))
6995 continue;
6996
6997 // Use the non-optimistic version to get the freed object.
6998 Value *Obj = getUnderlyingObject(DI.FreedOp);
6999 if (!Obj) {
7000 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7001 DI.MightFreeUnknownObjects = true;
7002 continue;
7003 }
7004
7005 // Free of null and undef can be ignored as no-ops (or UB in the latter
7006 // case).
7008 continue;
7009
7010 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7011 if (!ObjCB) {
7012 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7013 << "\n");
7014 DI.MightFreeUnknownObjects = true;
7015 continue;
7016 }
7017
7018 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7019 if (!AI) {
7020 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7021 << "\n");
7022 DI.MightFreeUnknownObjects = true;
7023 continue;
7024 }
7025
7026 DI.PotentialAllocationCalls.insert(ObjCB);
7027 }
7028 };
7029
7030 auto FreeCheck = [&](AllocationInfo &AI) {
7031 // If the stack is not accessible by other threads, the "must-free" logic
7032 // doesn't apply as the pointer could be shared and needs to be places in
7033 // "shareable" memory.
7034 if (!StackIsAccessibleByOtherThreads) {
7035 bool IsKnownNoSycn;
7037 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7038 LLVM_DEBUG(
7039 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7040 "other threads and function is not nosync:\n");
7041 return false;
7042 }
7043 }
7044 if (!HasUpdatedFrees)
7045 UpdateFrees();
7046
7047 // TODO: Allow multi exit functions that have different free calls.
7048 if (AI.PotentialFreeCalls.size() != 1) {
7049 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7050 << AI.PotentialFreeCalls.size() << "\n");
7051 return false;
7052 }
7053 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7054 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7055 if (!DI) {
7056 LLVM_DEBUG(
7057 dbgs() << "[H2S] unique free call was not known as deallocation call "
7058 << *UniqueFree << "\n");
7059 return false;
7060 }
7061 if (DI->MightFreeUnknownObjects) {
7062 LLVM_DEBUG(
7063 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7064 return false;
7065 }
7066 if (DI->PotentialAllocationCalls.empty())
7067 return true;
7068 if (DI->PotentialAllocationCalls.size() > 1) {
7069 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7070 << DI->PotentialAllocationCalls.size()
7071 << " different allocations\n");
7072 return false;
7073 }
7074 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7075 LLVM_DEBUG(
7076 dbgs()
7077 << "[H2S] unique free call not known to free this allocation but "
7078 << **DI->PotentialAllocationCalls.begin() << "\n");
7079 return false;
7080 }
7081
7082 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
7083 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
7084 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7085 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7086 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7087 "with the allocation "
7088 << *UniqueFree << "\n");
7089 return false;
7090 }
7091 }
7092 return true;
7093 };
7094
7095 auto UsesCheck = [&](AllocationInfo &AI) {
7096 bool ValidUsesOnly = true;
7097
7098 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7099 Instruction *UserI = cast<Instruction>(U.getUser());
7100 if (isa<LoadInst>(UserI))
7101 return true;
7102 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7103 if (SI->getValueOperand() == U.get()) {
7105 << "[H2S] escaping store to memory: " << *UserI << "\n");
7106 ValidUsesOnly = false;
7107 } else {
7108 // A store into the malloc'ed memory is fine.
7109 }
7110 return true;
7111 }
7112 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7113 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7114 return true;
7115 if (DeallocationInfos.count(CB)) {
7116 AI.PotentialFreeCalls.insert(CB);
7117 return true;
7118 }
7119
7120 unsigned ArgNo = CB->getArgOperandNo(&U);
7121 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7122
7123 bool IsKnownNoCapture;
7124 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7125 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7126
7127 // If a call site argument use is nofree, we are fine.
7128 bool IsKnownNoFree;
7129 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7130 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7131
7132 if (!IsAssumedNoCapture ||
7133 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7134 !IsAssumedNoFree)) {
7135 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7136
7137 // Emit a missed remark if this is missed OpenMP globalization.
7138 auto Remark = [&](OptimizationRemarkMissed ORM) {
7139 return ORM
7140 << "Could not move globalized variable to the stack. "
7141 "Variable is potentially captured in call. Mark "
7142 "parameter as `__attribute__((noescape))` to override.";
7143 };
7144
7145 if (ValidUsesOnly &&
7146 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7147 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7148
7149 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7150 ValidUsesOnly = false;
7151 }
7152 return true;
7153 }
7154
7155 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7156 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7157 Follow = true;
7158 return true;
7159 }
7160 // Unknown user for which we can not track uses further (in a way that
7161 // makes sense).
7162 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7163 ValidUsesOnly = false;
7164 return true;
7165 };
7166 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7167 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7168 [&](const Use &OldU, const Use &NewU) {
7169 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7170 return !SI || StackIsAccessibleByOtherThreads ||
7171 AA::isAssumedThreadLocalObject(
7172 A, *SI->getPointerOperand(), *this);
7173 }))
7174 return false;
7175 return ValidUsesOnly;
7176 };
7177
7178 // The actual update starts here. We look at all allocations and depending on
7179 // their status perform the appropriate check(s).
7180 for (auto &It : AllocationInfos) {
7181 AllocationInfo &AI = *It.second;
7182 if (AI.Status == AllocationInfo::INVALID)
7183 continue;
7184
7185 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7186 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7187 if (!APAlign) {
7188 // Can't generate an alloca which respects the required alignment
7189 // on the allocation.
7190 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7191 << "\n");
7192 AI.Status = AllocationInfo::INVALID;
7194 continue;
7195 }
7196 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7197 !APAlign->isPowerOf2()) {
7198 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7199 << "\n");
7200 AI.Status = AllocationInfo::INVALID;
7202 continue;
7203 }
7204 }
7205
7206 std::optional<APInt> Size = getSize(A, *this, AI);
7207 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7208 MaxHeapToStackSize != -1) {
7209 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7210 LLVM_DEBUG({
7211 if (!Size)
7212 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7213 else
7214 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7215 << MaxHeapToStackSize << "\n";
7216 });
7217
7218 AI.Status = AllocationInfo::INVALID;
7220 continue;
7221 }
7222 }
7223
7224 switch (AI.Status) {
7225 case AllocationInfo::STACK_DUE_TO_USE:
7226 if (UsesCheck(AI))
7227 break;
7228 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7229 [[fallthrough]];
7230 case AllocationInfo::STACK_DUE_TO_FREE:
7231 if (FreeCheck(AI))
7232 break;
7233 AI.Status = AllocationInfo::INVALID;
7235 break;
7236 case AllocationInfo::INVALID:
7237 llvm_unreachable("Invalid allocations should never reach this point!");
7238 };
7239
7240 // Check if we still think we can move it into the entry block. If the
7241 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7242 // ignore the potential compilations associated with loops.
7243 bool IsGlobalizedLocal =
7244 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7245 if (AI.MoveAllocaIntoEntry &&
7246 (!Size.has_value() ||
7247 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7248 AI.MoveAllocaIntoEntry = false;
7249 }
7250
7251 return Changed;
7252}
7253} // namespace
7254
7255/// ----------------------- Privatizable Pointers ------------------------------
7256namespace {
7257struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7258 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7259 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7260
7261 ChangeStatus indicatePessimisticFixpoint() override {
7262 AAPrivatizablePtr::indicatePessimisticFixpoint();
7263 PrivatizableType = nullptr;
7264 return ChangeStatus::CHANGED;
7265 }
7266
7267 /// Identify the type we can chose for a private copy of the underlying
7268 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7269 /// none.
7270 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7271
7272 /// Return a privatizable type that encloses both T0 and T1.
7273 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7274 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7275 std::optional<Type *> T1) {
7276 if (!T0)
7277 return T1;
7278 if (!T1)
7279 return T0;
7280 if (T0 == T1)
7281 return T0;
7282 return nullptr;
7283 }
7284
7285 std::optional<Type *> getPrivatizableType() const override {
7286 return PrivatizableType;
7287 }
7288
7289 const std::string getAsStr(Attributor *A) const override {
7290 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7291 }
7292
7293protected:
7294 std::optional<Type *> PrivatizableType;
7295};
7296
7297// TODO: Do this for call site arguments (probably also other values) as well.
7298
7299struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7300 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7301 : AAPrivatizablePtrImpl(IRP, A) {}
7302
7303 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7304 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7305 // If this is a byval argument and we know all the call sites (so we can
7306 // rewrite them), there is no need to check them explicitly.
7307 bool UsedAssumedInformation = false;
7309 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7310 /* IgnoreSubsumingPositions */ true);
7311 if (!Attrs.empty() &&
7312 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7313 true, UsedAssumedInformation))
7314 return Attrs[0].getValueAsType();
7315
7316 std::optional<Type *> Ty;
7317 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7318
7319 // Make sure the associated call site argument has the same type at all call
7320 // sites and it is an allocation we know is safe to privatize, for now that
7321 // means we only allow alloca instructions.
7322 // TODO: We can additionally analyze the accesses in the callee to create
7323 // the type from that information instead. That is a little more
7324 // involved and will be done in a follow up patch.
7325 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7326 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7327 // Check if a coresponding argument was found or if it is one not
7328 // associated (which can happen for callback calls).
7329 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7330 return false;
7331
7332 // Check that all call sites agree on a type.
7333 auto *PrivCSArgAA =
7334 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7335 if (!PrivCSArgAA)
7336 return false;
7337 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7338
7339 LLVM_DEBUG({
7340 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7341 if (CSTy && *CSTy)
7342 (*CSTy)->print(dbgs());
7343 else if (CSTy)
7344 dbgs() << "<nullptr>";
7345 else
7346 dbgs() << "<none>";
7347 });
7348
7349 Ty = combineTypes(Ty, CSTy);
7350
7351 LLVM_DEBUG({
7352 dbgs() << " : New Type: ";
7353 if (Ty && *Ty)
7354 (*Ty)->print(dbgs());
7355 else if (Ty)
7356 dbgs() << "<nullptr>";
7357 else
7358 dbgs() << "<none>";
7359 dbgs() << "\n";
7360 });
7361
7362 return !Ty || *Ty;
7363 };
7364
7365 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7366 UsedAssumedInformation))
7367 return nullptr;
7368 return Ty;
7369 }
7370
7371 /// See AbstractAttribute::updateImpl(...).
7372 ChangeStatus updateImpl(Attributor &A) override {
7373 PrivatizableType = identifyPrivatizableType(A);
7374 if (!PrivatizableType)
7375 return ChangeStatus::UNCHANGED;
7376 if (!*PrivatizableType)
7377 return indicatePessimisticFixpoint();
7378
7379 // The dependence is optional so we don't give up once we give up on the
7380 // alignment.
7381 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7382 DepClassTy::OPTIONAL);
7383
7384 // Avoid arguments with padding for now.
7385 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7386 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7387 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7388 return indicatePessimisticFixpoint();
7389 }
7390
7391 // Collect the types that will replace the privatizable type in the function
7392 // signature.
7393 SmallVector<Type *, 16> ReplacementTypes;
7394 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7395
7396 // Verify callee and caller agree on how the promoted argument would be
7397 // passed.
7398 Function &Fn = *getIRPosition().getAnchorScope();
7399 const auto *TTI =
7400 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7401 if (!TTI) {
7402 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7403 << Fn.getName() << "\n");
7404 return indicatePessimisticFixpoint();
7405 }
7406
7407 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7408 CallBase *CB = ACS.getInstruction();
7409 return TTI->areTypesABICompatible(
7410 CB->getCaller(),
7412 ReplacementTypes);
7413 };
7414 bool UsedAssumedInformation = false;
7415 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7416 UsedAssumedInformation)) {
7417 LLVM_DEBUG(
7418 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7419 << Fn.getName() << "\n");
7420 return indicatePessimisticFixpoint();
7421 }
7422
7423 // Register a rewrite of the argument.
7424 Argument *Arg = getAssociatedArgument();
7425 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7426 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7427 return indicatePessimisticFixpoint();
7428 }
7429
7430 unsigned ArgNo = Arg->getArgNo();
7431
7432 // Helper to check if for the given call site the associated argument is
7433 // passed to a callback where the privatization would be different.
7434 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7435 SmallVector<const Use *, 4> CallbackUses;
7436 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7437 for (const Use *U : CallbackUses) {
7438 AbstractCallSite CBACS(U);
7439 assert(CBACS && CBACS.isCallbackCall());
7440 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7441 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7442
7443 LLVM_DEBUG({
7444 dbgs()
7445 << "[AAPrivatizablePtr] Argument " << *Arg
7446 << "check if can be privatized in the context of its parent ("
7447 << Arg->getParent()->getName()
7448 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7449 "callback ("
7450 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7451 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7452 << CBACS.getCallArgOperand(CBArg) << " vs "
7453 << CB.getArgOperand(ArgNo) << "\n"
7454 << "[AAPrivatizablePtr] " << CBArg << " : "
7455 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7456 });
7457
7458 if (CBArgNo != int(ArgNo))
7459 continue;
7460 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7461 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7462 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7463 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7464 if (!CBArgPrivTy)
7465 continue;
7466 if (*CBArgPrivTy == PrivatizableType)
7467 continue;
7468 }
7469
7470 LLVM_DEBUG({
7471 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7472 << " cannot be privatized in the context of its parent ("
7473 << Arg->getParent()->getName()
7474 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7475 "callback ("
7476 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7477 << ").\n[AAPrivatizablePtr] for which the argument "
7478 "privatization is not compatible.\n";
7479 });
7480 return false;
7481 }
7482 }
7483 return true;
7484 };
7485
7486 // Helper to check if for the given call site the associated argument is
7487 // passed to a direct call where the privatization would be different.
7488 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7489 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7490 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7491 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7492 "Expected a direct call operand for callback call operand");
7493
7494 Function *DCCallee =
7496 LLVM_DEBUG({
7497 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7498 << " check if be privatized in the context of its parent ("
7499 << Arg->getParent()->getName()
7500 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7501 "direct call of ("
7502 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7503 });
7504
7505 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7506 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7507 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7508 DepClassTy::REQUIRED);
7509 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7510 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7511 if (!DCArgPrivTy)
7512 return true;
7513 if (*DCArgPrivTy == PrivatizableType)
7514 return true;
7515 }
7516 }
7517
7518 LLVM_DEBUG({
7519 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7520 << " cannot be privatized in the context of its parent ("
7521 << Arg->getParent()->getName()
7522 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7523 "direct call of ("
7525 << ").\n[AAPrivatizablePtr] for which the argument "
7526 "privatization is not compatible.\n";
7527 });
7528 return false;
7529 };
7530
7531 // Helper to check if the associated argument is used at the given abstract
7532 // call site in a way that is incompatible with the privatization assumed
7533 // here.
7534 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7535 if (ACS.isDirectCall())
7536 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7537 if (ACS.isCallbackCall())
7538 return IsCompatiblePrivArgOfDirectCS(ACS);
7539 return false;
7540 };
7541
7542 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7543 UsedAssumedInformation))
7544 return indicatePessimisticFixpoint();
7545
7546 return ChangeStatus::UNCHANGED;
7547 }
7548
7549 /// Given a type to private \p PrivType, collect the constituates (which are
7550 /// used) in \p ReplacementTypes.
7551 static void
7552 identifyReplacementTypes(Type *PrivType,
7553 SmallVectorImpl<Type *> &ReplacementTypes) {
7554 // TODO: For now we expand the privatization type to the fullest which can
7555 // lead to dead arguments that need to be removed later.
7556 assert(PrivType && "Expected privatizable type!");
7557
7558 // Traverse the type, extract constituate types on the outermost level.
7559 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7560 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7561 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7562 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7563 ReplacementTypes.append(PrivArrayType->getNumElements(),
7564 PrivArrayType->getElementType());
7565 } else {
7566 ReplacementTypes.push_back(PrivType);
7567 }
7568 }
7569
7570 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7571 /// The values needed are taken from the arguments of \p F starting at
7572 /// position \p ArgNo.
7573 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7574 unsigned ArgNo, BasicBlock::iterator IP) {
7575 assert(PrivType && "Expected privatizable type!");
7576
7577 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7578 const DataLayout &DL = F.getDataLayout();
7579
7580 // Traverse the type, build GEPs and stores.
7581 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7582 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7583 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7584 Value *Ptr =
7585 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7586 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7587 }
7588 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7589 Type *PointeeTy = PrivArrayType->getElementType();
7590 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7591 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7592 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7593 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7594 }
7595 } else {
7596 new StoreInst(F.getArg(ArgNo), &Base, IP);
7597 }
7598 }
7599
7600 /// Extract values from \p Base according to the type \p PrivType at the
7601 /// call position \p ACS. The values are appended to \p ReplacementValues.
7602 void createReplacementValues(Align Alignment, Type *PrivType,
7603 AbstractCallSite ACS, Value *Base,
7604 SmallVectorImpl<Value *> &ReplacementValues) {
7605 assert(Base && "Expected base value!");
7606 assert(PrivType && "Expected privatizable type!");
7607 Instruction *IP = ACS.getInstruction();
7608
7609 IRBuilder<NoFolder> IRB(IP);
7610 const DataLayout &DL = IP->getDataLayout();
7611
7612 // Traverse the type, build GEPs and loads.
7613 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7614 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7615 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7616 Type *PointeeTy = PrivStructType->getElementType(u);
7617 Value *Ptr =
7618 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7619 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7620 L->setAlignment(Alignment);
7621 ReplacementValues.push_back(L);
7622 }
7623 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7624 Type *PointeeTy = PrivArrayType->getElementType();
7625 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7626 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7627 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7628 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7629 L->setAlignment(Alignment);
7630 ReplacementValues.push_back(L);
7631 }
7632 } else {
7633 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7634 L->setAlignment(Alignment);
7635 ReplacementValues.push_back(L);
7636 }
7637 }
7638
7639 /// See AbstractAttribute::manifest(...)
7640 ChangeStatus manifest(Attributor &A) override {
7641 if (!PrivatizableType)
7642 return ChangeStatus::UNCHANGED;
7643 assert(*PrivatizableType && "Expected privatizable type!");
7644
7645 // Collect all tail calls in the function as we cannot allow new allocas to
7646 // escape into tail recursion.
7647 // TODO: Be smarter about new allocas escaping into tail calls.
7649 bool UsedAssumedInformation = false;
7650 if (!A.checkForAllInstructions(
7651 [&](Instruction &I) {
7652 CallInst &CI = cast<CallInst>(I);
7653 if (CI.isTailCall())
7654 TailCalls.push_back(&CI);
7655 return true;
7656 },
7657 *this, {Instruction::Call}, UsedAssumedInformation))
7658 return ChangeStatus::UNCHANGED;
7659
7660 Argument *Arg = getAssociatedArgument();
7661 // Query AAAlign attribute for alignment of associated argument to
7662 // determine the best alignment of loads.
7663 const auto *AlignAA =
7664 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7665
7666 // Callback to repair the associated function. A new alloca is placed at the
7667 // beginning and initialized with the values passed through arguments. The
7668 // new alloca replaces the use of the old pointer argument.
7670 [=](const Attributor::ArgumentReplacementInfo &ARI,
7671 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7672 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7674 const DataLayout &DL = IP->getDataLayout();
7675 unsigned AS = DL.getAllocaAddrSpace();
7676 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7677 Arg->getName() + ".priv", IP);
7678 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7679 ArgIt->getArgNo(), IP);
7680
7681 if (AI->getType() != Arg->getType())
7682 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7683 AI, Arg->getType(), "", IP);
7684 Arg->replaceAllUsesWith(AI);
7685
7686 for (CallInst *CI : TailCalls)
7687 CI->setTailCall(false);
7688 };
7689
7690 // Callback to repair a call site of the associated function. The elements
7691 // of the privatizable type are loaded prior to the call and passed to the
7692 // new function version.
7694 [=](const Attributor::ArgumentReplacementInfo &ARI,
7695 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7696 // When no alignment is specified for the load instruction,
7697 // natural alignment is assumed.
7698 createReplacementValues(
7699 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7700 *PrivatizableType, ACS,
7701 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7702 NewArgOperands);
7703 };
7704
7705 // Collect the types that will replace the privatizable type in the function
7706 // signature.
7707 SmallVector<Type *, 16> ReplacementTypes;
7708 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7709
7710 // Register a rewrite of the argument.
7711 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7712 std::move(FnRepairCB),
7713 std::move(ACSRepairCB)))
7714 return ChangeStatus::CHANGED;
7715 return ChangeStatus::UNCHANGED;
7716 }
7717
7718 /// See AbstractAttribute::trackStatistics()
7719 void trackStatistics() const override {
7720 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7721 }
7722};
7723
7724struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7725 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7726 : AAPrivatizablePtrImpl(IRP, A) {}
7727
7728 /// See AbstractAttribute::initialize(...).
7729 void initialize(Attributor &A) override {
7730 // TODO: We can privatize more than arguments.
7731 indicatePessimisticFixpoint();
7732 }
7733
7734 ChangeStatus updateImpl(Attributor &A) override {
7735 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7736 "updateImpl will not be called");
7737 }
7738
7739 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7740 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7741 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7742 if (!Obj) {
7743 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7744 return nullptr;
7745 }
7746
7747 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7748 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7749 if (CI->isOne())
7750 return AI->getAllocatedType();
7751 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7752 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7753 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7754 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7755 return PrivArgAA->getPrivatizableType();
7756 }
7757
7758 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7759 "alloca nor privatizable argument: "
7760 << *Obj << "!\n");
7761 return nullptr;
7762 }
7763
7764 /// See AbstractAttribute::trackStatistics()
7765 void trackStatistics() const override {
7766 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7767 }
7768};
7769
7770struct AAPrivatizablePtrCallSiteArgument final
7771 : public AAPrivatizablePtrFloating {
7772 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7773 : AAPrivatizablePtrFloating(IRP, A) {}
7774
7775 /// See AbstractAttribute::initialize(...).
7776 void initialize(Attributor &A) override {
7777 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7778 indicateOptimisticFixpoint();
7779 }
7780
7781 /// See AbstractAttribute::updateImpl(...).
7782 ChangeStatus updateImpl(Attributor &A) override {
7783 PrivatizableType = identifyPrivatizableType(A);
7784 if (!PrivatizableType)
7785 return ChangeStatus::UNCHANGED;
7786 if (!*PrivatizableType)
7787 return indicatePessimisticFixpoint();
7788
7789 const IRPosition &IRP = getIRPosition();
7790 bool IsKnownNoCapture;
7791 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7792 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7793 if (!IsAssumedNoCapture) {
7794 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7795 return indicatePessimisticFixpoint();
7796 }
7797
7798 bool IsKnownNoAlias;
7800 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7801 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7802 return indicatePessimisticFixpoint();
7803 }
7804
7805 bool IsKnown;
7806 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7807 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7808 return indicatePessimisticFixpoint();
7809 }
7810
7811 return ChangeStatus::UNCHANGED;
7812 }
7813
7814 /// See AbstractAttribute::trackStatistics()
7815 void trackStatistics() const override {
7816 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7817 }
7818};
7819
7820struct AAPrivatizablePtrCallSiteReturned final
7821 : public AAPrivatizablePtrFloating {
7822 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7823 : AAPrivatizablePtrFloating(IRP, A) {}
7824
7825 /// See AbstractAttribute::initialize(...).
7826 void initialize(Attributor &A) override {
7827 // TODO: We can privatize more than arguments.
7828 indicatePessimisticFixpoint();
7829 }
7830
7831 /// See AbstractAttribute::trackStatistics()
7832 void trackStatistics() const override {
7833 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7834 }
7835};
7836
7837struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7838 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7839 : AAPrivatizablePtrFloating(IRP, A) {}
7840
7841 /// See AbstractAttribute::initialize(...).
7842 void initialize(Attributor &A) override {
7843 // TODO: We can privatize more than arguments.
7844 indicatePessimisticFixpoint();
7845 }
7846
7847 /// See AbstractAttribute::trackStatistics()
7848 void trackStatistics() const override {
7849 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7850 }
7851};
7852} // namespace
7853
7854/// -------------------- Memory Behavior Attributes ----------------------------
7855/// Includes read-none, read-only, and write-only.
7856/// ----------------------------------------------------------------------------
7857namespace {
7858struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7859 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7860 : AAMemoryBehavior(IRP, A) {}
7861
7862 /// See AbstractAttribute::initialize(...).
7863 void initialize(Attributor &A) override {
7864 intersectAssumedBits(BEST_STATE);
7865 getKnownStateFromValue(A, getIRPosition(), getState());
7866 AAMemoryBehavior::initialize(A);
7867 }
7868
7869 /// Return the memory behavior information encoded in the IR for \p IRP.
7870 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7871 BitIntegerState &State,
7872 bool IgnoreSubsumingPositions = false) {
7874 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7875 for (const Attribute &Attr : Attrs) {
7876 switch (Attr.getKindAsEnum()) {
7877 case Attribute::ReadNone:
7878 State.addKnownBits(NO_ACCESSES);
7879 break;
7880 case Attribute::ReadOnly:
7881 State.addKnownBits(NO_WRITES);
7882 break;
7883 case Attribute::WriteOnly:
7884 State.addKnownBits(NO_READS);
7885 break;
7886 default:
7887 llvm_unreachable("Unexpected attribute!");
7888 }
7889 }
7890
7891 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7892 if (!I->mayReadFromMemory())
7893 State.addKnownBits(NO_READS);
7894 if (!I->mayWriteToMemory())
7895 State.addKnownBits(NO_WRITES);
7896 }
7897 }
7898
7899 /// See AbstractAttribute::getDeducedAttributes(...).
7900 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7901 SmallVectorImpl<Attribute> &Attrs) const override {
7902 assert(Attrs.size() == 0);
7903 if (isAssumedReadNone())
7904 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7905 else if (isAssumedReadOnly())
7906 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7907 else if (isAssumedWriteOnly())
7908 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7909 assert(Attrs.size() <= 1);
7910 }
7911
7912 /// See AbstractAttribute::manifest(...).
7913 ChangeStatus manifest(Attributor &A) override {
7914 const IRPosition &IRP = getIRPosition();
7915
7916 if (A.hasAttr(IRP, Attribute::ReadNone,
7917 /* IgnoreSubsumingPositions */ true))
7918 return ChangeStatus::UNCHANGED;
7919
7920 // Check if we would improve the existing attributes first.
7921 SmallVector<Attribute, 4> DeducedAttrs;
7922 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7923 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7924 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7925 /* IgnoreSubsumingPositions */ true);
7926 }))
7927 return ChangeStatus::UNCHANGED;
7928
7929 // Clear existing attributes.
7930 A.removeAttrs(IRP, AttrKinds);
7931 // Clear conflicting writable attribute.
7932 if (isAssumedReadOnly())
7933 A.removeAttrs(IRP, Attribute::Writable);
7934
7935 // Use the generic manifest method.
7936 return IRAttribute::manifest(A);
7937 }
7938
7939 /// See AbstractState::getAsStr().
7940 const std::string getAsStr(Attributor *A) const override {
7941 if (isAssumedReadNone())
7942 return "readnone";
7943 if (isAssumedReadOnly())
7944 return "readonly";
7945 if (isAssumedWriteOnly())
7946 return "writeonly";
7947 return "may-read/write";
7948 }
7949
7950 /// The set of IR attributes AAMemoryBehavior deals with.
7951 static const Attribute::AttrKind AttrKinds[3];
7952};
7953
7954const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7955 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7956
7957/// Memory behavior attribute for a floating value.
7958struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7959 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7960 : AAMemoryBehaviorImpl(IRP, A) {}
7961
7962 /// See AbstractAttribute::updateImpl(...).
7963 ChangeStatus updateImpl(Attributor &A) override;
7964
7965 /// See AbstractAttribute::trackStatistics()
7966 void trackStatistics() const override {
7967 if (isAssumedReadNone())
7969 else if (isAssumedReadOnly())
7971 else if (isAssumedWriteOnly())
7973 }
7974
7975private:
7976 /// Return true if users of \p UserI might access the underlying
7977 /// variable/location described by \p U and should therefore be analyzed.
7978 bool followUsersOfUseIn(Attributor &A, const Use &U,
7979 const Instruction *UserI);
7980
7981 /// Update the state according to the effect of use \p U in \p UserI.
7982 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7983};
7984
7985/// Memory behavior attribute for function argument.
7986struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7987 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
7988 : AAMemoryBehaviorFloating(IRP, A) {}
7989
7990 /// See AbstractAttribute::initialize(...).
7991 void initialize(Attributor &A) override {
7992 intersectAssumedBits(BEST_STATE);
7993 const IRPosition &IRP = getIRPosition();
7994 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7995 // can query it when we use has/getAttr. That would allow us to reuse the
7996 // initialize of the base class here.
7997 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
7998 /* IgnoreSubsumingPositions */ true);
7999 getKnownStateFromValue(A, IRP, getState(),
8000 /* IgnoreSubsumingPositions */ HasByVal);
8001 }
8002
8003 ChangeStatus manifest(Attributor &A) override {
8004 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8005 if (!getAssociatedValue().getType()->isPointerTy())
8006 return ChangeStatus::UNCHANGED;
8007
8008 // TODO: From readattrs.ll: "inalloca parameters are always
8009 // considered written"
8010 if (A.hasAttr(getIRPosition(),
8011 {Attribute::InAlloca, Attribute::Preallocated})) {
8012 removeKnownBits(NO_WRITES);
8013 removeAssumedBits(NO_WRITES);
8014 }
8015 A.removeAttrs(getIRPosition(), AttrKinds);
8016 return AAMemoryBehaviorFloating::manifest(A);
8017 }
8018
8019 /// See AbstractAttribute::trackStatistics()
8020 void trackStatistics() const override {
8021 if (isAssumedReadNone())
8022 STATS_DECLTRACK_ARG_ATTR(readnone)
8023 else if (isAssumedReadOnly())
8024 STATS_DECLTRACK_ARG_ATTR(readonly)
8025 else if (isAssumedWriteOnly())
8026 STATS_DECLTRACK_ARG_ATTR(writeonly)
8027 }
8028};
8029
8030struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8031 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8032 : AAMemoryBehaviorArgument(IRP, A) {}
8033
8034 /// See AbstractAttribute::initialize(...).
8035 void initialize(Attributor &A) override {
8036 // If we don't have an associated attribute this is either a variadic call
8037 // or an indirect call, either way, nothing to do here.
8038 Argument *Arg = getAssociatedArgument();
8039 if (!Arg) {
8040 indicatePessimisticFixpoint();
8041 return;
8042 }
8043 if (Arg->hasByValAttr()) {
8044 addKnownBits(NO_WRITES);
8045 removeKnownBits(NO_READS);
8046 removeAssumedBits(NO_READS);
8047 }
8048 AAMemoryBehaviorArgument::initialize(A);
8049 if (getAssociatedFunction()->isDeclaration())
8050 indicatePessimisticFixpoint();
8051 }
8052
8053 /// See AbstractAttribute::updateImpl(...).
8054 ChangeStatus updateImpl(Attributor &A) override {
8055 // TODO: Once we have call site specific value information we can provide
8056 // call site specific liveness liveness information and then it makes
8057 // sense to specialize attributes for call sites arguments instead of
8058 // redirecting requests to the callee argument.
8059 Argument *Arg = getAssociatedArgument();
8060 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8061 auto *ArgAA =
8062 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8063 if (!ArgAA)
8064 return indicatePessimisticFixpoint();
8065 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8066 }
8067
8068 /// See AbstractAttribute::trackStatistics()
8069 void trackStatistics() const override {
8070 if (isAssumedReadNone())
8072 else if (isAssumedReadOnly())
8074 else if (isAssumedWriteOnly())
8076 }
8077};
8078
8079/// Memory behavior attribute for a call site return position.
8080struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8081 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8082 : AAMemoryBehaviorFloating(IRP, A) {}
8083
8084 /// See AbstractAttribute::initialize(...).
8085 void initialize(Attributor &A) override {
8086 AAMemoryBehaviorImpl::initialize(A);
8087 }
8088 /// See AbstractAttribute::manifest(...).
8089 ChangeStatus manifest(Attributor &A) override {
8090 // We do not annotate returned values.
8091 return ChangeStatus::UNCHANGED;
8092 }
8093
8094 /// See AbstractAttribute::trackStatistics()
8095 void trackStatistics() const override {}
8096};
8097
8098/// An AA to represent the memory behavior function attributes.
8099struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8100 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8101 : AAMemoryBehaviorImpl(IRP, A) {}
8102
8103 /// See AbstractAttribute::updateImpl(Attributor &A).
8104 ChangeStatus updateImpl(Attributor &A) override;
8105
8106 /// See AbstractAttribute::manifest(...).
8107 ChangeStatus manifest(Attributor &A) override {
8108 // TODO: It would be better to merge this with AAMemoryLocation, so that
8109 // we could determine read/write per location. This would also have the
8110 // benefit of only one place trying to manifest the memory attribute.
8111 Function &F = cast<Function>(getAnchorValue());
8113 if (isAssumedReadNone())
8114 ME = MemoryEffects::none();
8115 else if (isAssumedReadOnly())
8117 else if (isAssumedWriteOnly())
8119
8120 A.removeAttrs(getIRPosition(), AttrKinds);
8121 // Clear conflicting writable attribute.
8122 if (ME.onlyReadsMemory())
8123 for (Argument &Arg : F.args())
8124 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8125 return A.manifestAttrs(getIRPosition(),
8126 Attribute::getWithMemoryEffects(F.getContext(), ME));
8127 }
8128
8129 /// See AbstractAttribute::trackStatistics()
8130 void trackStatistics() const override {
8131 if (isAssumedReadNone())
8132 STATS_DECLTRACK_FN_ATTR(readnone)
8133 else if (isAssumedReadOnly())
8134 STATS_DECLTRACK_FN_ATTR(readonly)
8135 else if (isAssumedWriteOnly())
8136 STATS_DECLTRACK_FN_ATTR(writeonly)
8137 }
8138};
8139
8140/// AAMemoryBehavior attribute for call sites.
8141struct AAMemoryBehaviorCallSite final
8142 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8143 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8144 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8145
8146 /// See AbstractAttribute::manifest(...).
8147 ChangeStatus manifest(Attributor &A) override {
8148 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8149 CallBase &CB = cast<CallBase>(getAnchorValue());
8151 if (isAssumedReadNone())
8152 ME = MemoryEffects::none();
8153 else if (isAssumedReadOnly())
8155 else if (isAssumedWriteOnly())
8157
8158 A.removeAttrs(getIRPosition(), AttrKinds);
8159 // Clear conflicting writable attribute.
8160 if (ME.onlyReadsMemory())
8161 for (Use &U : CB.args())
8162 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8163 Attribute::Writable);
8164 return A.manifestAttrs(
8165 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8166 }
8167
8168 /// See AbstractAttribute::trackStatistics()
8169 void trackStatistics() const override {
8170 if (isAssumedReadNone())
8171 STATS_DECLTRACK_CS_ATTR(readnone)
8172 else if (isAssumedReadOnly())
8173 STATS_DECLTRACK_CS_ATTR(readonly)
8174 else if (isAssumedWriteOnly())
8175 STATS_DECLTRACK_CS_ATTR(writeonly)
8176 }
8177};
8178
8179ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8180
8181 // The current assumed state used to determine a change.
8182 auto AssumedState = getAssumed();
8183
8184 auto CheckRWInst = [&](Instruction &I) {
8185 // If the instruction has an own memory behavior state, use it to restrict
8186 // the local state. No further analysis is required as the other memory
8187 // state is as optimistic as it gets.
8188 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8189 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8191 if (MemBehaviorAA) {
8192 intersectAssumedBits(MemBehaviorAA->getAssumed());
8193 return !isAtFixpoint();
8194 }
8195 }
8196
8197 // Remove access kind modifiers if necessary.
8198 if (I.mayReadFromMemory())
8199 removeAssumedBits(NO_READS);
8200 if (I.mayWriteToMemory())
8201 removeAssumedBits(NO_WRITES);
8202 return !isAtFixpoint();
8203 };
8204
8205 bool UsedAssumedInformation = false;
8206 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8207 UsedAssumedInformation))
8208 return indicatePessimisticFixpoint();
8209
8210 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8212}
8213
8214ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8215
8216 const IRPosition &IRP = getIRPosition();
8217 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8218 AAMemoryBehavior::StateType &S = getState();
8219
8220 // First, check the function scope. We take the known information and we avoid
8221 // work if the assumed information implies the current assumed information for
8222 // this attribute. This is a valid for all but byval arguments.
8223 Argument *Arg = IRP.getAssociatedArgument();
8224 AAMemoryBehavior::base_t FnMemAssumedState =
8226 if (!Arg || !Arg->hasByValAttr()) {
8227 const auto *FnMemAA =
8228 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8229 if (FnMemAA) {
8230 FnMemAssumedState = FnMemAA->getAssumed();
8231 S.addKnownBits(FnMemAA->getKnown());
8232 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8234 }
8235 }
8236
8237 // The current assumed state used to determine a change.
8238 auto AssumedState = S.getAssumed();
8239
8240 // Make sure the value is not captured (except through "return"), if
8241 // it is, any information derived would be irrelevant anyway as we cannot
8242 // check the potential aliases introduced by the capture. However, no need
8243 // to fall back to anythign less optimistic than the function state.
8244 bool IsKnownNoCapture;
8245 const AANoCapture *ArgNoCaptureAA = nullptr;
8246 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8247 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8248 &ArgNoCaptureAA);
8249
8250 if (!IsAssumedNoCapture &&
8251 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8252 S.intersectAssumedBits(FnMemAssumedState);
8253 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8255 }
8256
8257 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8258 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8259 Instruction *UserI = cast<Instruction>(U.getUser());
8260 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8261 << " \n");
8262
8263 // Droppable users, e.g., llvm::assume does not actually perform any action.
8264 if (UserI->isDroppable())
8265 return true;
8266
8267 // Check if the users of UserI should also be visited.
8268 Follow = followUsersOfUseIn(A, U, UserI);
8269
8270 // If UserI might touch memory we analyze the use in detail.
8271 if (UserI->mayReadOrWriteMemory())
8272 analyzeUseIn(A, U, UserI);
8273
8274 return !isAtFixpoint();
8275 };
8276
8277 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8278 return indicatePessimisticFixpoint();
8279
8280 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8282}
8283
8284bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8285 const Instruction *UserI) {
8286 // The loaded value is unrelated to the pointer argument, no need to
8287 // follow the users of the load.
8288 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8289 return false;
8290
8291 // By default we follow all uses assuming UserI might leak information on U,
8292 // we have special handling for call sites operands though.
8293 const auto *CB = dyn_cast<CallBase>(UserI);
8294 if (!CB || !CB->isArgOperand(&U))
8295 return true;
8296
8297 // If the use is a call argument known not to be captured, the users of
8298 // the call do not need to be visited because they have to be unrelated to
8299 // the input. Note that this check is not trivial even though we disallow
8300 // general capturing of the underlying argument. The reason is that the
8301 // call might the argument "through return", which we allow and for which we
8302 // need to check call users.
8303 if (U.get()->getType()->isPointerTy()) {
8304 unsigned ArgNo = CB->getArgOperandNo(&U);
8305 bool IsKnownNoCapture;
8307 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8308 DepClassTy::OPTIONAL, IsKnownNoCapture);
8309 }
8310
8311 return true;
8312}
8313
8314void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8315 const Instruction *UserI) {
8316 assert(UserI->mayReadOrWriteMemory());
8317
8318 switch (UserI->getOpcode()) {
8319 default:
8320 // TODO: Handle all atomics and other side-effect operations we know of.
8321 break;
8322 case Instruction::Load:
8323 // Loads cause the NO_READS property to disappear.
8324 removeAssumedBits(NO_READS);
8325 return;
8326
8327 case Instruction::Store:
8328 // Stores cause the NO_WRITES property to disappear if the use is the
8329 // pointer operand. Note that while capturing was taken care of somewhere
8330 // else we need to deal with stores of the value that is not looked through.
8331 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8332 removeAssumedBits(NO_WRITES);
8333 else
8334 indicatePessimisticFixpoint();
8335 return;
8336
8337 case Instruction::Call:
8338 case Instruction::CallBr:
8339 case Instruction::Invoke: {
8340 // For call sites we look at the argument memory behavior attribute (this
8341 // could be recursive!) in order to restrict our own state.
8342 const auto *CB = cast<CallBase>(UserI);
8343
8344 // Give up on operand bundles.
8345 if (CB->isBundleOperand(&U)) {
8346 indicatePessimisticFixpoint();
8347 return;
8348 }
8349
8350 // Calling a function does read the function pointer, maybe write it if the
8351 // function is self-modifying.
8352 if (CB->isCallee(&U)) {
8353 removeAssumedBits(NO_READS);
8354 break;
8355 }
8356
8357 // Adjust the possible access behavior based on the information on the
8358 // argument.
8359 IRPosition Pos;
8360 if (U.get()->getType()->isPointerTy())
8362 else
8364 const auto *MemBehaviorAA =
8365 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8366 if (!MemBehaviorAA)
8367 break;
8368 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8369 // and at least "known".
8370 intersectAssumedBits(MemBehaviorAA->getAssumed());
8371 return;
8372 }
8373 };
8374
8375 // Generally, look at the "may-properties" and adjust the assumed state if we
8376 // did not trigger special handling before.
8377 if (UserI->mayReadFromMemory())
8378 removeAssumedBits(NO_READS);
8379 if (UserI->mayWriteToMemory())
8380 removeAssumedBits(NO_WRITES);
8381}
8382} // namespace
8383
8384/// -------------------- Memory Locations Attributes ---------------------------
8385/// Includes read-none, argmemonly, inaccessiblememonly,
8386/// inaccessiblememorargmemonly
8387/// ----------------------------------------------------------------------------
8388
8391 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8392 return "all memory";
8394 return "no memory";
8395 std::string S = "memory:";
8396 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8397 S += "stack,";
8398 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8399 S += "constant,";
8401 S += "internal global,";
8403 S += "external global,";
8404 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8405 S += "argument,";
8407 S += "inaccessible,";
8408 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8409 S += "malloced,";
8410 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8411 S += "unknown,";
8412 S.pop_back();
8413 return S;
8414}
8415
8416namespace {
8417struct AAMemoryLocationImpl : public AAMemoryLocation {
8418
8419 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8420 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8421 AccessKind2Accesses.fill(nullptr);
8422 }
8423
8424 ~AAMemoryLocationImpl() override {
8425 // The AccessSets are allocated via a BumpPtrAllocator, we call
8426 // the destructor manually.
8427 for (AccessSet *AS : AccessKind2Accesses)
8428 if (AS)
8429 AS->~AccessSet();
8430 }
8431
8432 /// See AbstractAttribute::initialize(...).
8433 void initialize(Attributor &A) override {
8434 intersectAssumedBits(BEST_STATE);
8435 getKnownStateFromValue(A, getIRPosition(), getState());
8436 AAMemoryLocation::initialize(A);
8437 }
8438
8439 /// Return the memory behavior information encoded in the IR for \p IRP.
8440 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8441 BitIntegerState &State,
8442 bool IgnoreSubsumingPositions = false) {
8443 // For internal functions we ignore `argmemonly` and
8444 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8445 // constant propagation. It is unclear if this is the best way but it is
8446 // unlikely this will cause real performance problems. If we are deriving
8447 // attributes for the anchor function we even remove the attribute in
8448 // addition to ignoring it.
8449 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8450 // MemoryEffects::Other as a possible location.
8451 bool UseArgMemOnly = true;
8452 Function *AnchorFn = IRP.getAnchorScope();
8453 if (AnchorFn && A.isRunOn(*AnchorFn))
8454 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8455
8457 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8458 for (const Attribute &Attr : Attrs) {
8459 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8460 MemoryEffects ME = Attr.getMemoryEffects();
8461 if (ME.doesNotAccessMemory()) {
8462 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8463 continue;
8464 }
8465 if (ME.onlyAccessesInaccessibleMem()) {
8466 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8467 continue;
8468 }
8469 if (ME.onlyAccessesArgPointees()) {
8470 if (UseArgMemOnly)
8471 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8472 else {
8473 // Remove location information, only keep read/write info.
8474 ME = MemoryEffects(ME.getModRef());
8475 A.manifestAttrs(IRP,
8476 Attribute::getWithMemoryEffects(
8477 IRP.getAnchorValue().getContext(), ME),
8478 /*ForceReplace*/ true);
8479 }
8480 continue;
8481 }
8483 if (UseArgMemOnly)
8484 State.addKnownBits(inverseLocation(
8485 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8486 else {
8487 // Remove location information, only keep read/write info.
8488 ME = MemoryEffects(ME.getModRef());
8489 A.manifestAttrs(IRP,
8490 Attribute::getWithMemoryEffects(
8491 IRP.getAnchorValue().getContext(), ME),
8492 /*ForceReplace*/ true);
8493 }
8494 continue;
8495 }
8496 }
8497 }
8498
8499 /// See AbstractAttribute::getDeducedAttributes(...).
8500 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8501 SmallVectorImpl<Attribute> &Attrs) const override {
8502 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8503 assert(Attrs.size() == 0);
8504 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8505 if (isAssumedReadNone())
8506 Attrs.push_back(
8507 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8508 else if (isAssumedInaccessibleMemOnly())
8509 Attrs.push_back(Attribute::getWithMemoryEffects(
8511 else if (isAssumedArgMemOnly())
8512 Attrs.push_back(
8513 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8514 else if (isAssumedInaccessibleOrArgMemOnly())
8515 Attrs.push_back(Attribute::getWithMemoryEffects(
8517 }
8518 assert(Attrs.size() <= 1);
8519 }
8520
8521 /// See AbstractAttribute::manifest(...).
8522 ChangeStatus manifest(Attributor &A) override {
8523 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8524 // provide per-location modref information here.
8525 const IRPosition &IRP = getIRPosition();
8526
8527 SmallVector<Attribute, 1> DeducedAttrs;
8528 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8529 if (DeducedAttrs.size() != 1)
8530 return ChangeStatus::UNCHANGED;
8531 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8532
8533 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8534 IRP.getAnchorValue().getContext(), ME));
8535 }
8536
8537 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8538 bool checkForAllAccessesToMemoryKind(
8539 function_ref<bool(const Instruction *, const Value *, AccessKind,
8540 MemoryLocationsKind)>
8541 Pred,
8542 MemoryLocationsKind RequestedMLK) const override {
8543 if (!isValidState())
8544 return false;
8545
8546 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8547 if (AssumedMLK == NO_LOCATIONS)
8548 return true;
8549
8550 unsigned Idx = 0;
8551 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8552 CurMLK *= 2, ++Idx) {
8553 if (CurMLK & RequestedMLK)
8554 continue;
8555
8556 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8557 for (const AccessInfo &AI : *Accesses)
8558 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8559 return false;
8560 }
8561
8562 return true;
8563 }
8564
8565 ChangeStatus indicatePessimisticFixpoint() override {
8566 // If we give up and indicate a pessimistic fixpoint this instruction will
8567 // become an access for all potential access kinds:
8568 // TODO: Add pointers for argmemonly and globals to improve the results of
8569 // checkForAllAccessesToMemoryKind.
8570 bool Changed = false;
8571 MemoryLocationsKind KnownMLK = getKnown();
8572 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8573 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8574 if (!(CurMLK & KnownMLK))
8575 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8576 getAccessKindFromInst(I));
8577 return AAMemoryLocation::indicatePessimisticFixpoint();
8578 }
8579
8580protected:
8581 /// Helper struct to tie together an instruction that has a read or write
8582 /// effect with the pointer it accesses (if any).
8583 struct AccessInfo {
8584
8585 /// The instruction that caused the access.
8586 const Instruction *I;
8587
8588 /// The base pointer that is accessed, or null if unknown.
8589 const Value *Ptr;
8590
8591 /// The kind of access (read/write/read+write).
8593
8594 bool operator==(const AccessInfo &RHS) const {
8595 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8596 }
8597 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8598 if (LHS.I != RHS.I)
8599 return LHS.I < RHS.I;
8600 if (LHS.Ptr != RHS.Ptr)
8601 return LHS.Ptr < RHS.Ptr;
8602 if (LHS.Kind != RHS.Kind)
8603 return LHS.Kind < RHS.Kind;
8604 return false;
8605 }
8606 };
8607
8608 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8609 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8610 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8611 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8612 AccessKind2Accesses;
8613
8614 /// Categorize the pointer arguments of CB that might access memory in
8615 /// AccessedLoc and update the state and access map accordingly.
8616 void
8617 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8618 AAMemoryLocation::StateType &AccessedLocs,
8619 bool &Changed);
8620
8621 /// Return the kind(s) of location that may be accessed by \p V.
8623 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8624
8625 /// Return the access kind as determined by \p I.
8626 AccessKind getAccessKindFromInst(const Instruction *I) {
8627 AccessKind AK = READ_WRITE;
8628 if (I) {
8629 AK = I->mayReadFromMemory() ? READ : NONE;
8630 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8631 }
8632 return AK;
8633 }
8634
8635 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8636 /// an access of kind \p AK to a \p MLK memory location with the access
8637 /// pointer \p Ptr.
8638 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8639 MemoryLocationsKind MLK, const Instruction *I,
8640 const Value *Ptr, bool &Changed,
8641 AccessKind AK = READ_WRITE) {
8642
8643 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8644 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8645 if (!Accesses)
8646 Accesses = new (Allocator) AccessSet();
8647 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8648 if (MLK == NO_UNKOWN_MEM)
8649 MLK = NO_LOCATIONS;
8650 State.removeAssumedBits(MLK);
8651 }
8652
8653 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8654 /// arguments, and update the state and access map accordingly.
8655 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8656 AAMemoryLocation::StateType &State, bool &Changed,
8657 unsigned AccessAS = 0);
8658
8659 /// Used to allocate access sets.
8661};
8662
8663void AAMemoryLocationImpl::categorizePtrValue(
8664 Attributor &A, const Instruction &I, const Value &Ptr,
8665 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8666 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8667 << Ptr << " ["
8668 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8669
8670 auto Pred = [&](Value &Obj) {
8671 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8672 // TODO: recognize the TBAA used for constant accesses.
8673 MemoryLocationsKind MLK = NO_LOCATIONS;
8674
8675 // Filter accesses to constant (GPU) memory if we have an AS at the access
8676 // site or the object is known to actually have the associated AS.
8677 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8678 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8679 isIdentifiedObject(&Obj))) &&
8680 AA::isGPU(*I.getModule()))
8681 return true;
8682
8683 if (isa<UndefValue>(&Obj))
8684 return true;
8685 if (isa<Argument>(&Obj)) {
8686 // TODO: For now we do not treat byval arguments as local copies performed
8687 // on the call edge, though, we should. To make that happen we need to
8688 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8689 // would also allow us to mark functions only accessing byval arguments as
8690 // readnone again, arguably their accesses have no effect outside of the
8691 // function, like accesses to allocas.
8692 MLK = NO_ARGUMENT_MEM;
8693 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8694 // Reading constant memory is not treated as a read "effect" by the
8695 // function attr pass so we won't neither. Constants defined by TBAA are
8696 // similar. (We know we do not write it because it is constant.)
8697 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8698 if (GVar->isConstant())
8699 return true;
8700
8701 if (GV->hasLocalLinkage())
8702 MLK = NO_GLOBAL_INTERNAL_MEM;
8703 else
8704 MLK = NO_GLOBAL_EXTERNAL_MEM;
8705 } else if (isa<ConstantPointerNull>(&Obj) &&
8706 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8707 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8708 return true;
8709 } else if (isa<AllocaInst>(&Obj)) {
8710 MLK = NO_LOCAL_MEM;
8711 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8712 bool IsKnownNoAlias;
8715 IsKnownNoAlias))
8716 MLK = NO_MALLOCED_MEM;
8717 else
8718 MLK = NO_UNKOWN_MEM;
8719 } else {
8720 MLK = NO_UNKOWN_MEM;
8721 }
8722
8723 assert(MLK != NO_LOCATIONS && "No location specified!");
8724 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8725 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8726 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8727 getAccessKindFromInst(&I));
8728
8729 return true;
8730 };
8731
8732 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8734 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8735 LLVM_DEBUG(
8736 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8737 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8738 getAccessKindFromInst(&I));
8739 return;
8740 }
8741
8742 LLVM_DEBUG(
8743 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8744 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8745}
8746
8747void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8748 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8749 bool &Changed) {
8750 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8751
8752 // Skip non-pointer arguments.
8753 const Value *ArgOp = CB.getArgOperand(ArgNo);
8754 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8755 continue;
8756
8757 // Skip readnone arguments.
8758 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8759 const auto *ArgOpMemLocationAA =
8760 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8761
8762 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8763 continue;
8764
8765 // Categorize potentially accessed pointer arguments as if there was an
8766 // access instruction with them as pointer.
8767 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8768 }
8769}
8770
8772AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8773 bool &Changed) {
8774 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8775 << I << "\n");
8776
8777 AAMemoryLocation::StateType AccessedLocs;
8778 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8779
8780 if (auto *CB = dyn_cast<CallBase>(&I)) {
8781
8782 // First check if we assume any memory is access is visible.
8783 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8785 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8786 << " [" << CBMemLocationAA << "]\n");
8787 if (!CBMemLocationAA) {
8788 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8789 Changed, getAccessKindFromInst(&I));
8790 return NO_UNKOWN_MEM;
8791 }
8792
8793 if (CBMemLocationAA->isAssumedReadNone())
8794 return NO_LOCATIONS;
8795
8796 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8797 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8798 Changed, getAccessKindFromInst(&I));
8799 return AccessedLocs.getAssumed();
8800 }
8801
8802 uint32_t CBAssumedNotAccessedLocs =
8803 CBMemLocationAA->getAssumedNotAccessedLocation();
8804
8805 // Set the argmemonly and global bit as we handle them separately below.
8806 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8807 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8808
8809 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8810 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8811 continue;
8812 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8813 getAccessKindFromInst(&I));
8814 }
8815
8816 // Now handle global memory if it might be accessed. This is slightly tricky
8817 // as NO_GLOBAL_MEM has multiple bits set.
8818 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8819 if (HasGlobalAccesses) {
8820 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8821 AccessKind Kind, MemoryLocationsKind MLK) {
8822 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8823 getAccessKindFromInst(&I));
8824 return true;
8825 };
8826 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8827 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8828 return AccessedLocs.getWorstState();
8829 }
8830
8831 LLVM_DEBUG(
8832 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8833 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8834
8835 // Now handle argument memory if it might be accessed.
8836 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8837 if (HasArgAccesses)
8838 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8839
8840 LLVM_DEBUG(
8841 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8842 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8843
8844 return AccessedLocs.getAssumed();
8845 }
8846
8847 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8848 LLVM_DEBUG(
8849 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8850 << I << " [" << *Ptr << "]\n");
8851 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8852 Ptr->getType()->getPointerAddressSpace());
8853 return AccessedLocs.getAssumed();
8854 }
8855
8856 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8857 << I << "\n");
8858 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8859 getAccessKindFromInst(&I));
8860 return AccessedLocs.getAssumed();
8861}
8862
8863/// An AA to represent the memory behavior function attributes.
8864struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8865 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8866 : AAMemoryLocationImpl(IRP, A) {}
8867
8868 /// See AbstractAttribute::updateImpl(Attributor &A).
8869 ChangeStatus updateImpl(Attributor &A) override {
8870
8871 const auto *MemBehaviorAA =
8872 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8873 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8874 if (MemBehaviorAA->isKnownReadNone())
8875 return indicateOptimisticFixpoint();
8877 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8878 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8879 return ChangeStatus::UNCHANGED;
8880 }
8881
8882 // The current assumed state used to determine a change.
8883 auto AssumedState = getAssumed();
8884 bool Changed = false;
8885
8886 auto CheckRWInst = [&](Instruction &I) {
8887 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8888 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8889 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8890 removeAssumedBits(inverseLocation(MLK, false, false));
8891 // Stop once only the valid bit set in the *not assumed location*, thus
8892 // once we don't actually exclude any memory locations in the state.
8893 return getAssumedNotAccessedLocation() != VALID_STATE;
8894 };
8895
8896 bool UsedAssumedInformation = false;
8897 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8898 UsedAssumedInformation))
8899 return indicatePessimisticFixpoint();
8900
8901 Changed |= AssumedState != getAssumed();
8902 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8903 }
8904
8905 /// See AbstractAttribute::trackStatistics()
8906 void trackStatistics() const override {
8907 if (isAssumedReadNone())
8908 STATS_DECLTRACK_FN_ATTR(readnone)
8909 else if (isAssumedArgMemOnly())
8910 STATS_DECLTRACK_FN_ATTR(argmemonly)
8911 else if (isAssumedInaccessibleMemOnly())
8912 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8913 else if (isAssumedInaccessibleOrArgMemOnly())
8914 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8915 }
8916};
8917
8918/// AAMemoryLocation attribute for call sites.
8919struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8920 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8921 : AAMemoryLocationImpl(IRP, A) {}
8922
8923 /// See AbstractAttribute::updateImpl(...).
8924 ChangeStatus updateImpl(Attributor &A) override {
8925 // TODO: Once we have call site specific value information we can provide
8926 // call site specific liveness liveness information and then it makes
8927 // sense to specialize attributes for call sites arguments instead of
8928 // redirecting requests to the callee argument.
8929 Function *F = getAssociatedFunction();
8930 const IRPosition &FnPos = IRPosition::function(*F);
8931 auto *FnAA =
8932 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8933 if (!FnAA)
8934 return indicatePessimisticFixpoint();
8935 bool Changed = false;
8936 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8937 AccessKind Kind, MemoryLocationsKind MLK) {
8938 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8939 getAccessKindFromInst(I));
8940 return true;
8941 };
8942 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8943 return indicatePessimisticFixpoint();
8944 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8945 }
8946
8947 /// See AbstractAttribute::trackStatistics()
8948 void trackStatistics() const override {
8949 if (isAssumedReadNone())
8950 STATS_DECLTRACK_CS_ATTR(readnone)
8951 }
8952};
8953} // namespace
8954
8955/// ------------------ denormal-fp-math Attribute -------------------------
8956
8957namespace {
8958struct AADenormalFPMathImpl : public AADenormalFPMath {
8959 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8960 : AADenormalFPMath(IRP, A) {}
8961
8962 const std::string getAsStr(Attributor *A) const override {
8963 std::string Str("AADenormalFPMath[");
8964 raw_string_ostream OS(Str);
8965
8966 DenormalState Known = getKnown();
8967 if (Known.Mode.isValid())
8968 OS << "denormal-fp-math=" << Known.Mode;
8969 else
8970 OS << "invalid";
8971
8972 if (Known.ModeF32.isValid())
8973 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8974 OS << ']';
8975 return Str;
8976 }
8977};
8978
8979struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8980 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8981 : AADenormalFPMathImpl(IRP, A) {}
8982
8983 void initialize(Attributor &A) override {
8984 const Function *F = getAnchorScope();
8985 DenormalMode Mode = F->getDenormalModeRaw();
8986 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8987
8988 // TODO: Handling this here prevents handling the case where a callee has a
8989 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8990 // a function with a fully fixed mode.
8991 if (ModeF32 == DenormalMode::getInvalid())
8992 ModeF32 = Mode;
8993 Known = DenormalState{Mode, ModeF32};
8994 if (isModeFixed())
8995 indicateFixpoint();
8996 }
8997
8998 ChangeStatus updateImpl(Attributor &A) override {
8999 ChangeStatus Change = ChangeStatus::UNCHANGED;
9000
9001 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9002 Function *Caller = CS.getInstruction()->getFunction();
9003 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9004 << "->" << getAssociatedFunction()->getName() << '\n');
9005
9006 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9007 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9008 if (!CallerInfo)
9009 return false;
9010
9011 Change = Change | clampStateAndIndicateChange(this->getState(),
9012 CallerInfo->getState());
9013 return true;
9014 };
9015
9016 bool AllCallSitesKnown = true;
9017 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9018 return indicatePessimisticFixpoint();
9019
9020 if (Change == ChangeStatus::CHANGED && isModeFixed())
9021 indicateFixpoint();
9022 return Change;
9023 }
9024
9025 ChangeStatus manifest(Attributor &A) override {
9026 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9027
9028 SmallVector<Attribute, 2> AttrToAdd;
9029 SmallVector<StringRef, 2> AttrToRemove;
9030 if (Known.Mode == DenormalMode::getDefault()) {
9031 AttrToRemove.push_back("denormal-fp-math");
9032 } else {
9033 AttrToAdd.push_back(
9034 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
9035 }
9036
9037 if (Known.ModeF32 != Known.Mode) {
9038 AttrToAdd.push_back(
9039 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
9040 } else {
9041 AttrToRemove.push_back("denormal-fp-math-f32");
9042 }
9043
9044 auto &IRP = getIRPosition();
9045
9046 // TODO: There should be a combined add and remove API.
9047 return A.removeAttrs(IRP, AttrToRemove) |
9048 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9049 }
9050
9051 void trackStatistics() const override {
9052 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
9053 }
9054};
9055} // namespace
9056
9057/// ------------------ Value Constant Range Attribute -------------------------
9058
9059namespace {
9060struct AAValueConstantRangeImpl : AAValueConstantRange {
9061 using StateType = IntegerRangeState;
9062 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9063 : AAValueConstantRange(IRP, A) {}
9064
9065 /// See AbstractAttribute::initialize(..).
9066 void initialize(Attributor &A) override {
9067 if (A.hasSimplificationCallback(getIRPosition())) {
9068 indicatePessimisticFixpoint();
9069 return;
9070 }
9071
9072 // Intersect a range given by SCEV.
9073 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9074
9075 // Intersect a range given by LVI.
9076 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9077 }
9078
9079 /// See AbstractAttribute::getAsStr().
9080 const std::string getAsStr(Attributor *A) const override {
9081 std::string Str;
9082 llvm::raw_string_ostream OS(Str);
9083 OS << "range(" << getBitWidth() << ")<";
9084 getKnown().print(OS);
9085 OS << " / ";
9086 getAssumed().print(OS);
9087 OS << ">";
9088 return Str;
9089 }
9090
9091 /// Helper function to get a SCEV expr for the associated value at program
9092 /// point \p I.
9093 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9094 if (!getAnchorScope())
9095 return nullptr;
9096
9097 ScalarEvolution *SE =
9098 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9099 *getAnchorScope());
9100
9101 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9102 *getAnchorScope());
9103
9104 if (!SE || !LI)
9105 return nullptr;
9106
9107 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9108 if (!I)
9109 return S;
9110
9111 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9112 }
9113
9114 /// Helper function to get a range from SCEV for the associated value at
9115 /// program point \p I.
9116 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9117 const Instruction *I = nullptr) const {
9118 if (!getAnchorScope())
9119 return getWorstState(getBitWidth());
9120
9121 ScalarEvolution *SE =
9122 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9123 *getAnchorScope());
9124
9125 const SCEV *S = getSCEV(A, I);
9126 if (!SE || !S)
9127 return getWorstState(getBitWidth());
9128
9129 return SE->getUnsignedRange(S);
9130 }
9131
9132 /// Helper function to get a range from LVI for the associated value at
9133 /// program point \p I.
9134 ConstantRange
9135 getConstantRangeFromLVI(Attributor &A,
9136 const Instruction *CtxI = nullptr) const {
9137 if (!getAnchorScope())
9138 return getWorstState(getBitWidth());
9139
9140 LazyValueInfo *LVI =
9141 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9142 *getAnchorScope());
9143
9144 if (!LVI || !CtxI)
9145 return getWorstState(getBitWidth());
9146 return LVI->getConstantRange(&getAssociatedValue(),
9147 const_cast<Instruction *>(CtxI),
9148 /*UndefAllowed*/ false);
9149 }
9150
9151 /// Return true if \p CtxI is valid for querying outside analyses.
9152 /// This basically makes sure we do not ask intra-procedural analysis
9153 /// about a context in the wrong function or a context that violates
9154 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9155 /// if the original context of this AA is OK or should be considered invalid.
9156 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9157 const Instruction *CtxI,
9158 bool AllowAACtxI) const {
9159 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9160 return false;
9161
9162 // Our context might be in a different function, neither intra-procedural
9163 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9164 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9165 return false;
9166
9167 // If the context is not dominated by the value there are paths to the
9168 // context that do not define the value. This cannot be handled by
9169 // LazyValueInfo so we need to bail.
9170 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9171 InformationCache &InfoCache = A.getInfoCache();
9172 const DominatorTree *DT =
9173 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9174 *I->getFunction());
9175 return DT && DT->dominates(I, CtxI);
9176 }
9177
9178 return true;
9179 }
9180
9181 /// See AAValueConstantRange::getKnownConstantRange(..).
9182 ConstantRange
9183 getKnownConstantRange(Attributor &A,
9184 const Instruction *CtxI = nullptr) const override {
9185 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9186 /* AllowAACtxI */ false))
9187 return getKnown();
9188
9189 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9190 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9191 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9192 }
9193
9194 /// See AAValueConstantRange::getAssumedConstantRange(..).
9195 ConstantRange
9196 getAssumedConstantRange(Attributor &A,
9197 const Instruction *CtxI = nullptr) const override {
9198 // TODO: Make SCEV use Attributor assumption.
9199 // We may be able to bound a variable range via assumptions in
9200 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9201 // evolve to x^2 + x, then we can say that y is in [2, 12].
9202 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9203 /* AllowAACtxI */ false))
9204 return getAssumed();
9205
9206 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9207 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9208 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9209 }
9210
9211 /// Helper function to create MDNode for range metadata.
9212 static MDNode *
9213 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9214 const ConstantRange &AssumedConstantRange) {
9215 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9216 Ty, AssumedConstantRange.getLower())),
9217 ConstantAsMetadata::get(ConstantInt::get(
9218 Ty, AssumedConstantRange.getUpper()))};
9219 return MDNode::get(Ctx, LowAndHigh);
9220 }
9221
9222 /// Return true if \p Assumed is included in ranges from instruction \p I.
9223 static bool isBetterRange(const ConstantRange &Assumed,
9224 const Instruction &I) {
9225 if (Assumed.isFullSet())
9226 return false;
9227
9228 std::optional<ConstantRange> Known;
9229
9230 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9231 Known = CB->getRange();
9232 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9233 // If multiple ranges are annotated in IR, we give up to annotate assumed
9234 // range for now.
9235
9236 // TODO: If there exists a known range which containts assumed range, we
9237 // can say assumed range is better.
9238 if (KnownRanges->getNumOperands() > 2)
9239 return false;
9240
9241 ConstantInt *Lower =
9242 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9243 ConstantInt *Upper =
9244 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9245
9246 Known.emplace(Lower->getValue(), Upper->getValue());
9247 }
9248 return !Known || (*Known != Assumed && Known->contains(Assumed));
9249 }
9250
9251 /// Helper function to set range metadata.
9252 static bool
9253 setRangeMetadataIfisBetterRange(Instruction *I,
9254 const ConstantRange &AssumedConstantRange) {
9255 if (isBetterRange(AssumedConstantRange, *I)) {
9256 I->setMetadata(LLVMContext::MD_range,
9257 getMDNodeForConstantRange(I->getType(), I->getContext(),
9258 AssumedConstantRange));
9259 return true;
9260 }
9261 return false;
9262 }
9263 /// Helper function to set range return attribute.
9264 static bool
9265 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9266 Instruction *I,
9267 const ConstantRange &AssumedConstantRange) {
9268 if (isBetterRange(AssumedConstantRange, *I)) {
9269 A.manifestAttrs(IRP,
9270 Attribute::get(I->getContext(), Attribute::Range,
9271 AssumedConstantRange),
9272 /*ForceReplace*/ true);
9273 return true;
9274 }
9275 return false;
9276 }
9277
9278 /// See AbstractAttribute::manifest()
9279 ChangeStatus manifest(Attributor &A) override {
9280 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9281 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9282 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9283
9284 auto &V = getAssociatedValue();
9285 if (!AssumedConstantRange.isEmptySet() &&
9286 !AssumedConstantRange.isSingleElement()) {
9287 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9288 assert(I == getCtxI() && "Should not annotate an instruction which is "
9289 "not the context instruction");
9290 if (isa<LoadInst>(I))
9291 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9292 Changed = ChangeStatus::CHANGED;
9293 if (isa<CallInst>(I))
9294 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9295 AssumedConstantRange))
9296 Changed = ChangeStatus::CHANGED;
9297 }
9298 }
9299
9300 return Changed;
9301 }
9302};
9303
9304struct AAValueConstantRangeArgument final
9305 : AAArgumentFromCallSiteArguments<
9306 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9307 true /* BridgeCallBaseContext */> {
9308 using Base = AAArgumentFromCallSiteArguments<
9309 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9310 true /* BridgeCallBaseContext */>;
9311 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9312 : Base(IRP, A) {}
9313
9314 /// See AbstractAttribute::trackStatistics()
9315 void trackStatistics() const override {
9316 STATS_DECLTRACK_ARG_ATTR(value_range)
9317 }
9318};
9319
9320struct AAValueConstantRangeReturned
9321 : AAReturnedFromReturnedValues<AAValueConstantRange,
9322 AAValueConstantRangeImpl,
9323 AAValueConstantRangeImpl::StateType,
9324 /* PropagateCallBaseContext */ true> {
9325 using Base =
9326 AAReturnedFromReturnedValues<AAValueConstantRange,
9327 AAValueConstantRangeImpl,
9328 AAValueConstantRangeImpl::StateType,
9329 /* PropagateCallBaseContext */ true>;
9330 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9331 : Base(IRP, A) {}
9332
9333 /// See AbstractAttribute::initialize(...).
9334 void initialize(Attributor &A) override {
9335 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9336 indicatePessimisticFixpoint();
9337 }
9338
9339 /// See AbstractAttribute::trackStatistics()
9340 void trackStatistics() const override {
9341 STATS_DECLTRACK_FNRET_ATTR(value_range)
9342 }
9343};
9344
9345struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9346 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9347 : AAValueConstantRangeImpl(IRP, A) {}
9348
9349 /// See AbstractAttribute::initialize(...).
9350 void initialize(Attributor &A) override {
9351 AAValueConstantRangeImpl::initialize(A);
9352 if (isAtFixpoint())
9353 return;
9354
9355 Value &V = getAssociatedValue();
9356
9357 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9358 unionAssumed(ConstantRange(C->getValue()));
9359 indicateOptimisticFixpoint();
9360 return;
9361 }
9362
9363 if (isa<UndefValue>(&V)) {
9364 // Collapse the undef state to 0.
9365 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9366 indicateOptimisticFixpoint();
9367 return;
9368 }
9369
9370 if (isa<CallBase>(&V))
9371 return;
9372
9373 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9374 return;
9375
9376 // If it is a load instruction with range metadata, use it.
9377 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9378 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9379 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9380 return;
9381 }
9382
9383 // We can work with PHI and select instruction as we traverse their operands
9384 // during update.
9385 if (isa<SelectInst>(V) || isa<PHINode>(V))
9386 return;
9387
9388 // Otherwise we give up.
9389 indicatePessimisticFixpoint();
9390
9391 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9392 << getAssociatedValue() << "\n");
9393 }
9394
9395 bool calculateBinaryOperator(
9396 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9397 const Instruction *CtxI,
9398 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9399 Value *LHS = BinOp->getOperand(0);
9400 Value *RHS = BinOp->getOperand(1);
9401
9402 // Simplify the operands first.
9403 bool UsedAssumedInformation = false;
9404 const auto &SimplifiedLHS = A.getAssumedSimplified(
9405 IRPosition::value(*LHS, getCallBaseContext()), *this,
9406 UsedAssumedInformation, AA::Interprocedural);
9407 if (!SimplifiedLHS.has_value())
9408 return true;
9409 if (!*SimplifiedLHS)
9410 return false;
9411 LHS = *SimplifiedLHS;
9412
9413 const auto &SimplifiedRHS = A.getAssumedSimplified(
9414 IRPosition::value(*RHS, getCallBaseContext()), *this,
9415 UsedAssumedInformation, AA::Interprocedural);
9416 if (!SimplifiedRHS.has_value())
9417 return true;
9418 if (!*SimplifiedRHS)
9419 return false;
9420 RHS = *SimplifiedRHS;
9421
9422 // TODO: Allow non integers as well.
9423 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9424 return false;
9425
9426 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9427 *this, IRPosition::value(*LHS, getCallBaseContext()),
9428 DepClassTy::REQUIRED);
9429 if (!LHSAA)
9430 return false;
9431 QuerriedAAs.push_back(LHSAA);
9432 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9433
9434 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9435 *this, IRPosition::value(*RHS, getCallBaseContext()),
9436 DepClassTy::REQUIRED);
9437 if (!RHSAA)
9438 return false;
9439 QuerriedAAs.push_back(RHSAA);
9440 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9441
9442 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9443
9444 T.unionAssumed(AssumedRange);
9445
9446 // TODO: Track a known state too.
9447
9448 return T.isValidState();
9449 }
9450
9451 bool calculateCastInst(
9452 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9453 const Instruction *CtxI,
9454 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9455 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9456 // TODO: Allow non integers as well.
9457 Value *OpV = CastI->getOperand(0);
9458
9459 // Simplify the operand first.
9460 bool UsedAssumedInformation = false;
9461 const auto &SimplifiedOpV = A.getAssumedSimplified(
9462 IRPosition::value(*OpV, getCallBaseContext()), *this,
9463 UsedAssumedInformation, AA::Interprocedural);
9464 if (!SimplifiedOpV.has_value())
9465 return true;
9466 if (!*SimplifiedOpV)
9467 return false;
9468 OpV = *SimplifiedOpV;
9469
9470 if (!OpV->getType()->isIntegerTy())
9471 return false;
9472
9473 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9474 *this, IRPosition::value(*OpV, getCallBaseContext()),
9475 DepClassTy::REQUIRED);
9476 if (!OpAA)
9477 return false;
9478 QuerriedAAs.push_back(OpAA);
9479 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9480 getState().getBitWidth()));
9481 return T.isValidState();
9482 }
9483
9484 bool
9485 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9486 const Instruction *CtxI,
9487 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9488 Value *LHS = CmpI->getOperand(0);
9489 Value *RHS = CmpI->getOperand(1);
9490
9491 // Simplify the operands first.
9492 bool UsedAssumedInformation = false;
9493 const auto &SimplifiedLHS = A.getAssumedSimplified(
9494 IRPosition::value(*LHS, getCallBaseContext()), *this,
9495 UsedAssumedInformation, AA::Interprocedural);
9496 if (!SimplifiedLHS.has_value())
9497 return true;
9498 if (!*SimplifiedLHS)
9499 return false;
9500 LHS = *SimplifiedLHS;
9501
9502 const auto &SimplifiedRHS = A.getAssumedSimplified(
9503 IRPosition::value(*RHS, getCallBaseContext()), *this,
9504 UsedAssumedInformation, AA::Interprocedural);
9505 if (!SimplifiedRHS.has_value())
9506 return true;
9507 if (!*SimplifiedRHS)
9508 return false;
9509 RHS = *SimplifiedRHS;
9510
9511 // TODO: Allow non integers as well.
9512 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9513 return false;
9514
9515 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9516 *this, IRPosition::value(*LHS, getCallBaseContext()),
9517 DepClassTy::REQUIRED);
9518 if (!LHSAA)
9519 return false;
9520 QuerriedAAs.push_back(LHSAA);
9521 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9522 *this, IRPosition::value(*RHS, getCallBaseContext()),
9523 DepClassTy::REQUIRED);
9524 if (!RHSAA)
9525 return false;
9526 QuerriedAAs.push_back(RHSAA);
9527 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9528 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9529
9530 // If one of them is empty set, we can't decide.
9531 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9532 return true;
9533
9534 bool MustTrue = false, MustFalse = false;
9535
9536 auto AllowedRegion =
9538
9539 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9540 MustFalse = true;
9541
9542 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9543 MustTrue = true;
9544
9545 assert((!MustTrue || !MustFalse) &&
9546 "Either MustTrue or MustFalse should be false!");
9547
9548 if (MustTrue)
9549 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9550 else if (MustFalse)
9551 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9552 else
9553 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9554
9555 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9556 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9557 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9558 << *RHSAA);
9559
9560 // TODO: Track a known state too.
9561 return T.isValidState();
9562 }
9563
9564 /// See AbstractAttribute::updateImpl(...).
9565 ChangeStatus updateImpl(Attributor &A) override {
9566
9567 IntegerRangeState T(getBitWidth());
9568 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9570 if (!I || isa<CallBase>(I)) {
9571
9572 // Simplify the operand first.
9573 bool UsedAssumedInformation = false;
9574 const auto &SimplifiedOpV = A.getAssumedSimplified(
9575 IRPosition::value(V, getCallBaseContext()), *this,
9576 UsedAssumedInformation, AA::Interprocedural);
9577 if (!SimplifiedOpV.has_value())
9578 return true;
9579 if (!*SimplifiedOpV)
9580 return false;
9581 Value *VPtr = *SimplifiedOpV;
9582
9583 // If the value is not instruction, we query AA to Attributor.
9584 const auto *AA = A.getAAFor<AAValueConstantRange>(
9585 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9586 DepClassTy::REQUIRED);
9587
9588 // Clamp operator is not used to utilize a program point CtxI.
9589 if (AA)
9590 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9591 else
9592 return false;
9593
9594 return T.isValidState();
9595 }
9596
9598 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9599 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9600 return false;
9601 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9602 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9603 return false;
9604 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9605 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9606 return false;
9607 } else {
9608 // Give up with other instructions.
9609 // TODO: Add other instructions
9610
9611 T.indicatePessimisticFixpoint();
9612 return false;
9613 }
9614
9615 // Catch circular reasoning in a pessimistic way for now.
9616 // TODO: Check how the range evolves and if we stripped anything, see also
9617 // AADereferenceable or AAAlign for similar situations.
9618 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9619 if (QueriedAA != this)
9620 continue;
9621 // If we are in a stady state we do not need to worry.
9622 if (T.getAssumed() == getState().getAssumed())
9623 continue;
9624 T.indicatePessimisticFixpoint();
9625 }
9626
9627 return T.isValidState();
9628 };
9629
9630 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9631 return indicatePessimisticFixpoint();
9632
9633 // Ensure that long def-use chains can't cause circular reasoning either by
9634 // introducing a cutoff below.
9635 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9636 return ChangeStatus::UNCHANGED;
9637 if (++NumChanges > MaxNumChanges) {
9638 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9639 << " but only " << MaxNumChanges
9640 << " are allowed to avoid cyclic reasoning.");
9641 return indicatePessimisticFixpoint();
9642 }
9643 return ChangeStatus::CHANGED;
9644 }
9645
9646 /// See AbstractAttribute::trackStatistics()
9647 void trackStatistics() const override {
9649 }
9650
9651 /// Tracker to bail after too many widening steps of the constant range.
9652 int NumChanges = 0;
9653
9654 /// Upper bound for the number of allowed changes (=widening steps) for the
9655 /// constant range before we give up.
9656 static constexpr int MaxNumChanges = 5;
9657};
9658
9659struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9660 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9661 : AAValueConstantRangeImpl(IRP, A) {}
9662
9663 /// See AbstractAttribute::initialize(...).
9664 ChangeStatus updateImpl(Attributor &A) override {
9665 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9666 "not be called");
9667 }
9668
9669 /// See AbstractAttribute::trackStatistics()
9670 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9671};
9672
9673struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9674 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9675 : AAValueConstantRangeFunction(IRP, A) {}
9676
9677 /// See AbstractAttribute::trackStatistics()
9678 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9679};
9680
9681struct AAValueConstantRangeCallSiteReturned
9682 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9683 AAValueConstantRangeImpl::StateType,
9684 /* IntroduceCallBaseContext */ true> {
9685 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9686 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9687 AAValueConstantRangeImpl::StateType,
9688 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9689
9690 /// See AbstractAttribute::initialize(...).
9691 void initialize(Attributor &A) override {
9692 // If it is a call instruction with range attribute, use the range.
9693 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9694 if (std::optional<ConstantRange> Range = CI->getRange())
9695 intersectKnown(*Range);
9696 }
9697
9698 AAValueConstantRangeImpl::initialize(A);
9699 }
9700
9701 /// See AbstractAttribute::trackStatistics()
9702 void trackStatistics() const override {
9703 STATS_DECLTRACK_CSRET_ATTR(value_range)
9704 }
9705};
9706struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9707 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9708 : AAValueConstantRangeFloating(IRP, A) {}
9709
9710 /// See AbstractAttribute::manifest()
9711 ChangeStatus manifest(Attributor &A) override {
9712 return ChangeStatus::UNCHANGED;
9713 }
9714
9715 /// See AbstractAttribute::trackStatistics()
9716 void trackStatistics() const override {
9717 STATS_DECLTRACK_CSARG_ATTR(value_range)
9718 }
9719};
9720} // namespace
9721
9722/// ------------------ Potential Values Attribute -------------------------
9723
9724namespace {
9725struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9726 using StateType = PotentialConstantIntValuesState;
9727
9728 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9729 : AAPotentialConstantValues(IRP, A) {}
9730
9731 /// See AbstractAttribute::initialize(..).
9732 void initialize(Attributor &A) override {
9733 if (A.hasSimplificationCallback(getIRPosition()))
9734 indicatePessimisticFixpoint();
9735 else
9736 AAPotentialConstantValues::initialize(A);
9737 }
9738
9739 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9740 bool &ContainsUndef, bool ForSelf) {
9742 bool UsedAssumedInformation = false;
9743 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9744 UsedAssumedInformation)) {
9745 // Avoid recursion when the caller is computing constant values for this
9746 // IRP itself.
9747 if (ForSelf)
9748 return false;
9749 if (!IRP.getAssociatedType()->isIntegerTy())
9750 return false;
9751 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9752 *this, IRP, DepClassTy::REQUIRED);
9753 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9754 return false;
9755 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9756 S = PotentialValuesAA->getState().getAssumedSet();
9757 return true;
9758 }
9759
9760 // Copy all the constant values, except UndefValue. ContainsUndef is true
9761 // iff Values contains only UndefValue instances. If there are other known
9762 // constants, then UndefValue is dropped.
9763 ContainsUndef = false;
9764 for (auto &It : Values) {
9765 if (isa<UndefValue>(It.getValue())) {
9766 ContainsUndef = true;
9767 continue;
9768 }
9769 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9770 if (!CI)
9771 return false;
9772 S.insert(CI->getValue());
9773 }
9774 ContainsUndef &= S.empty();
9775
9776 return true;
9777 }
9778
9779 /// See AbstractAttribute::getAsStr().
9780 const std::string getAsStr(Attributor *A) const override {
9781 std::string Str;
9782 llvm::raw_string_ostream OS(Str);
9783 OS << getState();
9784 return Str;
9785 }
9786
9787 /// See AbstractAttribute::updateImpl(...).
9788 ChangeStatus updateImpl(Attributor &A) override {
9789 return indicatePessimisticFixpoint();
9790 }
9791};
9792
9793struct AAPotentialConstantValuesArgument final
9794 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9795 AAPotentialConstantValuesImpl,
9796 PotentialConstantIntValuesState> {
9797 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9798 AAPotentialConstantValuesImpl,
9800 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9801 : Base(IRP, A) {}
9802
9803 /// See AbstractAttribute::trackStatistics()
9804 void trackStatistics() const override {
9805 STATS_DECLTRACK_ARG_ATTR(potential_values)
9806 }
9807};
9808
9809struct AAPotentialConstantValuesReturned
9810 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9811 AAPotentialConstantValuesImpl> {
9812 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9813 AAPotentialConstantValuesImpl>;
9814 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9815 : Base(IRP, A) {}
9816
9817 void initialize(Attributor &A) override {
9818 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9819 indicatePessimisticFixpoint();
9820 Base::initialize(A);
9821 }
9822
9823 /// See AbstractAttribute::trackStatistics()
9824 void trackStatistics() const override {
9825 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9826 }
9827};
9828
9829struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9830 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9831 : AAPotentialConstantValuesImpl(IRP, A) {}
9832
9833 /// See AbstractAttribute::initialize(..).
9834 void initialize(Attributor &A) override {
9835 AAPotentialConstantValuesImpl::initialize(A);
9836 if (isAtFixpoint())
9837 return;
9838
9839 Value &V = getAssociatedValue();
9840
9841 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9842 unionAssumed(C->getValue());
9843 indicateOptimisticFixpoint();
9844 return;
9845 }
9846
9847 if (isa<UndefValue>(&V)) {
9848 unionAssumedWithUndef();
9849 indicateOptimisticFixpoint();
9850 return;
9851 }
9852
9853 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9854 return;
9855
9856 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9857 return;
9858
9859 indicatePessimisticFixpoint();
9860
9861 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9862 << getAssociatedValue() << "\n");
9863 }
9864
9865 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9866 const APInt &RHS) {
9867 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9868 }
9869
9870 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9871 uint32_t ResultBitWidth) {
9872 Instruction::CastOps CastOp = CI->getOpcode();
9873 switch (CastOp) {
9874 default:
9875 llvm_unreachable("unsupported or not integer cast");
9876 case Instruction::Trunc:
9877 return Src.trunc(ResultBitWidth);
9878 case Instruction::SExt:
9879 return Src.sext(ResultBitWidth);
9880 case Instruction::ZExt:
9881 return Src.zext(ResultBitWidth);
9882 case Instruction::BitCast:
9883 return Src;
9884 }
9885 }
9886
9887 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9888 const APInt &LHS, const APInt &RHS,
9889 bool &SkipOperation, bool &Unsupported) {
9890 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9891 // Unsupported is set to true when the binary operator is not supported.
9892 // SkipOperation is set to true when UB occur with the given operand pair
9893 // (LHS, RHS).
9894 // TODO: we should look at nsw and nuw keywords to handle operations
9895 // that create poison or undef value.
9896 switch (BinOpcode) {
9897 default:
9898 Unsupported = true;
9899 return LHS;
9900 case Instruction::Add:
9901 return LHS + RHS;
9902 case Instruction::Sub:
9903 return LHS - RHS;
9904 case Instruction::Mul:
9905 return LHS * RHS;
9906 case Instruction::UDiv:
9907 if (RHS.isZero()) {
9908 SkipOperation = true;
9909 return LHS;
9910 }
9911 return LHS.udiv(RHS);
9912 case Instruction::SDiv:
9913 if (RHS.isZero()) {
9914 SkipOperation = true;
9915 return LHS;
9916 }
9917 return LHS.sdiv(RHS);
9918 case Instruction::URem:
9919 if (RHS.isZero()) {
9920 SkipOperation = true;
9921 return LHS;
9922 }
9923 return LHS.urem(RHS);
9924 case Instruction::SRem:
9925 if (RHS.isZero()) {
9926 SkipOperation = true;
9927 return LHS;
9928 }
9929 return LHS.srem(RHS);
9930 case Instruction::Shl:
9931 return LHS.shl(RHS);
9932 case Instruction::LShr:
9933 return LHS.lshr(RHS);
9934 case Instruction::AShr:
9935 return LHS.ashr(RHS);
9936 case Instruction::And:
9937 return LHS & RHS;
9938 case Instruction::Or:
9939 return LHS | RHS;
9940 case Instruction::Xor:
9941 return LHS ^ RHS;
9942 }
9943 }
9944
9945 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9946 const APInt &LHS, const APInt &RHS) {
9947 bool SkipOperation = false;
9948 bool Unsupported = false;
9949 APInt Result =
9950 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9951 if (Unsupported)
9952 return false;
9953 // If SkipOperation is true, we can ignore this operand pair (L, R).
9954 if (!SkipOperation)
9955 unionAssumed(Result);
9956 return isValidState();
9957 }
9958
9959 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9960 auto AssumedBefore = getAssumed();
9961 Value *LHS = ICI->getOperand(0);
9962 Value *RHS = ICI->getOperand(1);
9963
9964 bool LHSContainsUndef = false, RHSContainsUndef = false;
9965 SetTy LHSAAPVS, RHSAAPVS;
9966 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9967 LHSContainsUndef, /* ForSelf */ false) ||
9968 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9969 RHSContainsUndef, /* ForSelf */ false))
9970 return indicatePessimisticFixpoint();
9971
9972 // TODO: make use of undef flag to limit potential values aggressively.
9973 bool MaybeTrue = false, MaybeFalse = false;
9974 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9975 if (LHSContainsUndef && RHSContainsUndef) {
9976 // The result of any comparison between undefs can be soundly replaced
9977 // with undef.
9978 unionAssumedWithUndef();
9979 } else if (LHSContainsUndef) {
9980 for (const APInt &R : RHSAAPVS) {
9981 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9982 MaybeTrue |= CmpResult;
9983 MaybeFalse |= !CmpResult;
9984 if (MaybeTrue & MaybeFalse)
9985 return indicatePessimisticFixpoint();
9986 }
9987 } else if (RHSContainsUndef) {
9988 for (const APInt &L : LHSAAPVS) {
9989 bool CmpResult = calculateICmpInst(ICI, L, Zero);
9990 MaybeTrue |= CmpResult;
9991 MaybeFalse |= !CmpResult;
9992 if (MaybeTrue & MaybeFalse)
9993 return indicatePessimisticFixpoint();
9994 }
9995 } else {
9996 for (const APInt &L : LHSAAPVS) {
9997 for (const APInt &R : RHSAAPVS) {
9998 bool CmpResult = calculateICmpInst(ICI, L, R);
9999 MaybeTrue |= CmpResult;
10000 MaybeFalse |= !CmpResult;
10001 if (MaybeTrue & MaybeFalse)
10002 return indicatePessimisticFixpoint();
10003 }
10004 }
10005 }
10006 if (MaybeTrue)
10007 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10008 if (MaybeFalse)
10009 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10010 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10011 : ChangeStatus::CHANGED;
10012 }
10013
10014 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10015 auto AssumedBefore = getAssumed();
10016 Value *LHS = SI->getTrueValue();
10017 Value *RHS = SI->getFalseValue();
10018
10019 bool UsedAssumedInformation = false;
10020 std::optional<Constant *> C = A.getAssumedConstant(
10021 *SI->getCondition(), *this, UsedAssumedInformation);
10022
10023 // Check if we only need one operand.
10024 bool OnlyLeft = false, OnlyRight = false;
10025 if (C && *C && (*C)->isOneValue())
10026 OnlyLeft = true;
10027 else if (C && *C && (*C)->isZeroValue())
10028 OnlyRight = true;
10029
10030 bool LHSContainsUndef = false, RHSContainsUndef = false;
10031 SetTy LHSAAPVS, RHSAAPVS;
10032 if (!OnlyRight &&
10033 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10034 LHSContainsUndef, /* ForSelf */ false))
10035 return indicatePessimisticFixpoint();
10036
10037 if (!OnlyLeft &&
10038 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10039 RHSContainsUndef, /* ForSelf */ false))
10040 return indicatePessimisticFixpoint();
10041
10042 if (OnlyLeft || OnlyRight) {
10043 // select (true/false), lhs, rhs
10044 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10045 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10046
10047 if (Undef)
10048 unionAssumedWithUndef();
10049 else {
10050 for (const auto &It : *OpAA)
10051 unionAssumed(It);
10052 }
10053
10054 } else if (LHSContainsUndef && RHSContainsUndef) {
10055 // select i1 *, undef , undef => undef
10056 unionAssumedWithUndef();
10057 } else {
10058 for (const auto &It : LHSAAPVS)
10059 unionAssumed(It);
10060 for (const auto &It : RHSAAPVS)
10061 unionAssumed(It);
10062 }
10063 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10064 : ChangeStatus::CHANGED;
10065 }
10066
10067 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10068 auto AssumedBefore = getAssumed();
10069 if (!CI->isIntegerCast())
10070 return indicatePessimisticFixpoint();
10071 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10072 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10073 Value *Src = CI->getOperand(0);
10074
10075 bool SrcContainsUndef = false;
10076 SetTy SrcPVS;
10077 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10078 SrcContainsUndef, /* ForSelf */ false))
10079 return indicatePessimisticFixpoint();
10080
10081 if (SrcContainsUndef)
10082 unionAssumedWithUndef();
10083 else {
10084 for (const APInt &S : SrcPVS) {
10085 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10086 unionAssumed(T);
10087 }
10088 }
10089 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10090 : ChangeStatus::CHANGED;
10091 }
10092
10093 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10094 auto AssumedBefore = getAssumed();
10095 Value *LHS = BinOp->getOperand(0);
10096 Value *RHS = BinOp->getOperand(1);
10097
10098 bool LHSContainsUndef = false, RHSContainsUndef = false;
10099 SetTy LHSAAPVS, RHSAAPVS;
10100 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10101 LHSContainsUndef, /* ForSelf */ false) ||
10102 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10103 RHSContainsUndef, /* ForSelf */ false))
10104 return indicatePessimisticFixpoint();
10105
10106 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10107
10108 // TODO: make use of undef flag to limit potential values aggressively.
10109 if (LHSContainsUndef && RHSContainsUndef) {
10110 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10111 return indicatePessimisticFixpoint();
10112 } else if (LHSContainsUndef) {
10113 for (const APInt &R : RHSAAPVS) {
10114 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10115 return indicatePessimisticFixpoint();
10116 }
10117 } else if (RHSContainsUndef) {
10118 for (const APInt &L : LHSAAPVS) {
10119 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10120 return indicatePessimisticFixpoint();
10121 }
10122 } else {
10123 for (const APInt &L : LHSAAPVS) {
10124 for (const APInt &R : RHSAAPVS) {
10125 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10126 return indicatePessimisticFixpoint();
10127 }
10128 }
10129 }
10130 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10131 : ChangeStatus::CHANGED;
10132 }
10133
10134 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10135 auto AssumedBefore = getAssumed();
10136 SetTy Incoming;
10137 bool ContainsUndef;
10138 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10139 ContainsUndef, /* ForSelf */ true))
10140 return indicatePessimisticFixpoint();
10141 if (ContainsUndef) {
10142 unionAssumedWithUndef();
10143 } else {
10144 for (const auto &It : Incoming)
10145 unionAssumed(It);
10146 }
10147 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10148 : ChangeStatus::CHANGED;
10149 }
10150
10151 /// See AbstractAttribute::updateImpl(...).
10152 ChangeStatus updateImpl(Attributor &A) override {
10153 Value &V = getAssociatedValue();
10155
10156 if (auto *ICI = dyn_cast<ICmpInst>(I))
10157 return updateWithICmpInst(A, ICI);
10158
10159 if (auto *SI = dyn_cast<SelectInst>(I))
10160 return updateWithSelectInst(A, SI);
10161
10162 if (auto *CI = dyn_cast<CastInst>(I))
10163 return updateWithCastInst(A, CI);
10164
10165 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10166 return updateWithBinaryOperator(A, BinOp);
10167
10168 if (isa<PHINode>(I) || isa<LoadInst>(I))
10169 return updateWithInstruction(A, I);
10170
10171 return indicatePessimisticFixpoint();
10172 }
10173
10174 /// See AbstractAttribute::trackStatistics()
10175 void trackStatistics() const override {
10176 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10177 }
10178};
10179
10180struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10181 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10182 : AAPotentialConstantValuesImpl(IRP, A) {}
10183
10184 /// See AbstractAttribute::initialize(...).
10185 ChangeStatus updateImpl(Attributor &A) override {
10187 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10188 "not be called");
10189 }
10190
10191 /// See AbstractAttribute::trackStatistics()
10192 void trackStatistics() const override {
10193 STATS_DECLTRACK_FN_ATTR(potential_values)
10194 }
10195};
10196
10197struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10198 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10199 : AAPotentialConstantValuesFunction(IRP, A) {}
10200
10201 /// See AbstractAttribute::trackStatistics()
10202 void trackStatistics() const override {
10203 STATS_DECLTRACK_CS_ATTR(potential_values)
10204 }
10205};
10206
10207struct AAPotentialConstantValuesCallSiteReturned
10208 : AACalleeToCallSite<AAPotentialConstantValues,
10209 AAPotentialConstantValuesImpl> {
10210 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10211 Attributor &A)
10212 : AACalleeToCallSite<AAPotentialConstantValues,
10213 AAPotentialConstantValuesImpl>(IRP, A) {}
10214
10215 /// See AbstractAttribute::trackStatistics()
10216 void trackStatistics() const override {
10217 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10218 }
10219};
10220
10221struct AAPotentialConstantValuesCallSiteArgument
10222 : AAPotentialConstantValuesFloating {
10223 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10224 Attributor &A)
10225 : AAPotentialConstantValuesFloating(IRP, A) {}
10226
10227 /// See AbstractAttribute::initialize(..).
10228 void initialize(Attributor &A) override {
10229 AAPotentialConstantValuesImpl::initialize(A);
10230 if (isAtFixpoint())
10231 return;
10232
10233 Value &V = getAssociatedValue();
10234
10235 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10236 unionAssumed(C->getValue());
10237 indicateOptimisticFixpoint();
10238 return;
10239 }
10240
10241 if (isa<UndefValue>(&V)) {
10242 unionAssumedWithUndef();
10243 indicateOptimisticFixpoint();
10244 return;
10245 }
10246 }
10247
10248 /// See AbstractAttribute::updateImpl(...).
10249 ChangeStatus updateImpl(Attributor &A) override {
10250 Value &V = getAssociatedValue();
10251 auto AssumedBefore = getAssumed();
10252 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10253 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10254 if (!AA)
10255 return indicatePessimisticFixpoint();
10256 const auto &S = AA->getAssumed();
10257 unionAssumed(S);
10258 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10259 : ChangeStatus::CHANGED;
10260 }
10261
10262 /// See AbstractAttribute::trackStatistics()
10263 void trackStatistics() const override {
10264 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10265 }
10266};
10267} // namespace
10268
10269/// ------------------------ NoUndef Attribute ---------------------------------
10271 Attribute::AttrKind ImpliedAttributeKind,
10272 bool IgnoreSubsumingPositions) {
10273 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10274 "Unexpected attribute kind");
10275 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10276 Attribute::NoUndef))
10277 return true;
10278
10279 Value &Val = IRP.getAssociatedValue();
10282 LLVMContext &Ctx = Val.getContext();
10283 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10284 return true;
10285 }
10286
10287 return false;
10288}
10289
10290namespace {
10291struct AANoUndefImpl : AANoUndef {
10292 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10293
10294 /// See AbstractAttribute::initialize(...).
10295 void initialize(Attributor &A) override {
10296 Value &V = getAssociatedValue();
10297 if (isa<UndefValue>(V))
10298 indicatePessimisticFixpoint();
10299 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10300 }
10301
10302 /// See followUsesInMBEC
10303 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10304 AANoUndef::StateType &State) {
10305 const Value *UseV = U->get();
10306 const DominatorTree *DT = nullptr;
10307 AssumptionCache *AC = nullptr;
10308 InformationCache &InfoCache = A.getInfoCache();
10309 if (Function *F = getAnchorScope()) {
10310 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10311 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10312 }
10313 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10314 bool TrackUse = false;
10315 // Track use for instructions which must produce undef or poison bits when
10316 // at least one operand contains such bits.
10318 TrackUse = true;
10319 return TrackUse;
10320 }
10321
10322 /// See AbstractAttribute::getAsStr().
10323 const std::string getAsStr(Attributor *A) const override {
10324 return getAssumed() ? "noundef" : "may-undef-or-poison";
10325 }
10326
10327 ChangeStatus manifest(Attributor &A) override {
10328 // We don't manifest noundef attribute for dead positions because the
10329 // associated values with dead positions would be replaced with undef
10330 // values.
10331 bool UsedAssumedInformation = false;
10332 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10333 UsedAssumedInformation))
10334 return ChangeStatus::UNCHANGED;
10335 // A position whose simplified value does not have any value is
10336 // considered to be dead. We don't manifest noundef in such positions for
10337 // the same reason above.
10338 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10340 .has_value())
10341 return ChangeStatus::UNCHANGED;
10342 return AANoUndef::manifest(A);
10343 }
10344};
10345
10346struct AANoUndefFloating : public AANoUndefImpl {
10347 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10348 : AANoUndefImpl(IRP, A) {}
10349
10350 /// See AbstractAttribute::initialize(...).
10351 void initialize(Attributor &A) override {
10352 AANoUndefImpl::initialize(A);
10353 if (!getState().isAtFixpoint() && getAnchorScope() &&
10354 !getAnchorScope()->isDeclaration())
10355 if (Instruction *CtxI = getCtxI())
10356 followUsesInMBEC(*this, A, getState(), *CtxI);
10357 }
10358
10359 /// See AbstractAttribute::updateImpl(...).
10360 ChangeStatus updateImpl(Attributor &A) override {
10361 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10362 bool IsKnownNoUndef;
10364 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10365 };
10366
10367 bool Stripped;
10368 bool UsedAssumedInformation = false;
10369 Value *AssociatedValue = &getAssociatedValue();
10371 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10372 AA::AnyScope, UsedAssumedInformation))
10373 Stripped = false;
10374 else
10375 Stripped =
10376 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10377
10378 if (!Stripped) {
10379 // If we haven't stripped anything we might still be able to use a
10380 // different AA, but only if the IRP changes. Effectively when we
10381 // interpret this not as a call site value but as a floating/argument
10382 // value.
10383 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10384 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10385 return indicatePessimisticFixpoint();
10386 return ChangeStatus::UNCHANGED;
10387 }
10388
10389 for (const auto &VAC : Values)
10390 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10391 return indicatePessimisticFixpoint();
10392
10393 return ChangeStatus::UNCHANGED;
10394 }
10395
10396 /// See AbstractAttribute::trackStatistics()
10397 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10398};
10399
10400struct AANoUndefReturned final
10401 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10402 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10403 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10404
10405 /// See AbstractAttribute::trackStatistics()
10406 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10407};
10408
10409struct AANoUndefArgument final
10410 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10411 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10412 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10413
10414 /// See AbstractAttribute::trackStatistics()
10415 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10416};
10417
10418struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10419 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10420 : AANoUndefFloating(IRP, A) {}
10421
10422 /// See AbstractAttribute::trackStatistics()
10423 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10424};
10425
10426struct AANoUndefCallSiteReturned final
10427 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10428 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10429 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10430
10431 /// See AbstractAttribute::trackStatistics()
10432 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10433};
10434
10435/// ------------------------ NoFPClass Attribute -------------------------------
10436
10437struct AANoFPClassImpl : AANoFPClass {
10438 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10439
10440 void initialize(Attributor &A) override {
10441 const IRPosition &IRP = getIRPosition();
10442
10443 Value &V = IRP.getAssociatedValue();
10444 if (isa<UndefValue>(V)) {
10445 indicateOptimisticFixpoint();
10446 return;
10447 }
10448
10450 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10451 for (const auto &Attr : Attrs) {
10452 addKnownBits(Attr.getNoFPClass());
10453 }
10454
10455 const DataLayout &DL = A.getDataLayout();
10456 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10457 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL);
10458 addKnownBits(~KnownFPClass.KnownFPClasses);
10459 }
10460
10461 if (Instruction *CtxI = getCtxI())
10462 followUsesInMBEC(*this, A, getState(), *CtxI);
10463 }
10464
10465 /// See followUsesInMBEC
10466 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10467 AANoFPClass::StateType &State) {
10468 // TODO: Determine what instructions can be looked through.
10469 auto *CB = dyn_cast<CallBase>(I);
10470 if (!CB)
10471 return false;
10472
10473 if (!CB->isArgOperand(U))
10474 return false;
10475
10476 unsigned ArgNo = CB->getArgOperandNo(U);
10477 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10478 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10479 State.addKnownBits(NoFPAA->getState().getKnown());
10480 return false;
10481 }
10482
10483 const std::string getAsStr(Attributor *A) const override {
10484 std::string Result = "nofpclass";
10485 raw_string_ostream OS(Result);
10486 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10487 return Result;
10488 }
10489
10490 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10491 SmallVectorImpl<Attribute> &Attrs) const override {
10492 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10493 }
10494};
10495
10496struct AANoFPClassFloating : public AANoFPClassImpl {
10497 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10498 : AANoFPClassImpl(IRP, A) {}
10499
10500 /// See AbstractAttribute::updateImpl(...).
10501 ChangeStatus updateImpl(Attributor &A) override {
10503 bool UsedAssumedInformation = false;
10504 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10505 AA::AnyScope, UsedAssumedInformation)) {
10506 Values.push_back({getAssociatedValue(), getCtxI()});
10507 }
10508
10509 StateType T;
10510 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10511 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10512 DepClassTy::REQUIRED);
10513 if (!AA || this == AA) {
10514 T.indicatePessimisticFixpoint();
10515 } else {
10516 const AANoFPClass::StateType &S =
10517 static_cast<const AANoFPClass::StateType &>(AA->getState());
10518 T ^= S;
10519 }
10520 return T.isValidState();
10521 };
10522
10523 for (const auto &VAC : Values)
10524 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10525 return indicatePessimisticFixpoint();
10526
10527 return clampStateAndIndicateChange(getState(), T);
10528 }
10529
10530 /// See AbstractAttribute::trackStatistics()
10531 void trackStatistics() const override {
10533 }
10534};
10535
10536struct AANoFPClassReturned final
10537 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10538 AANoFPClassImpl::StateType, false,
10539 Attribute::None, false> {
10540 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10541 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10542 AANoFPClassImpl::StateType, false,
10543 Attribute::None, false>(IRP, A) {}
10544
10545 /// See AbstractAttribute::trackStatistics()
10546 void trackStatistics() const override {
10548 }
10549};
10550
10551struct AANoFPClassArgument final
10552 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10553 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10554 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10555
10556 /// See AbstractAttribute::trackStatistics()
10557 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10558};
10559
10560struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10561 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10562 : AANoFPClassFloating(IRP, A) {}
10563
10564 /// See AbstractAttribute::trackStatistics()
10565 void trackStatistics() const override {
10567 }
10568};
10569
10570struct AANoFPClassCallSiteReturned final
10571 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10572 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10573 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10574
10575 /// See AbstractAttribute::trackStatistics()
10576 void trackStatistics() const override {
10578 }
10579};
10580
10581struct AACallEdgesImpl : public AACallEdges {
10582 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10583
10584 const SetVector<Function *> &getOptimisticEdges() const override {
10585 return CalledFunctions;
10586 }
10587
10588 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10589
10590 bool hasNonAsmUnknownCallee() const override {
10591 return HasUnknownCalleeNonAsm;
10592 }
10593
10594 const std::string getAsStr(Attributor *A) const override {
10595 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10596 std::to_string(CalledFunctions.size()) + "]";
10597 }
10598
10599 void trackStatistics() const override {}
10600
10601protected:
10602 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10603 if (CalledFunctions.insert(Fn)) {
10604 Change = ChangeStatus::CHANGED;
10605 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10606 << "\n");
10607 }
10608 }
10609
10610 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10611 if (!HasUnknownCallee)
10612 Change = ChangeStatus::CHANGED;
10613 if (NonAsm && !HasUnknownCalleeNonAsm)
10614 Change = ChangeStatus::CHANGED;
10615 HasUnknownCalleeNonAsm |= NonAsm;
10616 HasUnknownCallee = true;
10617 }
10618
10619private:
10620 /// Optimistic set of functions that might be called by this position.
10621 SetVector<Function *> CalledFunctions;
10622
10623 /// Is there any call with a unknown callee.
10624 bool HasUnknownCallee = false;
10625
10626 /// Is there any call with a unknown callee, excluding any inline asm.
10627 bool HasUnknownCalleeNonAsm = false;
10628};
10629
10630struct AACallEdgesCallSite : public AACallEdgesImpl {
10631 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10632 : AACallEdgesImpl(IRP, A) {}
10633 /// See AbstractAttribute::updateImpl(...).
10634 ChangeStatus updateImpl(Attributor &A) override {
10635 ChangeStatus Change = ChangeStatus::UNCHANGED;
10636
10637 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10638 if (Function *Fn = dyn_cast<Function>(&V)) {
10639 addCalledFunction(Fn, Change);
10640 } else {
10641 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10642 setHasUnknownCallee(true, Change);
10643 }
10644
10645 // Explore all values.
10646 return true;
10647 };
10648
10650 // Process any value that we might call.
10651 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10652 if (isa<Constant>(V)) {
10653 VisitValue(*V, CtxI);
10654 return;
10655 }
10656
10657 bool UsedAssumedInformation = false;
10658 Values.clear();
10659 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10660 AA::AnyScope, UsedAssumedInformation)) {
10661 Values.push_back({*V, CtxI});
10662 }
10663 for (auto &VAC : Values)
10664 VisitValue(*VAC.getValue(), VAC.getCtxI());
10665 };
10666
10667 CallBase *CB = cast<CallBase>(getCtxI());
10668
10669 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10670 if (IA->hasSideEffects() &&
10671 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10672 !hasAssumption(*CB, "ompx_no_call_asm")) {
10673 setHasUnknownCallee(false, Change);
10674 }
10675 return Change;
10676 }
10677
10678 if (CB->isIndirectCall())
10679 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10680 *this, getIRPosition(), DepClassTy::OPTIONAL))
10681 if (IndirectCallAA->foreachCallee(
10682 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10683 return Change;
10684
10685 // The most simple case.
10686 ProcessCalledOperand(CB->getCalledOperand(), CB);
10687
10688 // Process callback functions.
10689 SmallVector<const Use *, 4u> CallbackUses;
10690 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10691 for (const Use *U : CallbackUses)
10692 ProcessCalledOperand(U->get(), CB);
10693
10694 return Change;
10695 }
10696};
10697
10698struct AACallEdgesFunction : public AACallEdgesImpl {
10699 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10700 : AACallEdgesImpl(IRP, A) {}
10701
10702 /// See AbstractAttribute::updateImpl(...).
10703 ChangeStatus updateImpl(Attributor &A) override {
10704 ChangeStatus Change = ChangeStatus::UNCHANGED;
10705
10706 auto ProcessCallInst = [&](Instruction &Inst) {
10707 CallBase &CB = cast<CallBase>(Inst);
10708
10709 auto *CBEdges = A.getAAFor<AACallEdges>(
10710 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10711 if (!CBEdges)
10712 return false;
10713 if (CBEdges->hasNonAsmUnknownCallee())
10714 setHasUnknownCallee(true, Change);
10715 if (CBEdges->hasUnknownCallee())
10716 setHasUnknownCallee(false, Change);
10717
10718 for (Function *F : CBEdges->getOptimisticEdges())
10719 addCalledFunction(F, Change);
10720
10721 return true;
10722 };
10723
10724 // Visit all callable instructions.
10725 bool UsedAssumedInformation = false;
10726 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10727 UsedAssumedInformation,
10728 /* CheckBBLivenessOnly */ true)) {
10729 // If we haven't looked at all call like instructions, assume that there
10730 // are unknown callees.
10731 setHasUnknownCallee(true, Change);
10732 }
10733
10734 return Change;
10735 }
10736};
10737
10738/// -------------------AAInterFnReachability Attribute--------------------------
10739
10740struct AAInterFnReachabilityFunction
10741 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10742 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10743 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10744 : Base(IRP, A) {}
10745
10746 bool instructionCanReach(
10747 Attributor &A, const Instruction &From, const Function &To,
10748 const AA::InstExclusionSetTy *ExclusionSet) const override {
10749 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10750 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10751
10752 RQITy StackRQI(A, From, To, ExclusionSet, false);
10753 RQITy::Reachable Result;
10754 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10755 return NonConstThis->isReachableImpl(A, StackRQI,
10756 /*IsTemporaryRQI=*/true);
10757 return Result == RQITy::Reachable::Yes;
10758 }
10759
10760 bool isReachableImpl(Attributor &A, RQITy &RQI,
10761 bool IsTemporaryRQI) override {
10762 const Instruction *EntryI =
10763 &RQI.From->getFunction()->getEntryBlock().front();
10764 if (EntryI != RQI.From &&
10765 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10766 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10767 IsTemporaryRQI);
10768
10769 auto CheckReachableCallBase = [&](CallBase *CB) {
10770 auto *CBEdges = A.getAAFor<AACallEdges>(
10771 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10772 if (!CBEdges || !CBEdges->getState().isValidState())
10773 return false;
10774 // TODO Check To backwards in this case.
10775 if (CBEdges->hasUnknownCallee())
10776 return false;
10777
10778 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10779 if (Fn == RQI.To)
10780 return false;
10781
10782 if (Fn->isDeclaration()) {
10783 if (Fn->hasFnAttribute(Attribute::NoCallback))
10784 continue;
10785 // TODO Check To backwards in this case.
10786 return false;
10787 }
10788
10789 if (Fn == getAnchorScope()) {
10790 if (EntryI == RQI.From)
10791 continue;
10792 return false;
10793 }
10794
10795 const AAInterFnReachability *InterFnReachability =
10796 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10797 DepClassTy::OPTIONAL);
10798
10799 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10800 if (!InterFnReachability ||
10801 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10802 RQI.ExclusionSet))
10803 return false;
10804 }
10805 return true;
10806 };
10807
10808 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10809 *this, IRPosition::function(*RQI.From->getFunction()),
10810 DepClassTy::OPTIONAL);
10811
10812 // Determine call like instructions that we can reach from the inst.
10813 auto CheckCallBase = [&](Instruction &CBInst) {
10814 // There are usually less nodes in the call graph, check inter function
10815 // reachability first.
10816 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10817 return true;
10818 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10819 A, *RQI.From, CBInst, RQI.ExclusionSet);
10820 };
10821
10822 bool UsedExclusionSet = /* conservative */ true;
10823 bool UsedAssumedInformation = false;
10824 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10825 UsedAssumedInformation,
10826 /* CheckBBLivenessOnly */ true))
10827 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10828 IsTemporaryRQI);
10829
10830 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10831 IsTemporaryRQI);
10832 }
10833
10834 void trackStatistics() const override {}
10835};
10836} // namespace
10837
10838template <typename AAType>
10839static std::optional<Constant *>
10841 const IRPosition &IRP, Type &Ty) {
10842 if (!Ty.isIntegerTy())
10843 return nullptr;
10844
10845 // This will also pass the call base context.
10846 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10847 if (!AA)
10848 return nullptr;
10849
10850 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10851
10852 if (!COpt.has_value()) {
10853 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10854 return std::nullopt;
10855 }
10856 if (auto *C = *COpt) {
10857 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10858 return C;
10859 }
10860 return nullptr;
10861}
10862
10864 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10866 Type &Ty = *IRP.getAssociatedType();
10867 std::optional<Value *> V;
10868 for (auto &It : Values) {
10869 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10870 if (V.has_value() && !*V)
10871 break;
10872 }
10873 if (!V.has_value())
10874 return UndefValue::get(&Ty);
10875 return *V;
10876}
10877
10878namespace {
10879struct AAPotentialValuesImpl : AAPotentialValues {
10880 using StateType = PotentialLLVMValuesState;
10881
10882 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10883 : AAPotentialValues(IRP, A) {}
10884
10885 /// See AbstractAttribute::initialize(..).
10886 void initialize(Attributor &A) override {
10887 if (A.hasSimplificationCallback(getIRPosition())) {
10888 indicatePessimisticFixpoint();
10889 return;
10890 }
10891 Value *Stripped = getAssociatedValue().stripPointerCasts();
10892 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10893 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10894 getAnchorScope());
10895 indicateOptimisticFixpoint();
10896 return;
10897 }
10898 AAPotentialValues::initialize(A);
10899 }
10900
10901 /// See AbstractAttribute::getAsStr().
10902 const std::string getAsStr(Attributor *A) const override {
10903 std::string Str;
10904 llvm::raw_string_ostream OS(Str);
10905 OS << getState();
10906 return Str;
10907 }
10908
10909 template <typename AAType>
10910 static std::optional<Value *> askOtherAA(Attributor &A,
10911 const AbstractAttribute &AA,
10912 const IRPosition &IRP, Type &Ty) {
10914 return &IRP.getAssociatedValue();
10915 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10916 if (!C)
10917 return std::nullopt;
10918 if (*C)
10919 if (auto *CC = AA::getWithType(**C, Ty))
10920 return CC;
10921 return nullptr;
10922 }
10923
10924 virtual void addValue(Attributor &A, StateType &State, Value &V,
10925 const Instruction *CtxI, AA::ValueScope S,
10926 Function *AnchorScope) const {
10927
10928 IRPosition ValIRP = IRPosition::value(V);
10929 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10930 for (const auto &U : CB->args()) {
10931 if (U.get() != &V)
10932 continue;
10933 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10934 break;
10935 }
10936 }
10937
10938 Value *VPtr = &V;
10939 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10940 Type &Ty = *getAssociatedType();
10941 std::optional<Value *> SimpleV =
10942 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10943 if (SimpleV.has_value() && !*SimpleV) {
10944 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10945 *this, ValIRP, DepClassTy::OPTIONAL);
10946 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10947 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10948 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10949 if (PotentialConstantsAA->undefIsContained())
10950 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10951 return;
10952 }
10953 }
10954 if (!SimpleV.has_value())
10955 return;
10956
10957 if (*SimpleV)
10958 VPtr = *SimpleV;
10959 }
10960
10961 if (isa<ConstantInt>(VPtr))
10962 CtxI = nullptr;
10963 if (!AA::isValidInScope(*VPtr, AnchorScope))
10965
10966 State.unionAssumed({{*VPtr, CtxI}, S});
10967 }
10968
10969 /// Helper struct to tie a value+context pair together with the scope for
10970 /// which this is the simplified version.
10971 struct ItemInfo {
10972 AA::ValueAndContext I;
10974
10975 bool operator==(const ItemInfo &II) const {
10976 return II.I == I && II.S == S;
10977 };
10978 bool operator<(const ItemInfo &II) const {
10979 return std::tie(I, S) < std::tie(II.I, II.S);
10980 };
10981 };
10982
10983 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10984 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
10985 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10986 if (!(CS & S))
10987 continue;
10988
10989 bool UsedAssumedInformation = false;
10991 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10992 UsedAssumedInformation))
10993 return false;
10994
10995 for (auto &It : Values)
10996 ValueScopeMap[It] += CS;
10997 }
10998 for (auto &It : ValueScopeMap)
10999 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11000 AA::ValueScope(It.second), getAnchorScope());
11001
11002 return true;
11003 }
11004
11005 void giveUpOnIntraprocedural(Attributor &A) {
11006 auto NewS = StateType::getBestState(getState());
11007 for (const auto &It : getAssumedSet()) {
11008 if (It.second == AA::Intraprocedural)
11009 continue;
11010 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11011 AA::Interprocedural, getAnchorScope());
11012 }
11013 assert(!undefIsContained() && "Undef should be an explicit value!");
11014 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11015 getAnchorScope());
11016 getState() = NewS;
11017 }
11018
11019 /// See AbstractState::indicatePessimisticFixpoint(...).
11020 ChangeStatus indicatePessimisticFixpoint() override {
11021 getState() = StateType::getBestState(getState());
11022 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11023 AAPotentialValues::indicateOptimisticFixpoint();
11024 return ChangeStatus::CHANGED;
11025 }
11026
11027 /// See AbstractAttribute::updateImpl(...).
11028 ChangeStatus updateImpl(Attributor &A) override {
11029 return indicatePessimisticFixpoint();
11030 }
11031
11032 /// See AbstractAttribute::manifest(...).
11033 ChangeStatus manifest(Attributor &A) override {
11036 Values.clear();
11037 if (!getAssumedSimplifiedValues(A, Values, S))
11038 continue;
11039 Value &OldV = getAssociatedValue();
11040 if (isa<UndefValue>(OldV))
11041 continue;
11042 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11043 if (!NewV || NewV == &OldV)
11044 continue;
11045 if (getCtxI() &&
11046 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11047 continue;
11048 if (A.changeAfterManifest(getIRPosition(), *NewV))
11049 return ChangeStatus::CHANGED;
11050 }
11051 return ChangeStatus::UNCHANGED;
11052 }
11053
11054 bool getAssumedSimplifiedValues(
11055 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11056 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11057 if (!isValidState())
11058 return false;
11059 bool UsedAssumedInformation = false;
11060 for (const auto &It : getAssumedSet())
11061 if (It.second & S) {
11062 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11063 isa<SelectInst>(It.first.getValue()))) {
11064 if (A.getAssumedSimplifiedValues(
11065 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11066 this, Values, S, UsedAssumedInformation))
11067 continue;
11068 }
11069 Values.push_back(It.first);
11070 }
11071 assert(!undefIsContained() && "Undef should be an explicit value!");
11072 return true;
11073 }
11074};
11075
11076struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11077 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11078 : AAPotentialValuesImpl(IRP, A) {}
11079
11080 /// See AbstractAttribute::updateImpl(...).
11081 ChangeStatus updateImpl(Attributor &A) override {
11082 auto AssumedBefore = getAssumed();
11083
11084 genericValueTraversal(A, &getAssociatedValue());
11085
11086 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11087 : ChangeStatus::CHANGED;
11088 }
11089
11090 /// Helper struct to remember which AAIsDead instances we actually used.
11091 struct LivenessInfo {
11092 const AAIsDead *LivenessAA = nullptr;
11093 bool AnyDead = false;
11094 };
11095
11096 /// Check if \p Cmp is a comparison we can simplify.
11097 ///
11098 /// We handle multiple cases, one in which at least one operand is an
11099 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11100 /// operand. Return true if successful, in that case Worklist will be updated.
11101 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11102 CmpInst::Predicate Pred, ItemInfo II,
11103 SmallVectorImpl<ItemInfo> &Worklist) {
11104
11105 // Simplify the operands first.
11106 bool UsedAssumedInformation = false;
11107 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11108 auto GetSimplifiedValues = [&](Value &V,
11110 if (!A.getAssumedSimplifiedValues(
11111 IRPosition::value(V, getCallBaseContext()), this, Values,
11112 AA::Intraprocedural, UsedAssumedInformation)) {
11113 Values.clear();
11114 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11115 }
11116 return Values.empty();
11117 };
11118 if (GetSimplifiedValues(*LHS, LHSValues))
11119 return true;
11120 if (GetSimplifiedValues(*RHS, RHSValues))
11121 return true;
11122
11123 LLVMContext &Ctx = LHS->getContext();
11124
11125 InformationCache &InfoCache = A.getInfoCache();
11126 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11127 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11128 const auto *DT =
11129 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11130 : nullptr;
11131 const auto *TLI =
11132 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11133 auto *AC =
11134 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11135 : nullptr;
11136
11137 const DataLayout &DL = A.getDataLayout();
11138 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11139
11140 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11141 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11142 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11143 /* CtxI */ nullptr, II.S, getAnchorScope());
11144 return true;
11145 }
11146
11147 // Handle the trivial case first in which we don't even need to think
11148 // about null or non-null.
11149 if (&LHSV == &RHSV &&
11151 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11153 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11154 getAnchorScope());
11155 return true;
11156 }
11157
11158 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11159 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11160 if (TypedLHS && TypedRHS) {
11161 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11162 if (NewV && NewV != &Cmp) {
11163 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11164 getAnchorScope());
11165 return true;
11166 }
11167 }
11168
11169 // From now on we only handle equalities (==, !=).
11170 if (!CmpInst::isEquality(Pred))
11171 return false;
11172
11173 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11174 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11175 if (!LHSIsNull && !RHSIsNull)
11176 return false;
11177
11178 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11179 // non-nullptr operand and if we assume it's non-null we can conclude the
11180 // result of the comparison.
11181 assert((LHSIsNull || RHSIsNull) &&
11182 "Expected nullptr versus non-nullptr comparison at this point");
11183
11184 // The index is the operand that we assume is not null.
11185 unsigned PtrIdx = LHSIsNull;
11186 bool IsKnownNonNull;
11187 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11188 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11189 DepClassTy::REQUIRED, IsKnownNonNull);
11190 if (!IsAssumedNonNull)
11191 return false;
11192
11193 // The new value depends on the predicate, true for != and false for ==.
11194 Constant *NewV =
11195 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11196 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11197 getAnchorScope());
11198 return true;
11199 };
11200
11201 for (auto &LHSValue : LHSValues)
11202 for (auto &RHSValue : RHSValues)
11203 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11204 return false;
11205 return true;
11206 }
11207
11208 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11209 SmallVectorImpl<ItemInfo> &Worklist) {
11210 const Instruction *CtxI = II.I.getCtxI();
11211 bool UsedAssumedInformation = false;
11212
11213 std::optional<Constant *> C =
11214 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11215 bool NoValueYet = !C.has_value();
11216 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11217 return true;
11218 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11219 if (CI->isZero())
11220 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11221 else
11222 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11223 } else if (&SI == &getAssociatedValue()) {
11224 // We could not simplify the condition, assume both values.
11225 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11226 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11227 } else {
11228 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11229 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11230 if (!SimpleV.has_value())
11231 return true;
11232 if (*SimpleV) {
11233 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11234 return true;
11235 }
11236 return false;
11237 }
11238 return true;
11239 }
11240
11241 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11242 SmallVectorImpl<ItemInfo> &Worklist) {
11243 SmallSetVector<Value *, 4> PotentialCopies;
11244 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11245 bool UsedAssumedInformation = false;
11246 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11247 PotentialValueOrigins, *this,
11248 UsedAssumedInformation,
11249 /* OnlyExact */ true)) {
11250 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11251 "loaded values for load instruction "
11252 << LI << "\n");
11253 return false;
11254 }
11255
11256 // Do not simplify loads that are only used in llvm.assume if we cannot also
11257 // remove all stores that may feed into the load. The reason is that the
11258 // assume is probably worth something as long as the stores are around.
11259 InformationCache &InfoCache = A.getInfoCache();
11260 if (InfoCache.isOnlyUsedByAssume(LI)) {
11261 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11262 if (!I || isa<AssumeInst>(I))
11263 return true;
11264 if (auto *SI = dyn_cast<StoreInst>(I))
11265 return A.isAssumedDead(SI->getOperandUse(0), this,
11266 /* LivenessAA */ nullptr,
11267 UsedAssumedInformation,
11268 /* CheckBBLivenessOnly */ false);
11269 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11270 UsedAssumedInformation,
11271 /* CheckBBLivenessOnly */ false);
11272 })) {
11273 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11274 "and we cannot delete all the stores: "
11275 << LI << "\n");
11276 return false;
11277 }
11278 }
11279
11280 // Values have to be dynamically unique or we loose the fact that a
11281 // single llvm::Value might represent two runtime values (e.g.,
11282 // stack locations in different recursive calls).
11283 const Instruction *CtxI = II.I.getCtxI();
11284 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11285 bool AllLocal = ScopeIsLocal;
11286 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11287 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11288 return AA::isDynamicallyUnique(A, *this, *PC);
11289 });
11290 if (!DynamicallyUnique) {
11291 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11292 "values are dynamically unique: "
11293 << LI << "\n");
11294 return false;
11295 }
11296
11297 for (auto *PotentialCopy : PotentialCopies) {
11298 if (AllLocal) {
11299 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11300 } else {
11301 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11302 }
11303 }
11304 if (!AllLocal && ScopeIsLocal)
11305 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11306 return true;
11307 }
11308
11309 bool handlePHINode(
11310 Attributor &A, PHINode &PHI, ItemInfo II,
11311 SmallVectorImpl<ItemInfo> &Worklist,
11312 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11313 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11314 LivenessInfo &LI = LivenessAAs[&F];
11315 if (!LI.LivenessAA)
11316 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11317 DepClassTy::NONE);
11318 return LI;
11319 };
11320
11321 if (&PHI == &getAssociatedValue()) {
11322 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11323 const auto *CI =
11324 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11325 *PHI.getFunction());
11326
11327 Cycle *C = nullptr;
11328 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11329 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11330 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11331 if (LI.LivenessAA &&
11332 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11333 LI.AnyDead = true;
11334 continue;
11335 }
11336 Value *V = PHI.getIncomingValue(u);
11337 if (V == &PHI)
11338 continue;
11339
11340 // If the incoming value is not the PHI but an instruction in the same
11341 // cycle we might have multiple versions of it flying around.
11342 if (CyclePHI && isa<Instruction>(V) &&
11343 (!C || C->contains(cast<Instruction>(V)->getParent())))
11344 return false;
11345
11346 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11347 }
11348 return true;
11349 }
11350
11351 bool UsedAssumedInformation = false;
11352 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11353 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11354 if (!SimpleV.has_value())
11355 return true;
11356 if (!(*SimpleV))
11357 return false;
11358 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11359 return true;
11360 }
11361
11362 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11363 /// simplify any operand of the instruction \p I. Return true if successful,
11364 /// in that case Worklist will be updated.
11365 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11366 SmallVectorImpl<ItemInfo> &Worklist) {
11367 bool SomeSimplified = false;
11368 bool UsedAssumedInformation = false;
11369
11370 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11371 int Idx = 0;
11372 for (Value *Op : I.operands()) {
11373 const auto &SimplifiedOp = A.getAssumedSimplified(
11374 IRPosition::value(*Op, getCallBaseContext()), *this,
11375 UsedAssumedInformation, AA::Intraprocedural);
11376 // If we are not sure about any operand we are not sure about the entire
11377 // instruction, we'll wait.
11378 if (!SimplifiedOp.has_value())
11379 return true;
11380
11381 if (*SimplifiedOp)
11382 NewOps[Idx] = *SimplifiedOp;
11383 else
11384 NewOps[Idx] = Op;
11385
11386 SomeSimplified |= (NewOps[Idx] != Op);
11387 ++Idx;
11388 }
11389
11390 // We won't bother with the InstSimplify interface if we didn't simplify any
11391 // operand ourselves.
11392 if (!SomeSimplified)
11393 return false;
11394
11395 InformationCache &InfoCache = A.getInfoCache();
11396 Function *F = I.getFunction();
11397 const auto *DT =
11398 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11399 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11400 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11401
11402 const DataLayout &DL = I.getDataLayout();
11403 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11404 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11405 if (!NewV || NewV == &I)
11406 return false;
11407
11408 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11409 << *NewV << "\n");
11410 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11411 return true;
11412 }
11413
11415 Attributor &A, Instruction &I, ItemInfo II,
11416 SmallVectorImpl<ItemInfo> &Worklist,
11417 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11418 if (auto *CI = dyn_cast<CmpInst>(&I))
11419 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11420 CI->getPredicate(), II, Worklist);
11421
11422 switch (I.getOpcode()) {
11423 case Instruction::Select:
11424 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11425 case Instruction::PHI:
11426 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11427 case Instruction::Load:
11428 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11429 default:
11430 return handleGenericInst(A, I, II, Worklist);
11431 };
11432 return false;
11433 }
11434
11435 void genericValueTraversal(Attributor &A, Value *InitialV) {
11436 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11437
11438 SmallSet<ItemInfo, 16> Visited;
11440 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11441
11442 int Iteration = 0;
11443 do {
11444 ItemInfo II = Worklist.pop_back_val();
11445 Value *V = II.I.getValue();
11446 assert(V);
11447 const Instruction *CtxI = II.I.getCtxI();
11448 AA::ValueScope S = II.S;
11449
11450 // Check if we should process the current value. To prevent endless
11451 // recursion keep a record of the values we followed!
11452 if (!Visited.insert(II).second)
11453 continue;
11454
11455 // Make sure we limit the compile time for complex expressions.
11456 if (Iteration++ >= MaxPotentialValuesIterations) {
11457 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11458 << Iteration << "!\n");
11459 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11460 continue;
11461 }
11462
11463 // Explicitly look through calls with a "returned" attribute if we do
11464 // not have a pointer as stripPointerCasts only works on them.
11465 Value *NewV = nullptr;
11466 if (V->getType()->isPointerTy()) {
11467 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11468 } else {
11469 if (auto *CB = dyn_cast<CallBase>(V))
11470 if (auto *Callee =
11472 for (Argument &Arg : Callee->args())
11473 if (Arg.hasReturnedAttr()) {
11474 NewV = CB->getArgOperand(Arg.getArgNo());
11475 break;
11476 }
11477 }
11478 }
11479 if (NewV && NewV != V) {
11480 Worklist.push_back({{*NewV, CtxI}, S});
11481 continue;
11482 }
11483
11484 if (auto *I = dyn_cast<Instruction>(V)) {
11485 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11486 continue;
11487 }
11488
11489 if (V != InitialV || isa<Argument>(V))
11490 if (recurseForValue(A, IRPosition::value(*V), II.S))
11491 continue;
11492
11493 // If we haven't stripped anything we give up.
11494 if (V == InitialV && CtxI == getCtxI()) {
11495 indicatePessimisticFixpoint();
11496 return;
11497 }
11498
11499 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11500 } while (!Worklist.empty());
11501
11502 // If we actually used liveness information so we have to record a
11503 // dependence.
11504 for (auto &It : LivenessAAs)
11505 if (It.second.AnyDead)
11506 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11507 }
11508
11509 /// See AbstractAttribute::trackStatistics()
11510 void trackStatistics() const override {
11511 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11512 }
11513};
11514
11515struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11516 using Base = AAPotentialValuesImpl;
11517 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11518 : Base(IRP, A) {}
11519
11520 /// See AbstractAttribute::initialize(..).
11521 void initialize(Attributor &A) override {
11522 auto &Arg = cast<Argument>(getAssociatedValue());
11524 indicatePessimisticFixpoint();
11525 }
11526
11527 /// See AbstractAttribute::updateImpl(...).
11528 ChangeStatus updateImpl(Attributor &A) override {
11529 auto AssumedBefore = getAssumed();
11530
11531 unsigned ArgNo = getCalleeArgNo();
11532
11533 bool UsedAssumedInformation = false;
11535 auto CallSitePred = [&](AbstractCallSite ACS) {
11536 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11537 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11538 return false;
11539
11540 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11542 UsedAssumedInformation))
11543 return false;
11544
11545 return isValidState();
11546 };
11547
11548 if (!A.checkForAllCallSites(CallSitePred, *this,
11549 /* RequireAllCallSites */ true,
11550 UsedAssumedInformation))
11551 return indicatePessimisticFixpoint();
11552
11553 Function *Fn = getAssociatedFunction();
11554 bool AnyNonLocal = false;
11555 for (auto &It : Values) {
11556 if (isa<Constant>(It.getValue())) {
11557 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11558 getAnchorScope());
11559 continue;
11560 }
11561 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11562 return indicatePessimisticFixpoint();
11563
11564 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11565 if (Arg->getParent() == Fn) {
11566 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11567 getAnchorScope());
11568 continue;
11569 }
11570 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11571 getAnchorScope());
11572 AnyNonLocal = true;
11573 }
11574 assert(!undefIsContained() && "Undef should be an explicit value!");
11575 if (AnyNonLocal)
11576 giveUpOnIntraprocedural(A);
11577
11578 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11579 : ChangeStatus::CHANGED;
11580 }
11581
11582 /// See AbstractAttribute::trackStatistics()
11583 void trackStatistics() const override {
11584 STATS_DECLTRACK_ARG_ATTR(potential_values)
11585 }
11586};
11587
11588struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11589 using Base = AAPotentialValuesFloating;
11590 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11591 : Base(IRP, A) {}
11592
11593 /// See AbstractAttribute::initialize(..).
11594 void initialize(Attributor &A) override {
11595 Function *F = getAssociatedFunction();
11596 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11597 indicatePessimisticFixpoint();
11598 return;
11599 }
11600
11601 for (Argument &Arg : F->args())
11602 if (Arg.hasReturnedAttr()) {
11603 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11604 ReturnedArg = &Arg;
11605 break;
11606 }
11607 if (!A.isFunctionIPOAmendable(*F) ||
11608 A.hasSimplificationCallback(getIRPosition())) {
11609 if (!ReturnedArg)
11610 indicatePessimisticFixpoint();
11611 else
11612 indicateOptimisticFixpoint();
11613 }
11614 }
11615
11616 /// See AbstractAttribute::updateImpl(...).
11617 ChangeStatus updateImpl(Attributor &A) override {
11618 auto AssumedBefore = getAssumed();
11619 bool UsedAssumedInformation = false;
11620
11622 Function *AnchorScope = getAnchorScope();
11623 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11624 bool AddValues) {
11626 Values.clear();
11627 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11628 UsedAssumedInformation,
11629 /* RecurseForSelectAndPHI */ true))
11630 return false;
11631 if (!AddValues)
11632 continue;
11633
11634 bool AllInterAreIntra = false;
11635 if (S == AA::Interprocedural)
11636 AllInterAreIntra =
11637 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11638 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11639 });
11640
11641 for (const AA::ValueAndContext &VAC : Values) {
11642 addValue(A, getState(), *VAC.getValue(),
11643 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11644 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11645 }
11646 if (AllInterAreIntra)
11647 break;
11648 }
11649 return true;
11650 };
11651
11652 if (ReturnedArg) {
11653 HandleReturnedValue(*ReturnedArg, nullptr, true);
11654 } else {
11655 auto RetInstPred = [&](Instruction &RetI) {
11656 bool AddValues = true;
11657 if (isa<PHINode>(RetI.getOperand(0)) ||
11658 isa<SelectInst>(RetI.getOperand(0))) {
11659 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11660 AnchorScope);
11661 AddValues = false;
11662 }
11663 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11664 };
11665
11666 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11667 UsedAssumedInformation,
11668 /* CheckBBLivenessOnly */ true))
11669 return indicatePessimisticFixpoint();
11670 }
11671
11672 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11673 : ChangeStatus::CHANGED;
11674 }
11675
11676 ChangeStatus manifest(Attributor &A) override {
11677 if (ReturnedArg)
11678 return ChangeStatus::UNCHANGED;
11680 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11681 /* RecurseForSelectAndPHI */ true))
11682 return ChangeStatus::UNCHANGED;
11683 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11684 if (!NewVal)
11685 return ChangeStatus::UNCHANGED;
11686
11687 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11688 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11689 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11690 "Number of function with unique return");
11691 Changed |= A.manifestAttrs(
11693 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11694 STATS_DECLTRACK_ARG_ATTR(returned);
11695 }
11696
11697 auto RetInstPred = [&](Instruction &RetI) {
11698 Value *RetOp = RetI.getOperand(0);
11699 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11700 return true;
11701 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11702 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11703 Changed = ChangeStatus::CHANGED;
11704 return true;
11705 };
11706 bool UsedAssumedInformation = false;
11707 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11708 UsedAssumedInformation,
11709 /* CheckBBLivenessOnly */ true);
11710 return Changed;
11711 }
11712
11713 ChangeStatus indicatePessimisticFixpoint() override {
11714 return AAPotentialValues::indicatePessimisticFixpoint();
11715 }
11716
11717 /// See AbstractAttribute::trackStatistics()
11718 void trackStatistics() const override{
11719 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11720
11721 /// The argumented with an existing `returned` attribute.
11722 Argument *ReturnedArg = nullptr;
11723};
11724
11725struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11726 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11727 : AAPotentialValuesImpl(IRP, A) {}
11728
11729 /// See AbstractAttribute::updateImpl(...).
11730 ChangeStatus updateImpl(Attributor &A) override {
11731 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11732 "not be called");
11733 }
11734
11735 /// See AbstractAttribute::trackStatistics()
11736 void trackStatistics() const override {
11737 STATS_DECLTRACK_FN_ATTR(potential_values)
11738 }
11739};
11740
11741struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11742 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11743 : AAPotentialValuesFunction(IRP, A) {}
11744
11745 /// See AbstractAttribute::trackStatistics()
11746 void trackStatistics() const override {
11747 STATS_DECLTRACK_CS_ATTR(potential_values)
11748 }
11749};
11750
11751struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11752 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11753 : AAPotentialValuesImpl(IRP, A) {}
11754
11755 /// See AbstractAttribute::updateImpl(...).
11756 ChangeStatus updateImpl(Attributor &A) override {
11757 auto AssumedBefore = getAssumed();
11758
11759 Function *Callee = getAssociatedFunction();
11760 if (!Callee)
11761 return indicatePessimisticFixpoint();
11762
11763 bool UsedAssumedInformation = false;
11764 auto *CB = cast<CallBase>(getCtxI());
11765 if (CB->isMustTailCall() &&
11766 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11767 UsedAssumedInformation))
11768 return indicatePessimisticFixpoint();
11769
11770 Function *Caller = CB->getCaller();
11771
11772 auto AddScope = [&](AA::ValueScope S) {
11774 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11775 Values, S, UsedAssumedInformation))
11776 return false;
11777
11778 for (auto &It : Values) {
11779 Value *V = It.getValue();
11780 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11781 V, *CB, *this, UsedAssumedInformation);
11782 if (!CallerV.has_value()) {
11783 // Nothing to do as long as no value was determined.
11784 continue;
11785 }
11786 V = *CallerV ? *CallerV : V;
11787 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11788 if (recurseForValue(A, IRPosition::value(*V), S))
11789 continue;
11790 }
11791 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11792 giveUpOnIntraprocedural(A);
11793 return true;
11794 }
11795 addValue(A, getState(), *V, CB, S, getAnchorScope());
11796 }
11797 return true;
11798 };
11799 if (!AddScope(AA::Intraprocedural))
11800 return indicatePessimisticFixpoint();
11801 if (!AddScope(AA::Interprocedural))
11802 return indicatePessimisticFixpoint();
11803 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11804 : ChangeStatus::CHANGED;
11805 }
11806
11807 ChangeStatus indicatePessimisticFixpoint() override {
11808 return AAPotentialValues::indicatePessimisticFixpoint();
11809 }
11810
11811 /// See AbstractAttribute::trackStatistics()
11812 void trackStatistics() const override {
11813 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11814 }
11815};
11816
11817struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11818 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11819 : AAPotentialValuesFloating(IRP, A) {}
11820
11821 /// See AbstractAttribute::trackStatistics()
11822 void trackStatistics() const override {
11823 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11824 }
11825};
11826} // namespace
11827
11828/// ---------------------- Assumption Propagation ------------------------------
11829namespace {
11830struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11831 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11832 const DenseSet<StringRef> &Known)
11833 : AAAssumptionInfo(IRP, A, Known) {}
11834
11835 /// See AbstractAttribute::manifest(...).
11836 ChangeStatus manifest(Attributor &A) override {
11837 // Don't manifest a universal set if it somehow made it here.
11838 if (getKnown().isUniversal())
11839 return ChangeStatus::UNCHANGED;
11840
11841 const IRPosition &IRP = getIRPosition();
11842 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11843 getAssumed().getSet().end());
11844 llvm::sort(Set);
11845 return A.manifestAttrs(IRP,
11846 Attribute::get(IRP.getAnchorValue().getContext(),
11848 llvm::join(Set, ",")),
11849 /*ForceReplace=*/true);
11850 }
11851
11852 bool hasAssumption(const StringRef Assumption) const override {
11853 return isValidState() && setContains(Assumption);
11854 }
11855
11856 /// See AbstractAttribute::getAsStr()
11857 const std::string getAsStr(Attributor *A) const override {
11858 const SetContents &Known = getKnown();
11859 const SetContents &Assumed = getAssumed();
11860
11861 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11862 llvm::sort(Set);
11863 const std::string KnownStr = llvm::join(Set, ",");
11864
11865 std::string AssumedStr = "Universal";
11866 if (!Assumed.isUniversal()) {
11867 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11868 AssumedStr = llvm::join(Set, ",");
11869 }
11870 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11871 }
11872};
11873
11874/// Propagates assumption information from parent functions to all of their
11875/// successors. An assumption can be propagated if the containing function
11876/// dominates the called function.
11877///
11878/// We start with a "known" set of assumptions already valid for the associated
11879/// function and an "assumed" set that initially contains all possible
11880/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11881/// contents as concrete values are known. The concrete values are seeded by the
11882/// first nodes that are either entries into the call graph, or contains no
11883/// assumptions. Each node is updated as the intersection of the assumed state
11884/// with all of its predecessors.
11885struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11886 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11887 : AAAssumptionInfoImpl(IRP, A,
11888 getAssumptions(*IRP.getAssociatedFunction())) {}
11889
11890 /// See AbstractAttribute::updateImpl(...).
11891 ChangeStatus updateImpl(Attributor &A) override {
11892 bool Changed = false;
11893
11894 auto CallSitePred = [&](AbstractCallSite ACS) {
11895 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11896 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11897 DepClassTy::REQUIRED);
11898 if (!AssumptionAA)
11899 return false;
11900 // Get the set of assumptions shared by all of this function's callers.
11901 Changed |= getIntersection(AssumptionAA->getAssumed());
11902 return !getAssumed().empty() || !getKnown().empty();
11903 };
11904
11905 bool UsedAssumedInformation = false;
11906 // Get the intersection of all assumptions held by this node's predecessors.
11907 // If we don't know all the call sites then this is either an entry into the
11908 // call graph or an empty node. This node is known to only contain its own
11909 // assumptions and can be propagated to its successors.
11910 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11911 UsedAssumedInformation))
11912 return indicatePessimisticFixpoint();
11913
11914 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11915 }
11916
11917 void trackStatistics() const override {}
11918};
11919
11920/// Assumption Info defined for call sites.
11921struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11922
11923 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11924 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11925
11926 /// See AbstractAttribute::initialize(...).
11927 void initialize(Attributor &A) override {
11928 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11929 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11930 }
11931
11932 /// See AbstractAttribute::updateImpl(...).
11933 ChangeStatus updateImpl(Attributor &A) override {
11934 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11935 auto *AssumptionAA =
11936 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11937 if (!AssumptionAA)
11938 return indicatePessimisticFixpoint();
11939 bool Changed = getIntersection(AssumptionAA->getAssumed());
11940 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11941 }
11942
11943 /// See AbstractAttribute::trackStatistics()
11944 void trackStatistics() const override {}
11945
11946private:
11947 /// Helper to initialized the known set as all the assumptions this call and
11948 /// the callee contain.
11949 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11950 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11951 auto Assumptions = getAssumptions(CB);
11952 if (const Function *F = CB.getCaller())
11953 set_union(Assumptions, getAssumptions(*F));
11954 if (Function *F = IRP.getAssociatedFunction())
11955 set_union(Assumptions, getAssumptions(*F));
11956 return Assumptions;
11957 }
11958};
11959} // namespace
11960
11962 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11963 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11964}
11965
11967
11968/// ------------------------ UnderlyingObjects ---------------------------------
11969
11970namespace {
11971struct AAUnderlyingObjectsImpl
11972 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11974 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11975
11976 /// See AbstractAttribute::getAsStr().
11977 const std::string getAsStr(Attributor *A) const override {
11978 if (!isValidState())
11979 return "<invalid>";
11980 std::string Str;
11982 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
11983 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
11984 << " objects.\n";
11985 if (!InterAssumedUnderlyingObjects.empty()) {
11986 OS << "inter objects:\n";
11987 for (auto *Obj : InterAssumedUnderlyingObjects)
11988 OS << *Obj << '\n';
11989 }
11990 if (!IntraAssumedUnderlyingObjects.empty()) {
11991 OS << "intra objects:\n";
11992 for (auto *Obj : IntraAssumedUnderlyingObjects)
11993 OS << *Obj << '\n';
11994 }
11995 return Str;
11996 }
11997
11998 /// See AbstractAttribute::trackStatistics()
11999 void trackStatistics() const override {}
12000
12001 /// See AbstractAttribute::updateImpl(...).
12002 ChangeStatus updateImpl(Attributor &A) override {
12003 auto &Ptr = getAssociatedValue();
12004
12005 bool UsedAssumedInformation = false;
12006 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12008 SmallPtrSet<Value *, 8> SeenObjects;
12010
12011 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12012 Scope, UsedAssumedInformation))
12013 return UnderlyingObjects.insert(&Ptr);
12014
12015 bool Changed = false;
12016
12017 for (unsigned I = 0; I < Values.size(); ++I) {
12018 auto &VAC = Values[I];
12019 auto *Obj = VAC.getValue();
12020 Value *UO = getUnderlyingObject(Obj);
12021 if (!SeenObjects.insert(UO ? UO : Obj).second)
12022 continue;
12023 if (UO && UO != Obj) {
12024 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12025 Changed |= UnderlyingObjects.insert(UO);
12026 continue;
12027 }
12028
12029 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12030 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12031 auto Pred = [&](Value &V) {
12032 if (&V == UO)
12033 Changed |= UnderlyingObjects.insert(UO);
12034 else
12035 Values.emplace_back(V, nullptr);
12036 return true;
12037 };
12038
12039 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12041 "The forall call should not return false at this position");
12042 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12043 continue;
12044 }
12045
12046 if (isa<SelectInst>(Obj)) {
12047 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12048 UsedAssumedInformation);
12049 continue;
12050 }
12051 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12052 // Explicitly look through PHIs as we do not care about dynamically
12053 // uniqueness.
12054 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12055 Changed |=
12056 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12057 Scope, UsedAssumedInformation);
12058 }
12059 continue;
12060 }
12061
12062 Changed |= UnderlyingObjects.insert(Obj);
12063 }
12064
12065 return Changed;
12066 };
12067
12068 bool Changed = false;
12069 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12070 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12071 if (!UsedAssumedInformation)
12072 indicateOptimisticFixpoint();
12073 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12074 }
12075
12076 bool forallUnderlyingObjects(
12077 function_ref<bool(Value &)> Pred,
12078 AA::ValueScope Scope = AA::Interprocedural) const override {
12079 if (!isValidState())
12080 return Pred(getAssociatedValue());
12081
12082 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12083 ? IntraAssumedUnderlyingObjects
12084 : InterAssumedUnderlyingObjects;
12085 for (Value *Obj : AssumedUnderlyingObjects)
12086 if (!Pred(*Obj))
12087 return false;
12088
12089 return true;
12090 }
12091
12092private:
12093 /// Handle the case where the value is not the actual underlying value, such
12094 /// as a phi node or a select instruction.
12095 bool handleIndirect(Attributor &A, Value &V,
12096 SmallSetVector<Value *, 8> &UnderlyingObjects,
12097 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12098 bool Changed = false;
12099 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12100 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12101 auto Pred = [&](Value &V) {
12102 Changed |= UnderlyingObjects.insert(&V);
12103 return true;
12104 };
12105 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12107 "The forall call should not return false at this position");
12108 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12109 return Changed;
12110 }
12111
12112 /// All the underlying objects collected so far via intra procedural scope.
12113 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12114 /// All the underlying objects collected so far via inter procedural scope.
12115 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12116};
12117
12118struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12119 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12120 : AAUnderlyingObjectsImpl(IRP, A) {}
12121};
12122
12123struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12124 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12125 : AAUnderlyingObjectsImpl(IRP, A) {}
12126};
12127
12128struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12129 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12130 : AAUnderlyingObjectsImpl(IRP, A) {}
12131};
12132
12133struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12134 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12135 : AAUnderlyingObjectsImpl(IRP, A) {}
12136};
12137
12138struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12139 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12140 : AAUnderlyingObjectsImpl(IRP, A) {}
12141};
12142
12143struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12144 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12145 : AAUnderlyingObjectsImpl(IRP, A) {}
12146};
12147
12148struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12149 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12150 : AAUnderlyingObjectsImpl(IRP, A) {}
12151};
12152} // namespace
12153
12154/// ------------------------ Global Value Info -------------------------------
12155namespace {
12156struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12157 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12158 : AAGlobalValueInfo(IRP, A) {}
12159
12160 /// See AbstractAttribute::initialize(...).
12161 void initialize(Attributor &A) override {}
12162
12163 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12164 SmallVectorImpl<const Value *> &Worklist) {
12165 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12166 if (!UInst) {
12167 Follow = true;
12168 return true;
12169 }
12170
12171 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12172 << *UInst << "\n");
12173
12174 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12175 int Idx = &Cmp->getOperandUse(0) == &U;
12176 if (isa<Constant>(Cmp->getOperand(Idx)))
12177 return true;
12178 return U == &getAnchorValue();
12179 }
12180
12181 // Explicitly catch return instructions.
12182 if (isa<ReturnInst>(UInst)) {
12183 auto CallSitePred = [&](AbstractCallSite ACS) {
12184 Worklist.push_back(ACS.getInstruction());
12185 return true;
12186 };
12187 bool UsedAssumedInformation = false;
12188 // TODO: We should traverse the uses or add a "non-call-site" CB.
12189 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12190 /*RequireAllCallSites=*/true, this,
12191 UsedAssumedInformation))
12192 return false;
12193 return true;
12194 }
12195
12196 // For now we only use special logic for call sites. However, the tracker
12197 // itself knows about a lot of other non-capturing cases already.
12198 auto *CB = dyn_cast<CallBase>(UInst);
12199 if (!CB)
12200 return false;
12201 // Direct calls are OK uses.
12202 if (CB->isCallee(&U))
12203 return true;
12204 // Non-argument uses are scary.
12205 if (!CB->isArgOperand(&U))
12206 return false;
12207 // TODO: Iterate callees.
12208 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12209 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12210 return false;
12211
12212 unsigned ArgNo = CB->getArgOperandNo(&U);
12213 Worklist.push_back(Fn->getArg(ArgNo));
12214 return true;
12215 }
12216
12217 ChangeStatus updateImpl(Attributor &A) override {
12218 unsigned NumUsesBefore = Uses.size();
12219
12220 SmallPtrSet<const Value *, 8> Visited;
12222 Worklist.push_back(&getAnchorValue());
12223
12224 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12225 Uses.insert(&U);
12226 // TODO(captures): Make this more precise.
12227 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12228 if (CI.isPassthrough()) {
12229 Follow = true;
12230 return true;
12231 }
12232 return checkUse(A, U, Follow, Worklist);
12233 };
12234 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12235 Uses.insert(&OldU);
12236 return true;
12237 };
12238
12239 while (!Worklist.empty()) {
12240 const Value *V = Worklist.pop_back_val();
12241 if (!Visited.insert(V).second)
12242 continue;
12243 if (!A.checkForAllUses(UsePred, *this, *V,
12244 /* CheckBBLivenessOnly */ true,
12245 DepClassTy::OPTIONAL,
12246 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12247 return indicatePessimisticFixpoint();
12248 }
12249 }
12250
12251 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12252 : ChangeStatus::CHANGED;
12253 }
12254
12255 bool isPotentialUse(const Use &U) const override {
12256 return !isValidState() || Uses.contains(&U);
12257 }
12258
12259 /// See AbstractAttribute::manifest(...).
12260 ChangeStatus manifest(Attributor &A) override {
12261 return ChangeStatus::UNCHANGED;
12262 }
12263
12264 /// See AbstractAttribute::getAsStr().
12265 const std::string getAsStr(Attributor *A) const override {
12266 return "[" + std::to_string(Uses.size()) + " uses]";
12267 }
12268
12269 void trackStatistics() const override {
12270 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12271 }
12272
12273private:
12274 /// Set of (transitive) uses of this GlobalValue.
12275 SmallPtrSet<const Use *, 8> Uses;
12276};
12277} // namespace
12278
12279/// ------------------------ Indirect Call Info -------------------------------
12280namespace {
12281struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12282 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12283 : AAIndirectCallInfo(IRP, A) {}
12284
12285 /// See AbstractAttribute::initialize(...).
12286 void initialize(Attributor &A) override {
12287 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12288 if (!MD && !A.isClosedWorldModule())
12289 return;
12290
12291 if (MD) {
12292 for (const auto &Op : MD->operands())
12293 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12294 PotentialCallees.insert(Callee);
12295 } else if (A.isClosedWorldModule()) {
12296 ArrayRef<Function *> IndirectlyCallableFunctions =
12297 A.getInfoCache().getIndirectlyCallableFunctions(A);
12298 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12299 }
12300
12301 if (PotentialCallees.empty())
12302 indicateOptimisticFixpoint();
12303 }
12304
12305 ChangeStatus updateImpl(Attributor &A) override {
12306 CallBase *CB = cast<CallBase>(getCtxI());
12307 const Use &CalleeUse = CB->getCalledOperandUse();
12308 Value *FP = CB->getCalledOperand();
12309
12310 SmallSetVector<Function *, 4> AssumedCalleesNow;
12311 bool AllCalleesKnownNow = AllCalleesKnown;
12312
12313 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12314 bool &UsedAssumedInformation) {
12315 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12316 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12317 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12318 return true;
12319 UsedAssumedInformation = !GIAA->isAtFixpoint();
12320 return false;
12321 };
12322
12323 auto AddPotentialCallees = [&]() {
12324 for (auto *PotentialCallee : PotentialCallees) {
12325 bool UsedAssumedInformation = false;
12326 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12327 AssumedCalleesNow.insert(PotentialCallee);
12328 }
12329 };
12330
12331 // Use simplification to find potential callees, if !callees was present,
12332 // fallback to that set if necessary.
12333 bool UsedAssumedInformation = false;
12335 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12336 AA::ValueScope::AnyScope,
12337 UsedAssumedInformation)) {
12338 if (PotentialCallees.empty())
12339 return indicatePessimisticFixpoint();
12340 AddPotentialCallees();
12341 }
12342
12343 // Try to find a reason for \p Fn not to be a potential callee. If none was
12344 // found, add it to the assumed callees set.
12345 auto CheckPotentialCallee = [&](Function &Fn) {
12346 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12347 return false;
12348
12349 auto &CachedResult = FilterResults[&Fn];
12350 if (CachedResult.has_value())
12351 return CachedResult.value();
12352
12353 bool UsedAssumedInformation = false;
12354 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12355 if (!UsedAssumedInformation)
12356 CachedResult = false;
12357 return false;
12358 }
12359
12360 int NumFnArgs = Fn.arg_size();
12361 int NumCBArgs = CB->arg_size();
12362
12363 // Check if any excess argument (which we fill up with poison) is known to
12364 // be UB on undef.
12365 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12366 bool IsKnown = false;
12368 A, this, IRPosition::argument(*Fn.getArg(I)),
12369 DepClassTy::OPTIONAL, IsKnown)) {
12370 if (IsKnown)
12371 CachedResult = false;
12372 return false;
12373 }
12374 }
12375
12376 CachedResult = true;
12377 return true;
12378 };
12379
12380 // Check simplification result, prune known UB callees, also restrict it to
12381 // the !callees set, if present.
12382 for (auto &VAC : Values) {
12383 if (isa<UndefValue>(VAC.getValue()))
12384 continue;
12386 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12387 continue;
12388 // TODO: Check for known UB, e.g., poison + noundef.
12389 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12390 if (CheckPotentialCallee(*VACFn))
12391 AssumedCalleesNow.insert(VACFn);
12392 continue;
12393 }
12394 if (!PotentialCallees.empty()) {
12395 AddPotentialCallees();
12396 break;
12397 }
12398 AllCalleesKnownNow = false;
12399 }
12400
12401 if (AssumedCalleesNow == AssumedCallees &&
12402 AllCalleesKnown == AllCalleesKnownNow)
12403 return ChangeStatus::UNCHANGED;
12404
12405 std::swap(AssumedCallees, AssumedCalleesNow);
12406 AllCalleesKnown = AllCalleesKnownNow;
12407 return ChangeStatus::CHANGED;
12408 }
12409
12410 /// See AbstractAttribute::manifest(...).
12411 ChangeStatus manifest(Attributor &A) override {
12412 // If we can't specialize at all, give up now.
12413 if (!AllCalleesKnown && AssumedCallees.empty())
12414 return ChangeStatus::UNCHANGED;
12415
12416 CallBase *CB = cast<CallBase>(getCtxI());
12417 bool UsedAssumedInformation = false;
12418 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12419 UsedAssumedInformation))
12420 return ChangeStatus::UNCHANGED;
12421
12422 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12423 Value *FP = CB->getCalledOperand();
12424 if (FP->getType()->getPointerAddressSpace())
12425 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12426 FP->getName() + ".as0", CB->getIterator());
12427
12428 bool CBIsVoid = CB->getType()->isVoidTy();
12430 FunctionType *CSFT = CB->getFunctionType();
12431 SmallVector<Value *> CSArgs(CB->args());
12432
12433 // If we know all callees and there are none, the call site is (effectively)
12434 // dead (or UB).
12435 if (AssumedCallees.empty()) {
12436 assert(AllCalleesKnown &&
12437 "Expected all callees to be known if there are none.");
12438 A.changeToUnreachableAfterManifest(CB);
12439 return ChangeStatus::CHANGED;
12440 }
12441
12442 // Special handling for the single callee case.
12443 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12444 auto *NewCallee = AssumedCallees.front();
12445 if (isLegalToPromote(*CB, NewCallee)) {
12446 promoteCall(*CB, NewCallee, nullptr);
12447 NumIndirectCallsPromoted++;
12448 return ChangeStatus::CHANGED;
12449 }
12450 Instruction *NewCall =
12451 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12452 CB->getName(), CB->getIterator());
12453 if (!CBIsVoid)
12454 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12455 A.deleteAfterManifest(*CB);
12456 return ChangeStatus::CHANGED;
12457 }
12458
12459 // For each potential value we create a conditional
12460 //
12461 // ```
12462 // if (ptr == value) value(args);
12463 // else ...
12464 // ```
12465 //
12466 bool SpecializedForAnyCallees = false;
12467 bool SpecializedForAllCallees = AllCalleesKnown;
12468 ICmpInst *LastCmp = nullptr;
12469 SmallVector<Function *, 8> SkippedAssumedCallees;
12471 for (Function *NewCallee : AssumedCallees) {
12472 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12473 AssumedCallees.size())) {
12474 SkippedAssumedCallees.push_back(NewCallee);
12475 SpecializedForAllCallees = false;
12476 continue;
12477 }
12478 SpecializedForAnyCallees = true;
12479
12480 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12481 Instruction *ThenTI =
12482 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12483 BasicBlock *CBBB = CB->getParent();
12484 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12485 A.registerManifestAddedBasicBlock(*IP->getParent());
12486 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12487 BasicBlock *ElseBB;
12488 if (&*IP == CB) {
12489 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12490 ThenTI->getFunction(), CBBB);
12491 A.registerManifestAddedBasicBlock(*ElseBB);
12492 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12493 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12494 } else {
12495 ElseBB = IP->getParent();
12496 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12497 }
12498 CastInst *RetBC = nullptr;
12499 CallInst *NewCall = nullptr;
12500 if (isLegalToPromote(*CB, NewCallee)) {
12501 auto *CBClone = cast<CallBase>(CB->clone());
12502 CBClone->insertBefore(ThenTI->getIterator());
12503 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12504 NumIndirectCallsPromoted++;
12505 } else {
12506 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12507 CB->getName(), ThenTI->getIterator());
12508 }
12509 NewCalls.push_back({NewCall, RetBC});
12510 }
12511
12512 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12513 if (!AllCalleesKnown)
12514 return ChangeStatus::UNCHANGED;
12515 MDBuilder MDB(IndirectCB.getContext());
12516 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12517 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12518 return ChangeStatus::CHANGED;
12519 };
12520
12521 if (!SpecializedForAnyCallees)
12522 return AttachCalleeMetadata(*CB);
12523
12524 // Check if we need the fallback indirect call still.
12525 if (SpecializedForAllCallees) {
12527 LastCmp->eraseFromParent();
12528 new UnreachableInst(IP->getContext(), IP);
12529 IP->eraseFromParent();
12530 } else {
12531 auto *CBClone = cast<CallInst>(CB->clone());
12532 CBClone->setName(CB->getName());
12533 CBClone->insertBefore(*IP->getParent(), IP);
12534 NewCalls.push_back({CBClone, nullptr});
12535 AttachCalleeMetadata(*CBClone);
12536 }
12537
12538 // Check if we need a PHI to merge the results.
12539 if (!CBIsVoid) {
12540 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12541 CB->getName() + ".phi",
12542 CB->getParent()->getFirstInsertionPt());
12543 for (auto &It : NewCalls) {
12544 CallBase *NewCall = It.first;
12545 Instruction *CallRet = It.second ? It.second : It.first;
12546 if (CallRet->getType() == CB->getType())
12547 PHI->addIncoming(CallRet, CallRet->getParent());
12548 else if (NewCall->getType()->isVoidTy())
12549 PHI->addIncoming(PoisonValue::get(CB->getType()),
12550 NewCall->getParent());
12551 else
12552 llvm_unreachable("Call return should match or be void!");
12553 }
12554 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12555 }
12556
12557 A.deleteAfterManifest(*CB);
12558 Changed = ChangeStatus::CHANGED;
12559
12560 return Changed;
12561 }
12562
12563 /// See AbstractAttribute::getAsStr().
12564 const std::string getAsStr(Attributor *A) const override {
12565 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12566 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12567 " functions";
12568 }
12569
12570 void trackStatistics() const override {
12571 if (AllCalleesKnown) {
12573 Eliminated, CallSites,
12574 "Number of indirect call sites eliminated via specialization")
12575 } else {
12576 STATS_DECLTRACK(Specialized, CallSites,
12577 "Number of indirect call sites specialized")
12578 }
12579 }
12580
12581 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12582 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12583 }
12584
12585private:
12586 /// Map to remember filter results.
12587 DenseMap<Function *, std::optional<bool>> FilterResults;
12588
12589 /// If the !callee metadata was present, this set will contain all potential
12590 /// callees (superset).
12591 SmallSetVector<Function *, 4> PotentialCallees;
12592
12593 /// This set contains all currently assumed calllees, which might grow over
12594 /// time.
12595 SmallSetVector<Function *, 4> AssumedCallees;
12596
12597 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12598 /// if there could be others.
12599 bool AllCalleesKnown = true;
12600};
12601} // namespace
12602
12603/// --------------------- Invariant Load Pointer -------------------------------
12604namespace {
12605
12606struct AAInvariantLoadPointerImpl
12607 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12608 AAInvariantLoadPointer> {
12609
12610 enum {
12611 // pointer does not alias within the bounds of the function
12612 IS_NOALIAS = 1 << 0,
12613 // pointer is not involved in any effectful instructions within the bounds
12614 // of the function
12615 IS_NOEFFECT = 1 << 1,
12616 // loads are invariant within the bounds of the function
12617 IS_LOCALLY_INVARIANT = 1 << 2,
12618 // memory lifetime is constrained within the bounds of the function
12619 IS_LOCALLY_CONSTRAINED = 1 << 3,
12620
12621 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12622 IS_LOCALLY_CONSTRAINED,
12623 };
12624 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12625
12626 using Base =
12627 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12628
12629 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12630 // pessimistic about IS_KNOWN_INVARIANT
12631 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12632 : Base(IRP) {}
12633
12634 bool isKnownInvariant() const final {
12635 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12636 }
12637
12638 bool isKnownLocallyInvariant() const final {
12639 if (isKnown(IS_LOCALLY_INVARIANT))
12640 return true;
12641 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12642 }
12643
12644 bool isAssumedInvariant() const final {
12645 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12646 }
12647
12648 bool isAssumedLocallyInvariant() const final {
12649 if (isAssumed(IS_LOCALLY_INVARIANT))
12650 return true;
12651 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12652 }
12653
12654 ChangeStatus updateImpl(Attributor &A) override {
12655 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12656
12657 Changed |= updateNoAlias(A);
12658 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12659 return indicatePessimisticFixpoint();
12660
12661 Changed |= updateNoEffect(A);
12662
12663 Changed |= updateLocalInvariance(A);
12664
12665 return Changed;
12666 }
12667
12668 ChangeStatus manifest(Attributor &A) override {
12669 if (!isKnownInvariant())
12670 return ChangeStatus::UNCHANGED;
12671
12672 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12673 const Value *Ptr = &getAssociatedValue();
12674 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12675 if (U.get() != Ptr)
12676 return true;
12677 auto *I = dyn_cast<Instruction>(U.getUser());
12678 if (!I)
12679 return true;
12680
12681 // Ensure that we are only changing uses from the corresponding callgraph
12682 // SSC in the case that the AA isn't run on the entire module
12683 if (!A.isRunOn(I->getFunction()))
12684 return true;
12685
12686 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12687 return true;
12688
12689 if (auto *LI = dyn_cast<LoadInst>(I)) {
12690 LI->setMetadata(LLVMContext::MD_invariant_load,
12691 MDNode::get(LI->getContext(), {}));
12692 Changed = ChangeStatus::CHANGED;
12693 }
12694 return true;
12695 };
12696
12697 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12698 return Changed;
12699 }
12700
12701 /// See AbstractAttribute::getAsStr().
12702 const std::string getAsStr(Attributor *) const override {
12703 if (isKnownInvariant())
12704 return "load-invariant pointer";
12705 return "non-invariant pointer";
12706 }
12707
12708 /// See AbstractAttribute::trackStatistics().
12709 void trackStatistics() const override {}
12710
12711private:
12712 /// Indicate that noalias is required for the pointer to be invariant.
12713 bool requiresNoAlias() const {
12714 switch (getPositionKind()) {
12715 default:
12716 // Conservatively default to require noalias.
12717 return true;
12718 case IRP_FLOAT:
12719 case IRP_RETURNED:
12720 case IRP_CALL_SITE:
12721 return false;
12722 case IRP_CALL_SITE_RETURNED: {
12723 const auto &CB = cast<CallBase>(getAnchorValue());
12725 &CB, /*MustPreserveNullness=*/false);
12726 }
12727 case IRP_ARGUMENT: {
12728 const Function *F = getAssociatedFunction();
12729 assert(F && "no associated function for argument");
12730 return !isCallableCC(F->getCallingConv());
12731 }
12732 }
12733 }
12734
12735 bool isExternal() const {
12736 const Function *F = getAssociatedFunction();
12737 if (!F)
12738 return true;
12739 return isCallableCC(F->getCallingConv()) &&
12740 getPositionKind() != IRP_CALL_SITE_RETURNED;
12741 }
12742
12743 ChangeStatus updateNoAlias(Attributor &A) {
12744 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12745 return ChangeStatus::UNCHANGED;
12746
12747 // Try to use AANoAlias.
12748 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12749 getIRPosition(), this, DepClassTy::REQUIRED)) {
12750 if (ANoAlias->isKnownNoAlias()) {
12751 addKnownBits(IS_NOALIAS);
12752 return ChangeStatus::CHANGED;
12753 }
12754
12755 if (!ANoAlias->isAssumedNoAlias()) {
12756 removeAssumedBits(IS_NOALIAS);
12757 return ChangeStatus::CHANGED;
12758 }
12759
12760 return ChangeStatus::UNCHANGED;
12761 }
12762
12763 // Try to infer noalias from argument attribute, since it is applicable for
12764 // the duration of the function.
12765 if (const Argument *Arg = getAssociatedArgument()) {
12766 if (Arg->hasNoAliasAttr()) {
12767 addKnownBits(IS_NOALIAS);
12768 return ChangeStatus::UNCHANGED;
12769 }
12770
12771 // Noalias information is not provided, and cannot be inferred,
12772 // so we conservatively assume the pointer aliases.
12773 removeAssumedBits(IS_NOALIAS);
12774 return ChangeStatus::CHANGED;
12775 }
12776
12777 return ChangeStatus::UNCHANGED;
12778 }
12779
12780 ChangeStatus updateNoEffect(Attributor &A) {
12781 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12782 return ChangeStatus::UNCHANGED;
12783
12784 if (!getAssociatedFunction())
12785 return indicatePessimisticFixpoint();
12786
12787 if (isa<AllocaInst>(&getAssociatedValue()))
12788 return indicatePessimisticFixpoint();
12789
12790 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12791 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12792 return !LI || !LI->mayHaveSideEffects();
12793 };
12794 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12795 return indicatePessimisticFixpoint();
12796
12797 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12798 getIRPosition(), this, DepClassTy::REQUIRED)) {
12799 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12800 // attribute
12801 if (!AMemoryBehavior->isAssumedReadOnly())
12802 return indicatePessimisticFixpoint();
12803
12804 if (AMemoryBehavior->isKnownReadOnly()) {
12805 addKnownBits(IS_NOEFFECT);
12806 return ChangeStatus::UNCHANGED;
12807 }
12808
12809 return ChangeStatus::UNCHANGED;
12810 }
12811
12812 if (const Argument *Arg = getAssociatedArgument()) {
12813 if (Arg->onlyReadsMemory()) {
12814 addKnownBits(IS_NOEFFECT);
12815 return ChangeStatus::UNCHANGED;
12816 }
12817
12818 // Readonly information is not provided, and cannot be inferred from
12819 // AAMemoryBehavior.
12820 return indicatePessimisticFixpoint();
12821 }
12822
12823 return ChangeStatus::UNCHANGED;
12824 }
12825
12826 ChangeStatus updateLocalInvariance(Attributor &A) {
12827 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12828 return ChangeStatus::UNCHANGED;
12829
12830 // try to infer invariance from underlying objects
12831 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12832 getIRPosition(), this, DepClassTy::REQUIRED);
12833 if (!AUO)
12834 return ChangeStatus::UNCHANGED;
12835
12836 bool UsedAssumedInformation = false;
12837 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12838 if (!V.getType()->isPointerTy())
12839 return true;
12840 const auto *IsInvariantLoadPointer =
12841 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12842 DepClassTy::REQUIRED);
12843 // Conservatively fail if invariance cannot be inferred.
12844 if (!IsInvariantLoadPointer)
12845 return false;
12846
12847 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12848 return true;
12849 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12850 return false;
12851
12852 UsedAssumedInformation = true;
12853 return true;
12854 };
12855 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12856 return indicatePessimisticFixpoint();
12857
12858 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12860 CB, /*MustPreserveNullness=*/false)) {
12861 for (const Value *Arg : CB->args()) {
12862 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12863 return indicatePessimisticFixpoint();
12864 }
12865 }
12866 }
12867
12868 if (!UsedAssumedInformation) {
12869 // Pointer is known and not just assumed to be locally invariant.
12870 addKnownBits(IS_LOCALLY_INVARIANT);
12871 return ChangeStatus::CHANGED;
12872 }
12873
12874 return ChangeStatus::UNCHANGED;
12875 }
12876};
12877
12878struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12879 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12880 : AAInvariantLoadPointerImpl(IRP, A) {}
12881};
12882
12883struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12884 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12885 : AAInvariantLoadPointerImpl(IRP, A) {}
12886
12887 void initialize(Attributor &) override {
12888 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12889 }
12890};
12891
12892struct AAInvariantLoadPointerCallSiteReturned final
12893 : AAInvariantLoadPointerImpl {
12894 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12895 : AAInvariantLoadPointerImpl(IRP, A) {}
12896
12897 void initialize(Attributor &A) override {
12898 const Function *F = getAssociatedFunction();
12899 assert(F && "no associated function for return from call");
12900
12901 if (!F->isDeclaration() && !F->isIntrinsic())
12902 return AAInvariantLoadPointerImpl::initialize(A);
12903
12904 const auto &CB = cast<CallBase>(getAnchorValue());
12906 &CB, /*MustPreserveNullness=*/false))
12907 return AAInvariantLoadPointerImpl::initialize(A);
12908
12909 if (F->onlyReadsMemory() && F->hasNoSync())
12910 return AAInvariantLoadPointerImpl::initialize(A);
12911
12912 // At this point, the function is opaque, so we conservatively assume
12913 // non-invariance.
12914 indicatePessimisticFixpoint();
12915 }
12916};
12917
12918struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12919 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12920 : AAInvariantLoadPointerImpl(IRP, A) {}
12921
12922 void initialize(Attributor &) override {
12923 const Function *F = getAssociatedFunction();
12924 assert(F && "no associated function for argument");
12925
12926 if (!isCallableCC(F->getCallingConv())) {
12927 addKnownBits(IS_LOCALLY_CONSTRAINED);
12928 return;
12929 }
12930
12931 if (!F->hasLocalLinkage())
12932 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12933 }
12934};
12935
12936struct AAInvariantLoadPointerCallSiteArgument final
12937 : AAInvariantLoadPointerImpl {
12938 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12939 : AAInvariantLoadPointerImpl(IRP, A) {}
12940};
12941} // namespace
12942
12943/// ------------------------ Address Space ------------------------------------
12944namespace {
12945
12946template <typename InstType>
12947static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12948 Value *OriginalValue, PointerType *NewPtrTy,
12949 bool UseOriginalValue) {
12950 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12951 return false;
12952
12953 if (MemInst->isVolatile()) {
12954 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12955 *MemInst->getFunction());
12956 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12957 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12958 return false;
12959 }
12960
12961 if (UseOriginalValue) {
12962 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
12963 return true;
12964 }
12965
12966 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12967 CastInst->insertBefore(MemInst->getIterator());
12968 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
12969 return true;
12970}
12971
12972struct AAAddressSpaceImpl : public AAAddressSpace {
12973 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12974 : AAAddressSpace(IRP, A) {}
12975
12976 uint32_t getAddressSpace() const override {
12977 assert(isValidState() && "the AA is invalid");
12978 return AssumedAddressSpace;
12979 }
12980
12981 /// See AbstractAttribute::initialize(...).
12982 void initialize(Attributor &A) override {
12983 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12984 "Associated value is not a pointer");
12985
12986 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
12987 indicatePessimisticFixpoint();
12988 return;
12989 }
12990
12991 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12992 unsigned AS = getAssociatedType()->getPointerAddressSpace();
12993 if (AS != FlatAS) {
12994 [[maybe_unused]] bool R = takeAddressSpace(AS);
12995 assert(R && "The take should happen");
12996 indicateOptimisticFixpoint();
12997 }
12998 }
12999
13000 ChangeStatus updateImpl(Attributor &A) override {
13001 uint32_t OldAddressSpace = AssumedAddressSpace;
13002 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13003
13004 auto CheckAddressSpace = [&](Value &Obj) {
13005 // Ignore undef.
13006 if (isa<UndefValue>(&Obj))
13007 return true;
13008
13009 // If the object already has a non-flat address space, we simply take it.
13010 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13011 if (ObjAS != FlatAS)
13012 return takeAddressSpace(ObjAS);
13013
13014 // At this point, we know Obj is in the flat address space. For a final
13015 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13016 // associated function, if possible.
13017 Function *F = nullptr;
13018 if (auto *Arg = dyn_cast<Argument>(&Obj))
13019 F = Arg->getParent();
13020 else if (auto *I = dyn_cast<Instruction>(&Obj))
13021 F = I->getFunction();
13022
13023 // Use getAssumedAddrSpace if the associated function exists.
13024 if (F) {
13025 auto *TTI =
13026 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13027 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13028 if (AssumedAS != ~0U)
13029 return takeAddressSpace(AssumedAS);
13030 }
13031
13032 // Now we can't do anything else but to take the flat AS.
13033 return takeAddressSpace(FlatAS);
13034 };
13035
13036 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13037 DepClassTy::REQUIRED);
13038 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13039 return indicatePessimisticFixpoint();
13040
13041 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13042 : ChangeStatus::CHANGED;
13043 }
13044
13045 /// See AbstractAttribute::manifest(...).
13046 ChangeStatus manifest(Attributor &A) override {
13047 unsigned NewAS = getAddressSpace();
13048
13049 if (NewAS == InvalidAddressSpace ||
13050 NewAS == getAssociatedType()->getPointerAddressSpace())
13051 return ChangeStatus::UNCHANGED;
13052
13053 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13054
13055 Value *AssociatedValue = &getAssociatedValue();
13056 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13057
13058 PointerType *NewPtrTy =
13059 PointerType::get(getAssociatedType()->getContext(), NewAS);
13060 bool UseOriginalValue =
13061 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13062
13063 bool Changed = false;
13064
13065 auto Pred = [&](const Use &U, bool &) {
13066 if (U.get() != AssociatedValue)
13067 return true;
13068 auto *Inst = dyn_cast<Instruction>(U.getUser());
13069 if (!Inst)
13070 return true;
13071 // This is a WA to make sure we only change uses from the corresponding
13072 // CGSCC if the AA is run on CGSCC instead of the entire module.
13073 if (!A.isRunOn(Inst->getFunction()))
13074 return true;
13075 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13076 Changed |=
13077 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13078 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13079 Changed |=
13080 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13081 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13082 Changed |=
13083 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13084 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13085 Changed |=
13086 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13087 }
13088 return true;
13089 };
13090
13091 // It doesn't matter if we can't check all uses as we can simply
13092 // conservatively ignore those that can not be visited.
13093 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13094 /* CheckBBLivenessOnly */ true);
13095
13096 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13097 }
13098
13099 /// See AbstractAttribute::getAsStr().
13100 const std::string getAsStr(Attributor *A) const override {
13101 if (!isValidState())
13102 return "addrspace(<invalid>)";
13103 return "addrspace(" +
13104 (AssumedAddressSpace == InvalidAddressSpace
13105 ? "none"
13106 : std::to_string(AssumedAddressSpace)) +
13107 ")";
13108 }
13109
13110private:
13111 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13112
13113 bool takeAddressSpace(uint32_t AS) {
13114 if (AssumedAddressSpace == InvalidAddressSpace) {
13115 AssumedAddressSpace = AS;
13116 return true;
13117 }
13118 return AssumedAddressSpace == AS;
13119 }
13120
13121 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13122 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13123 assert(I->getSrcAddressSpace() != FlatAS &&
13124 "there should not be flat AS -> non-flat AS");
13125 return I->getPointerOperand();
13126 }
13127 if (auto *C = dyn_cast<ConstantExpr>(V))
13128 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13129 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13130 FlatAS &&
13131 "there should not be flat AS -> non-flat AS X");
13132 return C->getOperand(0);
13133 }
13134 return V;
13135 }
13136};
13137
13138struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13139 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13140 : AAAddressSpaceImpl(IRP, A) {}
13141
13142 void trackStatistics() const override {
13144 }
13145};
13146
13147struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13148 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13149 : AAAddressSpaceImpl(IRP, A) {}
13150
13151 /// See AbstractAttribute::initialize(...).
13152 void initialize(Attributor &A) override {
13153 // TODO: we don't rewrite function argument for now because it will need to
13154 // rewrite the function signature and all call sites.
13155 (void)indicatePessimisticFixpoint();
13156 }
13157
13158 void trackStatistics() const override {
13159 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13160 }
13161};
13162
13163struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13164 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13165 : AAAddressSpaceImpl(IRP, A) {}
13166
13167 void trackStatistics() const override {
13168 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13169 }
13170};
13171
13172struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13173 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13174 : AAAddressSpaceImpl(IRP, A) {}
13175
13176 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13177};
13178
13179struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13180 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13181 : AAAddressSpaceImpl(IRP, A) {}
13182
13183 /// See AbstractAttribute::initialize(...).
13184 void initialize(Attributor &A) override {
13185 // TODO: we don't rewrite call site argument for now because it will need to
13186 // rewrite the function signature of the callee.
13187 (void)indicatePessimisticFixpoint();
13188 }
13189
13190 void trackStatistics() const override {
13191 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13192 }
13193};
13194} // namespace
13195
13196/// ------------------------ No Alias Address Space ---------------------------
13197// This attribute assumes flat address space can alias all other address space
13198
13199// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13200// But merging it created failing cased on gateway test that cannot be
13201// reproduced locally. So should open a seperated PR to hande the merge of
13202// AANoAliasAddrSpace and AAAddressSpace attribute
13203
13204namespace {
13205struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13206 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13207 : AANoAliasAddrSpace(IRP, A) {}
13208
13209 void initialize(Attributor &A) override {
13210 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13211 "Associated value is not a pointer");
13212
13213 resetASRanges(A);
13214
13215 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13216 if (!FlatAS.has_value()) {
13217 indicatePessimisticFixpoint();
13218 return;
13219 }
13220
13221 removeAS(*FlatAS);
13222
13223 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13224 if (AS != *FlatAS) {
13225 removeAS(AS);
13226 indicateOptimisticFixpoint();
13227 }
13228 }
13229
13230 ChangeStatus updateImpl(Attributor &A) override {
13231 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13232 uint32_t OldAssumed = getAssumed();
13233
13234 auto CheckAddressSpace = [&](Value &Obj) {
13235 if (isa<PoisonValue>(&Obj))
13236 return true;
13237
13238 unsigned AS = Obj.getType()->getPointerAddressSpace();
13239 if (AS == FlatAS)
13240 return false;
13241
13242 removeAS(Obj.getType()->getPointerAddressSpace());
13243 return true;
13244 };
13245
13246 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13247 getIRPosition(), this, DepClassTy::REQUIRED);
13248 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13249 return indicatePessimisticFixpoint();
13250
13251 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13252 : ChangeStatus::CHANGED;
13253 }
13254
13255 /// See AbstractAttribute::manifest(...).
13256 ChangeStatus manifest(Attributor &A) override {
13257 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13258
13259 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13260 if (AS != FlatAS || Map.empty())
13261 return ChangeStatus::UNCHANGED;
13262
13263 LLVMContext &Ctx = getAssociatedValue().getContext();
13264 MDNode *NoAliasASNode = nullptr;
13265 MDBuilder MDB(Ctx);
13266 // Has to use iterator to get the range info.
13267 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13268 if (!I.value())
13269 continue;
13270 unsigned Upper = I.stop();
13271 unsigned Lower = I.start();
13272 if (!NoAliasASNode) {
13273 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13274 continue;
13275 }
13276 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13277 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13278 }
13279
13280 Value *AssociatedValue = &getAssociatedValue();
13281 bool Changed = false;
13282
13283 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13284 if (U.get() != AssociatedValue)
13285 return true;
13286 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13287 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13288 return true;
13289 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13291 return true;
13292 if (!A.isRunOn(Inst->getFunction()))
13293 return true;
13294 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13295 Changed = true;
13296 return true;
13297 };
13298 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13299 /*CheckBBLivenessOnly=*/true);
13300 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13301 }
13302
13303 /// See AbstractAttribute::getAsStr().
13304 const std::string getAsStr(Attributor *A) const override {
13305 if (!isValidState())
13306 return "<invalid>";
13307 std::string Str;
13308 raw_string_ostream OS(Str);
13309 OS << "CanNotBeAddrSpace(";
13310 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13311 unsigned Upper = I.stop();
13312 unsigned Lower = I.start();
13313 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13314 }
13315 OS << " )";
13316 return OS.str();
13317 }
13318
13319private:
13320 void removeAS(unsigned AS) {
13321 RangeMap::iterator I = Map.find(AS);
13322
13323 if (I != Map.end()) {
13324 unsigned Upper = I.stop();
13325 unsigned Lower = I.start();
13326 I.erase();
13327 if (Upper == Lower)
13328 return;
13329 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13330 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13331 if (AS != 0 && Lower <= AS - 1)
13332 Map.insert(Lower, AS - 1, true);
13333 }
13334 }
13335
13336 void resetASRanges(Attributor &A) {
13337 Map.clear();
13338 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13339 }
13340};
13341
13342struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13343 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13344 : AANoAliasAddrSpaceImpl(IRP, A) {}
13345
13346 void trackStatistics() const override {
13347 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13348 }
13349};
13350
13351struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13352 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13353 : AANoAliasAddrSpaceImpl(IRP, A) {}
13354
13355 void trackStatistics() const override {
13356 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13357 }
13358};
13359
13360struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13361 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13362 : AANoAliasAddrSpaceImpl(IRP, A) {}
13363
13364 void trackStatistics() const override {
13365 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13366 }
13367};
13368
13369struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13370 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13371 : AANoAliasAddrSpaceImpl(IRP, A) {}
13372
13373 void trackStatistics() const override {
13374 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13375 }
13376};
13377
13378struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13379 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13380 : AANoAliasAddrSpaceImpl(IRP, A) {}
13381
13382 void trackStatistics() const override {
13383 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13384 }
13385};
13386} // namespace
13387/// ----------- Allocation Info ----------
13388namespace {
13389struct AAAllocationInfoImpl : public AAAllocationInfo {
13390 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13391 : AAAllocationInfo(IRP, A) {}
13392
13393 std::optional<TypeSize> getAllocatedSize() const override {
13394 assert(isValidState() && "the AA is invalid");
13395 return AssumedAllocatedSize;
13396 }
13397
13398 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13399 const DataLayout &DL) {
13400
13401 // TODO: implement case for malloc like instructions
13402 switch (I->getOpcode()) {
13403 case Instruction::Alloca: {
13404 AllocaInst *AI = cast<AllocaInst>(I);
13405 return AI->getAllocationSize(DL);
13406 }
13407 default:
13408 return std::nullopt;
13409 }
13410 }
13411
13412 ChangeStatus updateImpl(Attributor &A) override {
13413
13414 const IRPosition &IRP = getIRPosition();
13415 Instruction *I = IRP.getCtxI();
13416
13417 // TODO: update check for malloc like calls
13418 if (!isa<AllocaInst>(I))
13419 return indicatePessimisticFixpoint();
13420
13421 bool IsKnownNoCapture;
13423 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13424 return indicatePessimisticFixpoint();
13425
13426 const AAPointerInfo *PI =
13427 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13428
13429 if (!PI)
13430 return indicatePessimisticFixpoint();
13431
13432 if (!PI->getState().isValidState() || PI->reachesReturn())
13433 return indicatePessimisticFixpoint();
13434
13435 const DataLayout &DL = A.getDataLayout();
13436 const auto AllocationSize = findInitialAllocationSize(I, DL);
13437
13438 // If allocation size is nullopt, we give up.
13439 if (!AllocationSize)
13440 return indicatePessimisticFixpoint();
13441
13442 // For zero sized allocations, we give up.
13443 // Since we can't reduce further
13444 if (*AllocationSize == 0)
13445 return indicatePessimisticFixpoint();
13446
13447 int64_t BinSize = PI->numOffsetBins();
13448
13449 // TODO: implement for multiple bins
13450 if (BinSize > 1)
13451 return indicatePessimisticFixpoint();
13452
13453 if (BinSize == 0) {
13454 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13455 if (!changeAllocationSize(NewAllocationSize))
13456 return ChangeStatus::UNCHANGED;
13457 return ChangeStatus::CHANGED;
13458 }
13459
13460 // TODO: refactor this to be part of multiple bin case
13461 const auto &It = PI->begin();
13462
13463 // TODO: handle if Offset is not zero
13464 if (It->first.Offset != 0)
13465 return indicatePessimisticFixpoint();
13466
13467 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13468
13469 if (SizeOfBin >= *AllocationSize)
13470 return indicatePessimisticFixpoint();
13471
13472 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13473
13474 if (!changeAllocationSize(NewAllocationSize))
13475 return ChangeStatus::UNCHANGED;
13476
13477 return ChangeStatus::CHANGED;
13478 }
13479
13480 /// See AbstractAttribute::manifest(...).
13481 ChangeStatus manifest(Attributor &A) override {
13482
13483 assert(isValidState() &&
13484 "Manifest should only be called if the state is valid.");
13485
13486 Instruction *I = getIRPosition().getCtxI();
13487
13488 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13489
13490 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13491
13492 switch (I->getOpcode()) {
13493 // TODO: add case for malloc like calls
13494 case Instruction::Alloca: {
13495
13496 AllocaInst *AI = cast<AllocaInst>(I);
13497
13498 Type *CharType = Type::getInt8Ty(I->getContext());
13499
13500 auto *NumBytesToValue =
13501 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13502
13503 BasicBlock::iterator insertPt = AI->getIterator();
13504 insertPt = std::next(insertPt);
13505 AllocaInst *NewAllocaInst =
13506 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13507 AI->getAlign(), AI->getName(), insertPt);
13508
13509 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13510 return ChangeStatus::CHANGED;
13511
13512 break;
13513 }
13514 default:
13515 break;
13516 }
13517
13518 return ChangeStatus::UNCHANGED;
13519 }
13520
13521 /// See AbstractAttribute::getAsStr().
13522 const std::string getAsStr(Attributor *A) const override {
13523 if (!isValidState())
13524 return "allocationinfo(<invalid>)";
13525 return "allocationinfo(" +
13526 (AssumedAllocatedSize == HasNoAllocationSize
13527 ? "none"
13528 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13529 ")";
13530 }
13531
13532private:
13533 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13534
13535 // Maintain the computed allocation size of the object.
13536 // Returns (bool) weather the size of the allocation was modified or not.
13537 bool changeAllocationSize(std::optional<TypeSize> Size) {
13538 if (AssumedAllocatedSize == HasNoAllocationSize ||
13539 AssumedAllocatedSize != Size) {
13540 AssumedAllocatedSize = Size;
13541 return true;
13542 }
13543 return false;
13544 }
13545};
13546
13547struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13548 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13549 : AAAllocationInfoImpl(IRP, A) {}
13550
13551 void trackStatistics() const override {
13552 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13553 }
13554};
13555
13556struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13557 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13558 : AAAllocationInfoImpl(IRP, A) {}
13559
13560 /// See AbstractAttribute::initialize(...).
13561 void initialize(Attributor &A) override {
13562 // TODO: we don't rewrite function argument for now because it will need to
13563 // rewrite the function signature and all call sites
13564 (void)indicatePessimisticFixpoint();
13565 }
13566
13567 void trackStatistics() const override {
13568 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13569 }
13570};
13571
13572struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13573 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13574 : AAAllocationInfoImpl(IRP, A) {}
13575
13576 void trackStatistics() const override {
13577 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13578 }
13579};
13580
13581struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13582 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13583 : AAAllocationInfoImpl(IRP, A) {}
13584
13585 void trackStatistics() const override {
13586 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13587 }
13588};
13589
13590struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13591 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13592 : AAAllocationInfoImpl(IRP, A) {}
13593
13594 /// See AbstractAttribute::initialize(...).
13595 void initialize(Attributor &A) override {
13596
13597 (void)indicatePessimisticFixpoint();
13598 }
13599
13600 void trackStatistics() const override {
13601 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13602 }
13603};
13604} // namespace
13605
13606const char AANoUnwind::ID = 0;
13607const char AANoSync::ID = 0;
13608const char AANoFree::ID = 0;
13609const char AANonNull::ID = 0;
13610const char AAMustProgress::ID = 0;
13611const char AANoRecurse::ID = 0;
13612const char AANonConvergent::ID = 0;
13613const char AAWillReturn::ID = 0;
13614const char AAUndefinedBehavior::ID = 0;
13615const char AANoAlias::ID = 0;
13616const char AAIntraFnReachability::ID = 0;
13617const char AANoReturn::ID = 0;
13618const char AAIsDead::ID = 0;
13619const char AADereferenceable::ID = 0;
13620const char AAAlign::ID = 0;
13621const char AAInstanceInfo::ID = 0;
13622const char AANoCapture::ID = 0;
13623const char AAValueSimplify::ID = 0;
13624const char AAHeapToStack::ID = 0;
13625const char AAPrivatizablePtr::ID = 0;
13626const char AAMemoryBehavior::ID = 0;
13627const char AAMemoryLocation::ID = 0;
13628const char AAValueConstantRange::ID = 0;
13629const char AAPotentialConstantValues::ID = 0;
13630const char AAPotentialValues::ID = 0;
13631const char AANoUndef::ID = 0;
13632const char AANoFPClass::ID = 0;
13633const char AACallEdges::ID = 0;
13634const char AAInterFnReachability::ID = 0;
13635const char AAPointerInfo::ID = 0;
13636const char AAAssumptionInfo::ID = 0;
13637const char AAUnderlyingObjects::ID = 0;
13638const char AAInvariantLoadPointer::ID = 0;
13639const char AAAddressSpace::ID = 0;
13640const char AANoAliasAddrSpace::ID = 0;
13641const char AAAllocationInfo::ID = 0;
13642const char AAIndirectCallInfo::ID = 0;
13643const char AAGlobalValueInfo::ID = 0;
13644const char AADenormalFPMath::ID = 0;
13645
13646// Macro magic to create the static generator function for attributes that
13647// follow the naming scheme.
13648
13649#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13650 case IRPosition::PK: \
13651 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13652
13653#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13654 case IRPosition::PK: \
13655 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13656 ++NumAAs; \
13657 break;
13658
13659#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13660 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13661 CLASS *AA = nullptr; \
13662 switch (IRP.getPositionKind()) { \
13663 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13664 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13665 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13666 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13667 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13668 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13669 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13670 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13671 } \
13672 return *AA; \
13673 }
13674
13675#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13676 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13677 CLASS *AA = nullptr; \
13678 switch (IRP.getPositionKind()) { \
13679 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13680 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13681 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13682 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13683 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13684 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13685 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13686 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13687 } \
13688 return *AA; \
13689 }
13690
13691#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13692 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13693 CLASS *AA = nullptr; \
13694 switch (IRP.getPositionKind()) { \
13695 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13696 default: \
13697 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13698 " position!"); \
13699 } \
13700 return *AA; \
13701 }
13702
13703#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13704 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13705 CLASS *AA = nullptr; \
13706 switch (IRP.getPositionKind()) { \
13707 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13708 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13709 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13710 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13711 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13712 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13713 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13714 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13715 } \
13716 return *AA; \
13717 }
13718
13719#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13720 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13721 CLASS *AA = nullptr; \
13722 switch (IRP.getPositionKind()) { \
13723 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13724 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13725 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13726 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13727 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13728 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13729 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13730 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13731 } \
13732 return *AA; \
13733 }
13734
13735#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13736 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13737 CLASS *AA = nullptr; \
13738 switch (IRP.getPositionKind()) { \
13739 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13740 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13741 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13742 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13743 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13744 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13745 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13746 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13747 } \
13748 return *AA; \
13749 }
13750
13760
13778
13783
13788
13795
13797
13798#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13799#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13800#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13801#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13802#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13803#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13804#undef SWITCH_PK_CREATE
13805#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition CFG.cpp:135
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
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, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h: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.
iterator_range< succ_op_iterator > successors()
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:372
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:256
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
iterator end()
Definition DenseMap.h:81
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
Analysis pass which computes a DominatorTree.
Definition Dominators.h:283
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:164
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h: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:730
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:130
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:220
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:140
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:146
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:239
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:193
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:229
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:223
static MemoryEffectsBase writeOnly()
Definition ModRef.h:135
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:163
static MemoryEffectsBase none()
Definition ModRef.h:125
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:250
static MemoryEffectsBase unknown()
Definition ModRef.h:120
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:58
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:101
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:149
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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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
const Use & getOperandUse(unsigned i) const
Definition User.h:245
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:118
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:24
Value * getOperand(unsigned i) const
Definition User.h:232
unsigned getNumOperands() const
Definition User.h:254
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:546
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1099
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:322
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:323
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:182
@ Intraprocedural
Definition Attributor.h:183
@ Interprocedural
Definition Attributor.h:184
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
@ 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:532
@ Length
Definition DWP.cpp:532
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:360
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:301
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:354
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:320
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
Value * getValue() const
Definition Attributor.h:194
const Instruction * getCtxI() const
Definition Attributor.h:195
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr 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.