LLVM 23.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
296static Value *constructPointer(Value *Ptr, int64_t Offset,
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
320 if (!ValueConstantRangeAA)
321 return false;
322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed()
323 : ValueConstantRangeAA->getKnown();
324 if (Range.isFullSet())
325 return false;
326
327 // We can only use the lower part of the range because the upper part can
328 // be higher than what the value can really be.
329 if (GetMinOffset)
330 ROffset = Range.getSignedMin();
331 else
332 ROffset = Range.getSignedMax();
333 return true;
334 };
335
336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
337 /* AllowInvariant */ true,
338 AttributorAnalysis);
339}
340
341static const Value *
343 const Value *Ptr, int64_t &BytesOffset,
344 const DataLayout &DL, bool AllowNonInbounds = false) {
345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
346 const Value *Base =
347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
348 /* GetMinOffset */ true, AllowNonInbounds);
349
350 BytesOffset = OffsetAPInt.getSExtValue();
351 return Base;
352}
353
354/// Clamp the information known for all returned values of a function
355/// (identified by \p QueryingAA) into \p S.
356template <typename AAType, typename StateType = typename AAType::StateType,
357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
358 bool RecurseForSelectAndPHI = true>
360 Attributor &A, const AAType &QueryingAA, StateType &S,
361 const IRPosition::CallBaseContext *CBContext = nullptr) {
362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
363 << QueryingAA << " into " << S << "\n");
364
365 assert((QueryingAA.getIRPosition().getPositionKind() ==
367 QueryingAA.getIRPosition().getPositionKind() ==
369 "Can only clamp returned value states for a function returned or call "
370 "site returned position!");
371
372 // Use an optional state as there might not be any return values and we want
373 // to join (IntegerState::operator&) the state of all there are.
374 std::optional<StateType> T;
375
376 // Callback for each possibly returned value.
377 auto CheckReturnValue = [&](Value &RV) -> bool {
378 const IRPosition &RVPos = IRPosition::value(RV, CBContext);
379 // If possible, use the hasAssumedIRAttr interface.
380 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
381 bool IsKnown;
383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown);
384 }
385
386 const AAType *AA =
387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED);
388 if (!AA)
389 return false;
390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV
391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n");
392 const StateType &AAS = AA->getState();
393 if (!T)
394 T = StateType::getBestState(AAS);
395 *T &= AAS;
396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
397 << "\n");
398 return T->isValidState();
399 };
400
401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA,
403 RecurseForSelectAndPHI))
404 S.indicatePessimisticFixpoint();
405 else if (T)
406 S ^= *T;
407}
408
409namespace {
410/// Helper class for generic deduction: return value -> returned position.
411template <typename AAType, typename BaseType,
412 typename StateType = typename BaseType::StateType,
413 bool PropagateCallBaseContext = false,
414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind,
415 bool RecurseForSelectAndPHI = true>
416struct AAReturnedFromReturnedValues : public BaseType {
417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A)
418 : BaseType(IRP, A) {}
419
420 /// See AbstractAttribute::updateImpl(...).
421 ChangeStatus updateImpl(Attributor &A) override {
422 StateType S(StateType::getBestState(this->getState()));
423 clampReturnedValueStates<AAType, StateType, IRAttributeKind,
424 RecurseForSelectAndPHI>(
425 A, *this, S,
426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr);
427 // TODO: If we know we visited all returned values, thus no are assumed
428 // dead, we can take the known information from the state T.
429 return clampStateAndIndicateChange<StateType>(this->getState(), S);
430 }
431};
432
433/// Clamp the information known at all call sites for a given argument
434/// (identified by \p QueryingAA) into \p S.
435template <typename AAType, typename StateType = typename AAType::StateType,
436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
437static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
438 StateType &S) {
439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
440 << QueryingAA << " into " << S << "\n");
441
442 assert(QueryingAA.getIRPosition().getPositionKind() ==
444 "Can only clamp call site argument states for an argument position!");
445
446 // Use an optional state as there might not be any return values and we want
447 // to join (IntegerState::operator&) the state of all there are.
448 std::optional<StateType> T;
449
450 // The argument number which is also the call site argument number.
451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo();
452
453 auto CallSiteCheck = [&](AbstractCallSite ACS) {
454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
455 // Check if a coresponding argument was found or if it is on not associated
456 // (which can happen for callback calls).
457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
458 return false;
459
460 // If possible, use the hasAssumedIRAttr interface.
461 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
462 bool IsKnown;
464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown);
465 }
466
467 const AAType *AA =
468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED);
469 if (!AA)
470 return false;
471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos
473 << "\n");
474 const StateType &AAS = AA->getState();
475 if (!T)
476 T = StateType::getBestState(AAS);
477 *T &= AAS;
478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
479 << "\n");
480 return T->isValidState();
481 };
482
483 bool UsedAssumedInformation = false;
484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
485 UsedAssumedInformation))
486 S.indicatePessimisticFixpoint();
487 else if (T)
488 S ^= *T;
489}
490
491/// This function is the bridge between argument position and the call base
492/// context.
493template <typename AAType, typename BaseType,
494 typename StateType = typename AAType::StateType,
495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
496bool getArgumentStateFromCallBaseContext(Attributor &A,
497 BaseType &QueryingAttribute,
498 IRPosition &Pos, StateType &State) {
500 "Expected an 'argument' position !");
501 const CallBase *CBContext = Pos.getCallBaseContext();
502 if (!CBContext)
503 return false;
504
505 int ArgNo = Pos.getCallSiteArgNo();
506 assert(ArgNo >= 0 && "Invalid Arg No!");
507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo);
508
509 // If possible, use the hasAssumedIRAttr interface.
510 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
511 bool IsKnown;
513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown);
514 }
515
516 const auto *AA =
517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED);
518 if (!AA)
519 return false;
520 const StateType &CBArgumentState =
521 static_cast<const StateType &>(AA->getState());
522
523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument"
524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState
525 << "\n");
526
527 // NOTE: If we want to do call site grouping it should happen here.
528 State ^= CBArgumentState;
529 return true;
530}
531
532/// Helper class for generic deduction: call site argument -> argument position.
533template <typename AAType, typename BaseType,
534 typename StateType = typename AAType::StateType,
535 bool BridgeCallBaseContext = false,
536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
537struct AAArgumentFromCallSiteArguments : public BaseType {
538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A)
539 : BaseType(IRP, A) {}
540
541 /// See AbstractAttribute::updateImpl(...).
542 ChangeStatus updateImpl(Attributor &A) override {
543 StateType S = StateType::getBestState(this->getState());
544
545 if (BridgeCallBaseContext) {
546 bool Success =
547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType,
548 IRAttributeKind>(
549 A, *this, this->getIRPosition(), S);
550 if (Success)
551 return clampStateAndIndicateChange<StateType>(this->getState(), S);
552 }
553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this,
554 S);
555
556 // TODO: If we know we visited all incoming values, thus no are assumed
557 // dead, we can take the known information from the state T.
558 return clampStateAndIndicateChange<StateType>(this->getState(), S);
559 }
560};
561
562/// Helper class for generic replication: function returned -> cs returned.
563template <typename AAType, typename BaseType,
564 typename StateType = typename BaseType::StateType,
565 bool IntroduceCallBaseContext = false,
566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind>
567struct AACalleeToCallSite : public BaseType {
568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {}
569
570 /// See AbstractAttribute::updateImpl(...).
571 ChangeStatus updateImpl(Attributor &A) override {
572 auto IRPKind = this->getIRPosition().getPositionKind();
574 IRPKind == IRPosition::IRP_CALL_SITE) &&
575 "Can only wrap function returned positions for call site "
576 "returned positions!");
577 auto &S = this->getState();
578
579 CallBase &CB = cast<CallBase>(this->getAnchorValue());
580 if (IntroduceCallBaseContext)
581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB
582 << "\n");
583
584 ChangeStatus Changed = ChangeStatus::UNCHANGED;
585 auto CalleePred = [&](ArrayRef<const Function *> Callees) {
586 for (const Function *Callee : Callees) {
587 IRPosition FnPos =
589 ? IRPosition::returned(*Callee,
590 IntroduceCallBaseContext ? &CB : nullptr)
591 : IRPosition::function(
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const CondBrInst *Br = dyn_cast<CondBrInst>(I))
670 BrInsts.push_back(Br);
671 return true;
672 };
673
674 // Here, accumulate conditional branch instructions in the context. We
675 // explore the child paths and collect the known states. The disjunction of
676 // those states can be merged to its own state. Let ParentState_i be a state
677 // to indicate the known information for an i-th branch instruction in the
678 // context. ChildStates are created for its successors respectively.
679 //
680 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
681 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
682 // ...
683 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
684 //
685 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
686 //
687 // FIXME: Currently, recursive branches are not handled. For example, we
688 // can't deduce that ptr must be dereferenced in below function.
689 //
690 // void f(int a, int c, int *ptr) {
691 // if(a)
692 // if (b) {
693 // *ptr = 0;
694 // } else {
695 // *ptr = 1;
696 // }
697 // else {
698 // if (b) {
699 // *ptr = 0;
700 // } else {
701 // *ptr = 1;
702 // }
703 // }
704 // }
705
706 Explorer->checkForAllContext(&CtxI, Pred);
707 for (const CondBrInst *Br : BrInsts) {
708 StateType ParentState;
709
710 // The known state of the parent state is a conjunction of children's
711 // known states so it is initialized with a best state.
712 ParentState.indicateOptimisticFixpoint();
713
714 for (const BasicBlock *BB : Br->successors()) {
715 StateType ChildState;
716
717 size_t BeforeSize = Uses.size();
718 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
719
720 // Erase uses which only appear in the child.
721 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
722 It = Uses.erase(It);
723
724 ParentState &= ChildState;
725 }
726
727 // Use only known state.
728 S += ParentState;
729 }
730}
731} // namespace
732
733/// ------------------------ PointerInfo ---------------------------------------
734
735namespace llvm {
736namespace AA {
737namespace PointerInfo {
738
739struct State;
740
741} // namespace PointerInfo
742} // namespace AA
743
744/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
745template <>
748 static inline Access getEmptyKey();
749 static inline Access getTombstoneKey();
750 static unsigned getHashValue(const Access &A);
751 static bool isEqual(const Access &LHS, const Access &RHS);
752};
753
754/// Helper that allows RangeTy as a key in a DenseMap.
755template <> struct DenseMapInfo<AA::RangeTy> {
756 static inline AA::RangeTy getEmptyKey() {
757 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
758 return AA::RangeTy{EmptyKey, EmptyKey};
759 }
760
761 static inline AA::RangeTy getTombstoneKey() {
762 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
763 return AA::RangeTy{TombstoneKey, TombstoneKey};
764 }
765
771
772 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
773 return A == B;
774 }
775};
776
777/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
778/// but the instruction
779struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
782 static inline Access getEmptyKey();
783 static inline Access getTombstoneKey();
784 static unsigned getHashValue(const Access &A);
785 static bool isEqual(const Access &LHS, const Access &RHS);
786};
787
788} // namespace llvm
789
790/// A type to track pointer/struct usage and accesses for AAPointerInfo.
792 /// Return the best possible representable state.
793 static State getBestState(const State &SIS) { return State(); }
794
795 /// Return the worst possible representable state.
796 static State getWorstState(const State &SIS) {
797 State R;
798 R.indicatePessimisticFixpoint();
799 return R;
800 }
801
802 State() = default;
803 State(State &&SIS) = default;
804
805 const State &getAssumed() const { return *this; }
806
807 /// See AbstractState::isValidState().
808 bool isValidState() const override { return BS.isValidState(); }
809
810 /// See AbstractState::isAtFixpoint().
811 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
812
813 /// See AbstractState::indicateOptimisticFixpoint().
815 BS.indicateOptimisticFixpoint();
817 }
818
819 /// See AbstractState::indicatePessimisticFixpoint().
821 BS.indicatePessimisticFixpoint();
823 }
824
825 State &operator=(const State &R) {
826 if (this == &R)
827 return *this;
828 BS = R.BS;
829 AccessList = R.AccessList;
830 OffsetBins = R.OffsetBins;
831 RemoteIMap = R.RemoteIMap;
832 ReturnedOffsets = R.ReturnedOffsets;
833 return *this;
834 }
835
837 if (this == &R)
838 return *this;
839 std::swap(BS, R.BS);
840 std::swap(AccessList, R.AccessList);
841 std::swap(OffsetBins, R.OffsetBins);
842 std::swap(RemoteIMap, R.RemoteIMap);
843 std::swap(ReturnedOffsets, R.ReturnedOffsets);
844 return *this;
845 }
846
847 /// Add a new Access to the state at offset \p Offset and with size \p Size.
848 /// The access is associated with \p I, writes \p Content (if anything), and
849 /// is of kind \p Kind. If an Access already exists for the same \p I and same
850 /// \p RemoteI, the two are combined, potentially losing information about
851 /// offset and size. The resulting access must now be moved from its original
852 /// OffsetBin to the bin for its new offset.
853 ///
854 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
856 Instruction &I, std::optional<Value *> Content,
858 Instruction *RemoteI = nullptr);
859
862 int64_t numOffsetBins() const { return OffsetBins.size(); }
863
864 const AAPointerInfo::Access &getAccess(unsigned Index) const {
865 return AccessList[Index];
866 }
867
868protected:
869 // Every memory instruction results in an Access object. We maintain a list of
870 // all Access objects that we own, along with the following maps:
871 //
872 // - OffsetBins: RangeTy -> { Access }
873 // - RemoteIMap: RemoteI x LocalI -> Access
874 //
875 // A RemoteI is any instruction that accesses memory. RemoteI is different
876 // from LocalI if and only if LocalI is a call; then RemoteI is some
877 // instruction in the callgraph starting from LocalI. Multiple paths in the
878 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
879 // are all combined into a single Access object. This may result in loss of
880 // information in RangeTy in the Access object.
884
885 /// Flag to determine if the underlying pointer is reaching a return statement
886 /// in the associated function or not. Returns in other functions cause
887 /// invalidation.
889
890 /// See AAPointerInfo::forallInterferingAccesses.
891 template <typename F>
893 if (!isValidState() || !ReturnedOffsets.isUnassigned())
894 return false;
895
896 for (const auto &It : OffsetBins) {
897 AA::RangeTy ItRange = It.getFirst();
898 if (!Range.mayOverlap(ItRange))
899 continue;
900 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
901 for (auto Index : It.getSecond()) {
902 auto &Access = AccessList[Index];
903 if (!CB(Access, IsExact))
904 return false;
905 }
906 }
907 return true;
908 }
909
910 /// See AAPointerInfo::forallInterferingAccesses.
911 template <typename F>
913 AA::RangeTy &Range) const {
914 if (!isValidState() || !ReturnedOffsets.isUnassigned())
915 return false;
916
917 auto LocalList = RemoteIMap.find(&I);
918 if (LocalList == RemoteIMap.end()) {
919 return true;
920 }
921
922 for (unsigned Index : LocalList->getSecond()) {
923 for (auto &R : AccessList[Index]) {
924 Range &= R;
925 if (Range.offsetAndSizeAreUnknown())
926 break;
927 }
928 }
930 }
931
932private:
933 /// State to track fixpoint and validity.
934 BooleanState BS;
935};
936
939 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
940 Instruction *RemoteI) {
941 RemoteI = RemoteI ? RemoteI : &I;
942
943 // Check if we have an access for this instruction, if not, simply add it.
944 auto &LocalList = RemoteIMap[RemoteI];
945 bool AccExists = false;
946 unsigned AccIndex = AccessList.size();
947 for (auto Index : LocalList) {
948 auto &A = AccessList[Index];
949 if (A.getLocalInst() == &I) {
950 AccExists = true;
951 AccIndex = Index;
952 break;
953 }
954 }
955
956 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
957 LLVM_DEBUG(if (ToAdd.size()) dbgs()
958 << "[AAPointerInfo] Inserting access in new offset bins\n";);
959
960 for (auto Key : ToAdd) {
961 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
962 OffsetBins[Key].insert(AccIndex);
963 }
964 };
965
966 if (!AccExists) {
967 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
968 assert((AccessList.size() == AccIndex + 1) &&
969 "New Access should have been at AccIndex");
970 LocalList.push_back(AccIndex);
971 AddToBins(AccessList[AccIndex].getRanges());
973 }
974
975 // Combine the new Access with the existing Access, and then update the
976 // mapping in the offset bins.
977 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
978 auto &Current = AccessList[AccIndex];
979 auto Before = Current;
980 Current &= Acc;
981 if (Current == Before)
983
984 auto &ExistingRanges = Before.getRanges();
985 auto &NewRanges = Current.getRanges();
986
987 // Ranges that are in the old access but not the new access need to be removed
988 // from the offset bins.
990 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
991 LLVM_DEBUG(if (ToRemove.size()) dbgs()
992 << "[AAPointerInfo] Removing access from old offset bins\n";);
993
994 for (auto Key : ToRemove) {
995 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
996 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
997 auto &Bin = OffsetBins[Key];
998 assert(Bin.count(AccIndex) &&
999 "Expected bin to actually contain the Access.");
1000 Bin.erase(AccIndex);
1001 }
1002
1003 // Ranges that are in the new access but not the old access need to be added
1004 // to the offset bins.
1006 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1007 AddToBins(ToAdd);
1008 return ChangeStatus::CHANGED;
1009}
1010
1011namespace {
1012
1013#ifndef NDEBUG
1015 const AAPointerInfo::OffsetInfo &OI) {
1016 OS << llvm::interleaved_array(OI);
1017 return OS;
1018}
1019#endif // NDEBUG
1020
1021struct AAPointerInfoImpl
1022 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1024 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1025
1026 /// See AbstractAttribute::getAsStr().
1027 const std::string getAsStr(Attributor *A) const override {
1028 return std::string("PointerInfo ") +
1029 (isValidState() ? (std::string("#") +
1030 std::to_string(OffsetBins.size()) + " bins")
1031 : "<invalid>") +
1032 (reachesReturn()
1033 ? (" (returned:" +
1034 join(map_range(ReturnedOffsets,
1035 [](int64_t O) { return std::to_string(O); }),
1036 ", ") +
1037 ")")
1038 : "");
1039 }
1040
1041 /// See AbstractAttribute::manifest(...).
1042 ChangeStatus manifest(Attributor &A) override {
1043 return AAPointerInfo::manifest(A);
1044 }
1045
1046 const_bin_iterator begin() const override { return State::begin(); }
1047 const_bin_iterator end() const override { return State::end(); }
1048 int64_t numOffsetBins() const override { return State::numOffsetBins(); }
1049 bool reachesReturn() const override {
1050 return !ReturnedOffsets.isUnassigned();
1051 }
1052 void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1053 if (ReturnedOffsets.isUnknown()) {
1054 OI.setUnknown();
1055 return;
1056 }
1057
1058 OffsetInfo MergedOI;
1059 for (auto Offset : ReturnedOffsets) {
1060 OffsetInfo TmpOI = OI;
1061 TmpOI.addToAll(Offset);
1062 MergedOI.merge(TmpOI);
1063 }
1064 OI = std::move(MergedOI);
1065 }
1066
1067 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1068 if (ReturnedOffsets.isUnknown())
1069 return ChangeStatus::UNCHANGED;
1070 if (ReachedReturnedOffsets.isUnknown()) {
1071 ReturnedOffsets.setUnknown();
1072 return ChangeStatus::CHANGED;
1073 }
1074 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1075 return ChangeStatus::CHANGED;
1076 return ChangeStatus::UNCHANGED;
1077 }
1078
1079 bool forallInterferingAccesses(
1080 AA::RangeTy Range,
1081 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1082 const override {
1083 return State::forallInterferingAccesses(Range, CB);
1084 }
1085
1086 bool forallInterferingAccesses(
1087 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1088 bool FindInterferingWrites, bool FindInterferingReads,
1089 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1090 AA::RangeTy &Range,
1091 function_ref<bool(const Access &)> SkipCB) const override {
1092 HasBeenWrittenTo = false;
1093
1094 SmallPtrSet<const Access *, 8> DominatingWrites;
1095 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1096
1097 Function &Scope = *I.getFunction();
1098 bool IsKnownNoSync;
1099 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1100 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1101 IsKnownNoSync);
1102 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1103 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1104 bool AllInSameNoSyncFn = IsAssumedNoSync;
1105 bool InstIsExecutedByInitialThreadOnly =
1106 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1107
1108 // If the function is not ending in aligned barriers, we need the stores to
1109 // be in aligned barriers. The load being in one is not sufficient since the
1110 // store might be executed by a thread that disappears after, causing the
1111 // aligned barrier guarding the load to unblock and the load to read a value
1112 // that has no CFG path to the load.
1113 bool InstIsExecutedInAlignedRegion =
1114 FindInterferingReads && ExecDomainAA &&
1115 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1116
1117 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1118 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1119
1120 InformationCache &InfoCache = A.getInfoCache();
1121 bool IsThreadLocalObj =
1122 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1123
1124 // Helper to determine if we need to consider threading, which we cannot
1125 // right now. However, if the function is (assumed) nosync or the thread
1126 // executing all instructions is the main thread only we can ignore
1127 // threading. Also, thread-local objects do not require threading reasoning.
1128 // Finally, we can ignore threading if either access is executed in an
1129 // aligned region.
1130 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1131 if (IsThreadLocalObj || AllInSameNoSyncFn)
1132 return true;
1133 const auto *FnExecDomainAA =
1134 I.getFunction() == &Scope
1135 ? ExecDomainAA
1136 : A.lookupAAFor<AAExecutionDomain>(
1137 IRPosition::function(*I.getFunction()), &QueryingAA,
1138 DepClassTy::NONE);
1139 if (!FnExecDomainAA)
1140 return false;
1141 if (InstIsExecutedInAlignedRegion ||
1142 (FindInterferingWrites &&
1143 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1144 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1145 return true;
1146 }
1147 if (InstIsExecutedByInitialThreadOnly &&
1148 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1149 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1150 return true;
1151 }
1152 return false;
1153 };
1154
1155 // Helper to determine if the access is executed by the same thread as the
1156 // given instruction, for now it is sufficient to avoid any potential
1157 // threading effects as we cannot deal with them anyway.
1158 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1159 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1160 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1161 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1162 };
1163
1164 // TODO: Use inter-procedural reachability and dominance.
1165 bool IsKnownNoRecurse;
1167 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1168 IsKnownNoRecurse);
1169
1170 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1171 // AAExecutionDomain) such that we allow scopes other than kernels as long
1172 // as the reaching kernels are disjoint.
1173 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1174 bool ObjHasKernelLifetime = false;
1175 const bool UseDominanceReasoning =
1176 FindInterferingWrites && IsKnownNoRecurse;
1177 const DominatorTree *DT =
1178 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope);
1179
1180 // Helper to check if a value has "kernel lifetime", that is it will not
1181 // outlive a GPU kernel. This is true for shared, constant, and local
1182 // globals on AMD and NVIDIA GPUs.
1183 auto HasKernelLifetime = [&](Value *V, Module &M) {
1184 if (!AA::isGPU(M))
1185 return false;
1186 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1187 case AA::GPUAddressSpace::Shared:
1188 case AA::GPUAddressSpace::Constant:
1189 case AA::GPUAddressSpace::Local:
1190 return true;
1191 default:
1192 return false;
1193 };
1194 };
1195
1196 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1197 // to determine if we should look at reachability from the callee. For
1198 // certain pointers we know the lifetime and we do not have to step into the
1199 // callee to determine reachability as the pointer would be dead in the
1200 // callee. See the conditional initialization below.
1201 std::function<bool(const Function &)> IsLiveInCalleeCB;
1202
1203 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1204 // If the alloca containing function is not recursive the alloca
1205 // must be dead in the callee.
1206 const Function *AIFn = AI->getFunction();
1207 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1208 bool IsKnownNoRecurse;
1210 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1211 IsKnownNoRecurse)) {
1212 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1213 }
1214 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1215 // If the global has kernel lifetime we can stop if we reach a kernel
1216 // as it is "dead" in the (unknown) callees.
1217 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1218 if (ObjHasKernelLifetime)
1219 IsLiveInCalleeCB = [&A](const Function &Fn) {
1220 return !A.getInfoCache().isKernel(Fn);
1221 };
1222 }
1223
1224 // Set of accesses/instructions that will overwrite the result and are
1225 // therefore blockers in the reachability traversal.
1226 AA::InstExclusionSetTy ExclusionSet;
1227
1228 auto AccessCB = [&](const Access &Acc, bool Exact) {
1229 Function *AccScope = Acc.getRemoteInst()->getFunction();
1230 bool AccInSameScope = AccScope == &Scope;
1231
1232 // If the object has kernel lifetime we can ignore accesses only reachable
1233 // by other kernels. For now we only skip accesses *in* other kernels.
1234 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1235 A.getInfoCache().isKernel(*AccScope))
1236 return true;
1237
1238 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1239 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1240 ExclusionSet.insert(Acc.getRemoteInst());
1241 }
1242
1243 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1244 (!FindInterferingReads || !Acc.isRead()))
1245 return true;
1246
1247 bool Dominates = FindInterferingWrites && DT && Exact &&
1248 Acc.isMustAccess() && AccInSameScope &&
1249 DT->dominates(Acc.getRemoteInst(), &I);
1250 if (Dominates)
1251 DominatingWrites.insert(&Acc);
1252
1253 // Track if all interesting accesses are in the same `nosync` function as
1254 // the given instruction.
1255 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1256
1257 InterferingAccesses.push_back({&Acc, Exact});
1258 return true;
1259 };
1260 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1261 return false;
1262
1263 HasBeenWrittenTo = !DominatingWrites.empty();
1264
1265 // Dominating writes form a chain, find the least/lowest member.
1266 Instruction *LeastDominatingWriteInst = nullptr;
1267 for (const Access *Acc : DominatingWrites) {
1268 if (!LeastDominatingWriteInst) {
1269 LeastDominatingWriteInst = Acc->getRemoteInst();
1270 } else if (DT->dominates(LeastDominatingWriteInst,
1271 Acc->getRemoteInst())) {
1272 LeastDominatingWriteInst = Acc->getRemoteInst();
1273 }
1274 }
1275
1276 // Helper to determine if we can skip a specific write access.
1277 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1278 if (SkipCB && SkipCB(Acc))
1279 return true;
1280 if (!CanIgnoreThreading(Acc))
1281 return false;
1282
1283 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1284 // If we successfully excluded all effects we are interested in, the
1285 // access can be skipped.
1286 bool ReadChecked = !FindInterferingReads;
1287 bool WriteChecked = !FindInterferingWrites;
1288
1289 // If the instruction cannot reach the access, the former does not
1290 // interfere with what the access reads.
1291 if (!ReadChecked) {
1292 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1293 &ExclusionSet, IsLiveInCalleeCB))
1294 ReadChecked = true;
1295 }
1296 // If the instruction cannot be reach from the access, the latter does not
1297 // interfere with what the instruction reads.
1298 if (!WriteChecked) {
1299 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1300 &ExclusionSet, IsLiveInCalleeCB))
1301 WriteChecked = true;
1302 }
1303
1304 // If we still might be affected by the write of the access but there are
1305 // dominating writes in the function of the instruction
1306 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1307 // by them. This would have happend above if they are all in the same
1308 // function, so we only check the inter-procedural case. Effectively, we
1309 // want to show that there is no call after the dominting write that might
1310 // reach the access, and when it returns reach the instruction with the
1311 // updated value. To this end, we iterate all call sites, check if they
1312 // might reach the instruction without going through another access
1313 // (ExclusionSet) and at the same time might reach the access. However,
1314 // that is all part of AAInterFnReachability.
1315 if (!WriteChecked && HasBeenWrittenTo &&
1316 Acc.getRemoteInst()->getFunction() != &Scope) {
1317
1318 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1319 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1320 if (FnReachabilityAA) {
1321 // Without going backwards in the call tree, can we reach the access
1322 // from the least dominating write. Do not allow to pass the
1323 // instruction itself either.
1324 bool Inserted = ExclusionSet.insert(&I).second;
1325
1326 if (!FnReachabilityAA->instructionCanReach(
1327 A, *LeastDominatingWriteInst,
1328 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1329 WriteChecked = true;
1330
1331 if (Inserted)
1332 ExclusionSet.erase(&I);
1333 }
1334 }
1335
1336 if (ReadChecked && WriteChecked)
1337 return true;
1338
1339 if (!DT || !UseDominanceReasoning)
1340 return false;
1341 if (!DominatingWrites.count(&Acc))
1342 return false;
1343 return LeastDominatingWriteInst != Acc.getRemoteInst();
1344 };
1345
1346 // Run the user callback on all accesses we cannot skip and return if
1347 // that succeeded for all or not.
1348 for (auto &It : InterferingAccesses) {
1349 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1350 !CanSkipAccess(*It.first, It.second)) {
1351 if (!UserCB(*It.first, It.second))
1352 return false;
1353 }
1354 }
1355 return true;
1356 }
1357
1358 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1359 const AAPointerInfo &OtherAA,
1360 CallBase &CB) {
1361 using namespace AA::PointerInfo;
1362 if (!OtherAA.getState().isValidState() || !isValidState())
1363 return indicatePessimisticFixpoint();
1364
1365 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1366 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1367 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1368 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1369
1370 // Combine the accesses bin by bin.
1371 const auto &State = OtherAAImpl.getState();
1372 for (const auto &It : State) {
1373 for (auto Index : It.getSecond()) {
1374 const auto &RAcc = State.getAccess(Index);
1375 if (IsByval && !RAcc.isRead())
1376 continue;
1377 bool UsedAssumedInformation = false;
1378 AccessKind AK = RAcc.getKind();
1379 auto Content = A.translateArgumentToCallSiteContent(
1380 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1381 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1382 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1383
1384 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1385 RAcc.getType(), RAcc.getRemoteInst());
1386 }
1387 }
1388 return Changed;
1389 }
1390
1391 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1392 const OffsetInfo &Offsets, CallBase &CB,
1393 bool IsMustAcc) {
1394 using namespace AA::PointerInfo;
1395 if (!OtherAA.getState().isValidState() || !isValidState())
1396 return indicatePessimisticFixpoint();
1397
1398 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1399
1400 // Combine the accesses bin by bin.
1401 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1402 const auto &State = OtherAAImpl.getState();
1403 for (const auto &It : State) {
1404 for (auto Index : It.getSecond()) {
1405 const auto &RAcc = State.getAccess(Index);
1406 if (!IsMustAcc && RAcc.isAssumption())
1407 continue;
1408 for (auto Offset : Offsets) {
1409 auto NewRanges = Offset == AA::RangeTy::Unknown
1411 : RAcc.getRanges();
1412 if (!NewRanges.isUnknown()) {
1413 NewRanges.addToAllOffsets(Offset);
1414 }
1415 AccessKind AK = RAcc.getKind();
1416 if (!IsMustAcc)
1417 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1418 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1419 RAcc.getType(), RAcc.getRemoteInst());
1420 }
1421 }
1422 }
1423 return Changed;
1424 }
1425
1426 /// Statistic tracking for all AAPointerInfo implementations.
1427 /// See AbstractAttribute::trackStatistics().
1428 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1429
1430 /// Dump the state into \p O.
1431 void dumpState(raw_ostream &O) {
1432 for (auto &It : OffsetBins) {
1433 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1434 << "] : " << It.getSecond().size() << "\n";
1435 for (auto AccIndex : It.getSecond()) {
1436 auto &Acc = AccessList[AccIndex];
1437 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1438 if (Acc.getLocalInst() != Acc.getRemoteInst())
1439 O << " --> " << *Acc.getRemoteInst()
1440 << "\n";
1441 if (!Acc.isWrittenValueYetUndetermined()) {
1442 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1443 O << " - c: func " << Acc.getWrittenValue()->getName()
1444 << "\n";
1445 else if (Acc.getWrittenValue())
1446 O << " - c: " << *Acc.getWrittenValue() << "\n";
1447 else
1448 O << " - c: <unknown>\n";
1449 }
1450 }
1451 }
1452 }
1453};
1454
1455struct AAPointerInfoFloating : public AAPointerInfoImpl {
1457 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1458 : AAPointerInfoImpl(IRP, A) {}
1459
1460 /// Deal with an access and signal if it was handled successfully.
1461 bool handleAccess(Attributor &A, Instruction &I,
1462 std::optional<Value *> Content, AccessKind Kind,
1463 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1464 Type &Ty) {
1465 using namespace AA::PointerInfo;
1467 const DataLayout &DL = A.getDataLayout();
1468 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1469 if (!AccessSize.isScalable())
1470 Size = AccessSize.getFixedValue();
1471
1472 // Make a strictly ascending list of offsets as required by addAccess()
1473 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1474 llvm::sort(OffsetsSorted);
1475
1477 if (!VT || VT->getElementCount().isScalable() ||
1478 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1479 (*Content)->getType() != VT ||
1480 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1481 Changed =
1482 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1483 } else {
1484 // Handle vector stores with constant content element-wise.
1485 // TODO: We could look for the elements or create instructions
1486 // representing them.
1487 // TODO: We need to push the Content into the range abstraction
1488 // (AA::RangeTy) to allow different content values for different
1489 // ranges. ranges. Hence, support vectors storing different values.
1490 Type *ElementType = VT->getElementType();
1491 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1492 auto *ConstContent = cast<Constant>(*Content);
1493 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1494 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1495
1496 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1497 Value *ElementContent = ConstantExpr::getExtractElement(
1498 ConstContent, ConstantInt::get(Int32Ty, i));
1499
1500 // Add the element access.
1501 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1502 ElementContent, Kind, ElementType);
1503
1504 // Advance the offsets for the next element.
1505 for (auto &ElementOffset : ElementOffsets)
1506 ElementOffset += ElementSize;
1507 }
1508 }
1509 return true;
1510 };
1511
1512 /// See AbstractAttribute::updateImpl(...).
1513 ChangeStatus updateImpl(Attributor &A) override;
1514
1515 /// If the indices to \p GEP can be traced to constants, incorporate all
1516 /// of these into \p UsrOI.
1517 ///
1518 /// \return true iff \p UsrOI is updated.
1519 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1520 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1521 const GEPOperator *GEP);
1522
1523 /// See AbstractAttribute::trackStatistics()
1524 void trackStatistics() const override {
1525 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1526 }
1527};
1528
1529bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1530 const DataLayout &DL,
1531 OffsetInfo &UsrOI,
1532 const OffsetInfo &PtrOI,
1533 const GEPOperator *GEP) {
1534 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1535 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1536 APInt ConstantOffset(BitWidth, 0);
1537
1538 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1539 "Don't look for constant values if the offset has already been "
1540 "determined to be unknown.");
1541
1542 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1543 UsrOI.setUnknown();
1544 return true;
1545 }
1546
1547 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1548 << (VariableOffsets.empty() ? "" : "not") << " constant "
1549 << *GEP << "\n");
1550
1551 auto Union = PtrOI;
1552 Union.addToAll(ConstantOffset.getSExtValue());
1553
1554 // Each VI in VariableOffsets has a set of potential constant values. Every
1555 // combination of elements, picked one each from these sets, is separately
1556 // added to the original set of offsets, thus resulting in more offsets.
1557 for (const auto &VI : VariableOffsets) {
1558 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1559 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1560 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1561 UsrOI.setUnknown();
1562 return true;
1563 }
1564
1565 // UndefValue is treated as a zero, which leaves Union as is.
1566 if (PotentialConstantsAA->undefIsContained())
1567 continue;
1568
1569 // We need at least one constant in every set to compute an actual offset.
1570 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1571 // don't actually exist. In other words, the absence of constant values
1572 // implies that the operation can be assumed dead for now.
1573 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1574 if (AssumedSet.empty())
1575 return false;
1576
1577 OffsetInfo Product;
1578 for (const auto &ConstOffset : AssumedSet) {
1579 auto CopyPerOffset = Union;
1580 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1581 VI.second.getZExtValue());
1582 Product.merge(CopyPerOffset);
1583 }
1584 Union = Product;
1585 }
1586
1587 UsrOI = std::move(Union);
1588 return true;
1589}
1590
1591ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1592 using namespace AA::PointerInfo;
1594 const DataLayout &DL = A.getDataLayout();
1595 Value &AssociatedValue = getAssociatedValue();
1596
1597 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1598 OffsetInfoMap[&AssociatedValue].insert(0);
1599
1600 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1601 // One does not simply walk into a map and assign a reference to a possibly
1602 // new location. That can cause an invalidation before the assignment
1603 // happens, like so:
1604 //
1605 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1606 //
1607 // The RHS is a reference that may be invalidated by an insertion caused by
1608 // the LHS. So we ensure that the side-effect of the LHS happens first.
1609
1610 assert(OffsetInfoMap.contains(CurPtr) &&
1611 "CurPtr does not exist in the map!");
1612
1613 auto &UsrOI = OffsetInfoMap[Usr];
1614 auto &PtrOI = OffsetInfoMap[CurPtr];
1615 assert(!PtrOI.isUnassigned() &&
1616 "Cannot pass through if the input Ptr was not visited!");
1617 UsrOI.merge(PtrOI);
1618 Follow = true;
1619 return true;
1620 };
1621
1622 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1623 Value *CurPtr = U.get();
1624 User *Usr = U.getUser();
1625 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1626 << "\n");
1627 assert(OffsetInfoMap.count(CurPtr) &&
1628 "The current pointer offset should have been seeded!");
1629 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1630 "Current pointer should be assigned");
1631
1632 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1633 if (CE->isCast())
1634 return HandlePassthroughUser(Usr, CurPtr, Follow);
1635 if (!isa<GEPOperator>(CE)) {
1636 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1637 << "\n");
1638 return false;
1639 }
1640 }
1641 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1642 // Note the order here, the Usr access might change the map, CurPtr is
1643 // already in it though.
1644 auto &UsrOI = OffsetInfoMap[Usr];
1645 auto &PtrOI = OffsetInfoMap[CurPtr];
1646
1647 if (UsrOI.isUnknown())
1648 return true;
1649
1650 if (PtrOI.isUnknown()) {
1651 Follow = true;
1652 UsrOI.setUnknown();
1653 return true;
1654 }
1655
1656 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1657 return true;
1658 }
1659 if (isa<PtrToIntInst>(Usr))
1660 return false;
1661 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1662 return HandlePassthroughUser(Usr, CurPtr, Follow);
1663 // Returns are allowed if they are in the associated functions. Users can
1664 // then check the call site return. Returns from other functions can't be
1665 // tracked and are cause for invalidation.
1666 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1667 if (RI->getFunction() == getAssociatedFunction()) {
1668 auto &PtrOI = OffsetInfoMap[CurPtr];
1669 Changed |= setReachesReturn(PtrOI);
1670 return true;
1671 }
1672 return false;
1673 }
1674
1675 // For PHIs we need to take care of the recurrence explicitly as the value
1676 // might change while we iterate through a loop. For now, we give up if
1677 // the PHI is not invariant.
1678 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1679 // Note the order here, the Usr access might change the map, CurPtr is
1680 // already in it though.
1681 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1682 auto &UsrOI = PhiIt->second;
1683 auto &PtrOI = OffsetInfoMap[CurPtr];
1684
1685 // Check if the PHI operand has already an unknown offset as we can't
1686 // improve on that anymore.
1687 if (PtrOI.isUnknown()) {
1688 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1689 << *CurPtr << " in " << *PHI << "\n");
1690 Follow = !UsrOI.isUnknown();
1691 UsrOI.setUnknown();
1692 return true;
1693 }
1694
1695 // Check if the PHI is invariant (so far).
1696 if (UsrOI == PtrOI) {
1697 assert(!PtrOI.isUnassigned() &&
1698 "Cannot assign if the current Ptr was not visited!");
1699 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1700 return true;
1701 }
1702
1703 // Check if the PHI operand can be traced back to AssociatedValue.
1704 APInt Offset(
1705 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1706 0);
1707 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1708 DL, Offset, /* AllowNonInbounds */ true);
1709 auto It = OffsetInfoMap.find(CurPtrBase);
1710 if (It == OffsetInfoMap.end()) {
1711 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1712 << *CurPtr << " in " << *PHI
1713 << " (base: " << *CurPtrBase << ")\n");
1714 UsrOI.setUnknown();
1715 Follow = true;
1716 return true;
1717 }
1718
1719 // Check if the PHI operand is not dependent on the PHI itself. Every
1720 // recurrence is a cyclic net of PHIs in the data flow, and has an
1721 // equivalent Cycle in the control flow. One of those PHIs must be in the
1722 // header of that control flow Cycle. This is independent of the choice of
1723 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1724 // every Cycle header; if such a node is marked unknown, this will
1725 // eventually propagate through the whole net of PHIs in the recurrence.
1726 const auto *CI =
1727 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1728 *PHI->getFunction());
1729 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1730 auto BaseOI = It->getSecond();
1731 BaseOI.addToAll(Offset.getZExtValue());
1732 if (IsFirstPHIUser || BaseOI == UsrOI) {
1733 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1734 << " in " << *Usr << "\n");
1735 return HandlePassthroughUser(Usr, CurPtr, Follow);
1736 }
1737
1738 LLVM_DEBUG(
1739 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1740 << *CurPtr << " in " << *PHI << "\n");
1741 UsrOI.setUnknown();
1742 Follow = true;
1743 return true;
1744 }
1745
1746 UsrOI.merge(PtrOI);
1747 Follow = true;
1748 return true;
1749 }
1750
1751 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1752 // If the access is to a pointer that may or may not be the associated
1753 // value, e.g. due to a PHI, we cannot assume it will be read.
1754 AccessKind AK = AccessKind::AK_R;
1755 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1756 AK = AccessKind(AK | AccessKind::AK_MUST);
1757 else
1758 AK = AccessKind(AK | AccessKind::AK_MAY);
1759 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1760 OffsetInfoMap[CurPtr].Offsets, Changed,
1761 *LoadI->getType()))
1762 return false;
1763
1764 auto IsAssumption = [](Instruction &I) {
1765 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1766 return II->isAssumeLikeIntrinsic();
1767 return false;
1768 };
1769
1770 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1771 // Check if the assumption and the load are executed together without
1772 // memory modification.
1773 do {
1774 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1775 return true;
1776 FromI = FromI->getNextNode();
1777 } while (FromI && FromI != ToI);
1778 return false;
1779 };
1780
1781 BasicBlock *BB = LoadI->getParent();
1782 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1783 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1784 return false;
1785 BasicBlock *IntrBB = IntrI.getParent();
1786 if (IntrI.getParent() == BB) {
1787 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1788 return false;
1789 } else {
1790 auto PredIt = pred_begin(IntrBB);
1791 if (PredIt == pred_end(IntrBB))
1792 return false;
1793 if ((*PredIt) != BB)
1794 return false;
1795 if (++PredIt != pred_end(IntrBB))
1796 return false;
1797 for (auto *SuccBB : successors(BB)) {
1798 if (SuccBB == IntrBB)
1799 continue;
1800 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1801 continue;
1802 return false;
1803 }
1804 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1805 return false;
1806 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1807 return false;
1808 }
1809 return true;
1810 };
1811
1812 std::pair<Value *, IntrinsicInst *> Assumption;
1813 for (const Use &LoadU : LoadI->uses()) {
1814 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1815 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1816 continue;
1817 for (const Use &CmpU : CmpI->uses()) {
1818 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1819 if (!IsValidAssume(*IntrI))
1820 continue;
1821 int Idx = CmpI->getOperandUse(0) == LoadU;
1822 Assumption = {CmpI->getOperand(Idx), IntrI};
1823 break;
1824 }
1825 }
1826 }
1827 if (Assumption.first)
1828 break;
1829 }
1830
1831 // Check if we found an assumption associated with this load.
1832 if (!Assumption.first || !Assumption.second)
1833 return true;
1834
1835 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1836 << *Assumption.second << ": " << *LoadI
1837 << " == " << *Assumption.first << "\n");
1838 bool UsedAssumedInformation = false;
1839 std::optional<Value *> Content = nullptr;
1840 if (Assumption.first)
1841 Content =
1842 A.getAssumedSimplified(*Assumption.first, *this,
1843 UsedAssumedInformation, AA::Interprocedural);
1844 return handleAccess(
1845 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1846 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1847 }
1848
1849 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1850 ArrayRef<Value *> OtherOps, AccessKind AK) {
1851 for (auto *OtherOp : OtherOps) {
1852 if (OtherOp == CurPtr) {
1853 LLVM_DEBUG(
1854 dbgs()
1855 << "[AAPointerInfo] Escaping use in store like instruction " << I
1856 << "\n");
1857 return false;
1858 }
1859 }
1860
1861 // If the access is to a pointer that may or may not be the associated
1862 // value, e.g. due to a PHI, we cannot assume it will be written.
1863 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1864 AK = AccessKind(AK | AccessKind::AK_MUST);
1865 else
1866 AK = AccessKind(AK | AccessKind::AK_MAY);
1867 bool UsedAssumedInformation = false;
1868 std::optional<Value *> Content = nullptr;
1869 if (ValueOp)
1870 Content = A.getAssumedSimplified(
1871 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1872 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1873 Changed, ValueTy);
1874 };
1875
1876 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1877 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1878 *StoreI->getValueOperand()->getType(),
1879 {StoreI->getValueOperand()}, AccessKind::AK_W);
1880 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1881 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1882 {RMWI->getValOperand()}, AccessKind::AK_RW);
1883 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1884 return HandleStoreLike(
1885 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1886 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1887 AccessKind::AK_RW);
1888
1889 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1890 if (CB->isLifetimeStartOrEnd())
1891 return true;
1892 const auto *TLI =
1893 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1894 if (getFreedOperand(CB, TLI) == U)
1895 return true;
1896 if (CB->isArgOperand(&U)) {
1897 unsigned ArgNo = CB->getArgOperandNo(&U);
1898 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1899 *this, IRPosition::callsite_argument(*CB, ArgNo),
1901 if (!CSArgPI)
1902 return false;
1903 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1904 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1905 IsArgMustAcc) |
1906 Changed;
1907 if (!CSArgPI->reachesReturn())
1908 return isValidState();
1909
1911 if (!Callee || Callee->arg_size() <= ArgNo)
1912 return false;
1913 bool UsedAssumedInformation = false;
1914 auto ReturnedValue = A.getAssumedSimplified(
1915 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1917 auto *ReturnedArg =
1918 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1919 auto *Arg = Callee->getArg(ArgNo);
1920 if (ReturnedArg && Arg != ReturnedArg)
1921 return true;
1922 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1923 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1925 if (!CSRetPI)
1926 return false;
1927 OffsetInfo OI = OffsetInfoMap[CurPtr];
1928 CSArgPI->addReturnedOffsetsTo(OI);
1929 Changed =
1930 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1931 return isValidState();
1932 }
1933 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1934 << "\n");
1935 return false;
1936 }
1937
1938 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1939 return false;
1940 };
1941 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1942 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1943 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1944 if (OffsetInfoMap.count(NewU)) {
1945 LLVM_DEBUG({
1946 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1947 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1948 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1949 << "\n";
1950 }
1951 });
1952 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1953 }
1954 bool Unused;
1955 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1956 };
1957 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1958 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1959 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1960 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1961 return indicatePessimisticFixpoint();
1962 }
1963
1964 LLVM_DEBUG({
1965 dbgs() << "Accesses by bin after update:\n";
1966 dumpState(dbgs());
1967 });
1968
1969 return Changed;
1970}
1971
1972struct AAPointerInfoReturned final : AAPointerInfoImpl {
1973 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1974 : AAPointerInfoImpl(IRP, A) {}
1975
1976 /// See AbstractAttribute::updateImpl(...).
1977 ChangeStatus updateImpl(Attributor &A) override {
1978 return indicatePessimisticFixpoint();
1979 }
1980
1981 /// See AbstractAttribute::trackStatistics()
1982 void trackStatistics() const override {
1983 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1984 }
1985};
1986
1987struct AAPointerInfoArgument final : AAPointerInfoFloating {
1988 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1989 : AAPointerInfoFloating(IRP, A) {}
1990
1991 /// See AbstractAttribute::trackStatistics()
1992 void trackStatistics() const override {
1993 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1994 }
1995};
1996
1997struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
1998 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
1999 : AAPointerInfoFloating(IRP, A) {}
2000
2001 /// See AbstractAttribute::updateImpl(...).
2002 ChangeStatus updateImpl(Attributor &A) override {
2003 using namespace AA::PointerInfo;
2004 // We handle memory intrinsics explicitly, at least the first (=
2005 // destination) and second (=source) arguments as we know how they are
2006 // accessed.
2007 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2008 int64_t LengthVal = AA::RangeTy::Unknown;
2009 if (auto Length = MI->getLengthInBytes())
2010 LengthVal = Length->getSExtValue();
2011 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2012 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2013 if (ArgNo > 1) {
2014 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2015 << *MI << "\n");
2016 return indicatePessimisticFixpoint();
2017 } else {
2018 auto Kind =
2019 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2020 Changed =
2021 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2022 }
2023 LLVM_DEBUG({
2024 dbgs() << "Accesses by bin after update:\n";
2025 dumpState(dbgs());
2026 });
2027
2028 return Changed;
2029 }
2030
2031 // TODO: Once we have call site specific value information we can provide
2032 // call site specific liveness information and then it makes
2033 // sense to specialize attributes for call sites arguments instead of
2034 // redirecting requests to the callee argument.
2035 Argument *Arg = getAssociatedArgument();
2036 if (Arg) {
2037 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2038 auto *ArgAA =
2039 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2040 if (ArgAA && ArgAA->getState().isValidState())
2041 return translateAndAddStateFromCallee(A, *ArgAA,
2042 *cast<CallBase>(getCtxI()));
2043 if (!Arg->getParent()->isDeclaration())
2044 return indicatePessimisticFixpoint();
2045 }
2046
2047 bool IsKnownNoCapture;
2049 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2050 return indicatePessimisticFixpoint();
2051
2052 bool IsKnown = false;
2053 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2054 return ChangeStatus::UNCHANGED;
2055 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2056 auto Kind =
2057 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2058 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2059 nullptr);
2060 }
2061
2062 /// See AbstractAttribute::trackStatistics()
2063 void trackStatistics() const override {
2064 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2065 }
2066};
2067
2068struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2069 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2070 : AAPointerInfoFloating(IRP, A) {}
2071
2072 /// See AbstractAttribute::trackStatistics()
2073 void trackStatistics() const override {
2074 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2075 }
2076};
2077} // namespace
2078
2079/// -----------------------NoUnwind Function Attribute--------------------------
2080
2081namespace {
2082struct AANoUnwindImpl : AANoUnwind {
2083 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2084
2085 /// See AbstractAttribute::initialize(...).
2086 void initialize(Attributor &A) override {
2087 bool IsKnown;
2089 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2090 (void)IsKnown;
2091 }
2092
2093 const std::string getAsStr(Attributor *A) const override {
2094 return getAssumed() ? "nounwind" : "may-unwind";
2095 }
2096
2097 /// See AbstractAttribute::updateImpl(...).
2098 ChangeStatus updateImpl(Attributor &A) override {
2099 auto Opcodes = {
2100 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2101 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2102 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2103
2104 auto CheckForNoUnwind = [&](Instruction &I) {
2105 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2106 return true;
2107
2108 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2109 bool IsKnownNoUnwind;
2111 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2112 IsKnownNoUnwind);
2113 }
2114 return false;
2115 };
2116
2117 bool UsedAssumedInformation = false;
2118 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2119 UsedAssumedInformation))
2120 return indicatePessimisticFixpoint();
2121
2122 return ChangeStatus::UNCHANGED;
2123 }
2124};
2125
2126struct AANoUnwindFunction final : public AANoUnwindImpl {
2127 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2128 : AANoUnwindImpl(IRP, A) {}
2129
2130 /// See AbstractAttribute::trackStatistics()
2131 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2132};
2133
2134/// NoUnwind attribute deduction for a call sites.
2135struct AANoUnwindCallSite final
2136 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2137 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2138 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2139
2140 /// See AbstractAttribute::trackStatistics()
2141 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2142};
2143} // namespace
2144
2145/// ------------------------ NoSync Function Attribute -------------------------
2146
2147bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2148 switch (CB.getIntrinsicID()) {
2149 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2150 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2151 case Intrinsic::nvvm_barrier_cta_red_and_aligned_all:
2152 case Intrinsic::nvvm_barrier_cta_red_and_aligned_count:
2153 case Intrinsic::nvvm_barrier_cta_red_or_aligned_all:
2154 case Intrinsic::nvvm_barrier_cta_red_or_aligned_count:
2155 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_all:
2156 case Intrinsic::nvvm_barrier_cta_red_popc_aligned_count:
2157 return true;
2158 case Intrinsic::amdgcn_s_barrier:
2159 if (ExecutedAligned)
2160 return true;
2161 break;
2162 default:
2163 break;
2164 }
2165 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2166}
2167
2169 if (!I->isAtomic())
2170 return false;
2171
2172 if (auto *FI = dyn_cast<FenceInst>(I))
2173 // All legal orderings for fence are stronger than monotonic.
2174 return FI->getSyncScopeID() != SyncScope::SingleThread;
2175 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2176 // Unordered is not a legal ordering for cmpxchg.
2177 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2178 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2179 }
2180
2181 AtomicOrdering Ordering;
2182 switch (I->getOpcode()) {
2183 case Instruction::AtomicRMW:
2184 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2185 break;
2186 case Instruction::Store:
2187 Ordering = cast<StoreInst>(I)->getOrdering();
2188 break;
2189 case Instruction::Load:
2190 Ordering = cast<LoadInst>(I)->getOrdering();
2191 break;
2192 default:
2194 "New atomic operations need to be known in the attributor.");
2195 }
2196
2197 return (Ordering != AtomicOrdering::Unordered &&
2198 Ordering != AtomicOrdering::Monotonic);
2199}
2200
2201/// Return true if this intrinsic is nosync. This is only used for intrinsics
2202/// which would be nosync except that they have a volatile flag. All other
2203/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2205 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2206 return !MI->isVolatile();
2207 return false;
2208}
2209
2210namespace {
2211struct AANoSyncImpl : AANoSync {
2212 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2213
2214 /// See AbstractAttribute::initialize(...).
2215 void initialize(Attributor &A) override {
2216 bool IsKnown;
2217 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2218 DepClassTy::NONE, IsKnown));
2219 (void)IsKnown;
2220 }
2221
2222 const std::string getAsStr(Attributor *A) const override {
2223 return getAssumed() ? "nosync" : "may-sync";
2224 }
2225
2226 /// See AbstractAttribute::updateImpl(...).
2227 ChangeStatus updateImpl(Attributor &A) override;
2228};
2229
2230ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2231
2232 auto CheckRWInstForNoSync = [&](Instruction &I) {
2233 return AA::isNoSyncInst(A, I, *this);
2234 };
2235
2236 auto CheckForNoSync = [&](Instruction &I) {
2237 // At this point we handled all read/write effects and they are all
2238 // nosync, so they can be skipped.
2239 if (I.mayReadOrWriteMemory())
2240 return true;
2241
2242 bool IsKnown;
2243 CallBase &CB = cast<CallBase>(I);
2246 IsKnown))
2247 return true;
2248
2249 // non-convergent and readnone imply nosync.
2250 return !CB.isConvergent();
2251 };
2252
2253 bool UsedAssumedInformation = false;
2254 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
2255 UsedAssumedInformation) ||
2256 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
2257 UsedAssumedInformation))
2258 return indicatePessimisticFixpoint();
2259
2261}
2262
2263struct AANoSyncFunction final : public AANoSyncImpl {
2264 AANoSyncFunction(const IRPosition &IRP, Attributor &A)
2265 : AANoSyncImpl(IRP, A) {}
2266
2267 /// See AbstractAttribute::trackStatistics()
2268 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
2269};
2270
2271/// NoSync attribute deduction for a call sites.
2272struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> {
2273 AANoSyncCallSite(const IRPosition &IRP, Attributor &A)
2274 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {}
2275
2276 /// See AbstractAttribute::trackStatistics()
2277 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
2278};
2279} // namespace
2280
2281/// ------------------------ No-Free Attributes ----------------------------
2282
2283namespace {
2284struct AANoFreeImpl : public AANoFree {
2285 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {}
2286
2287 /// See AbstractAttribute::initialize(...).
2288 void initialize(Attributor &A) override {
2289 bool IsKnown;
2290 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(),
2291 DepClassTy::NONE, IsKnown));
2292 (void)IsKnown;
2293 }
2294
2295 /// See AbstractAttribute::updateImpl(...).
2296 ChangeStatus updateImpl(Attributor &A) override {
2297 auto CheckForNoFree = [&](Instruction &I) {
2298 bool IsKnown;
2301 DepClassTy::REQUIRED, IsKnown);
2302 };
2303
2304 bool UsedAssumedInformation = false;
2305 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
2306 UsedAssumedInformation))
2307 return indicatePessimisticFixpoint();
2308 return ChangeStatus::UNCHANGED;
2309 }
2310
2311 /// See AbstractAttribute::getAsStr().
2312 const std::string getAsStr(Attributor *A) const override {
2313 return getAssumed() ? "nofree" : "may-free";
2314 }
2315};
2316
2317struct AANoFreeFunction final : public AANoFreeImpl {
2318 AANoFreeFunction(const IRPosition &IRP, Attributor &A)
2319 : AANoFreeImpl(IRP, A) {}
2320
2321 /// See AbstractAttribute::trackStatistics()
2322 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
2323};
2324
2325/// NoFree attribute deduction for a call sites.
2326struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> {
2327 AANoFreeCallSite(const IRPosition &IRP, Attributor &A)
2328 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {}
2329
2330 /// See AbstractAttribute::trackStatistics()
2331 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
2332};
2333
2334/// NoFree attribute for floating values.
2335struct AANoFreeFloating : AANoFreeImpl {
2336 AANoFreeFloating(const IRPosition &IRP, Attributor &A)
2337 : AANoFreeImpl(IRP, A) {}
2338
2339 /// See AbstractAttribute::trackStatistics()
2340 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
2341
2342 /// See Abstract Attribute::updateImpl(...).
2343 ChangeStatus updateImpl(Attributor &A) override {
2344 const IRPosition &IRP = getIRPosition();
2345
2346 bool IsKnown;
2349 DepClassTy::OPTIONAL, IsKnown))
2350 return ChangeStatus::UNCHANGED;
2351
2352 Value &AssociatedValue = getIRPosition().getAssociatedValue();
2353 auto Pred = [&](const Use &U, bool &Follow) -> bool {
2354 Instruction *UserI = cast<Instruction>(U.getUser());
2355 if (auto *CB = dyn_cast<CallBase>(UserI)) {
2356 if (CB->isBundleOperand(&U))
2357 return false;
2358 if (!CB->isArgOperand(&U))
2359 return true;
2360 unsigned ArgNo = CB->getArgOperandNo(&U);
2361
2362 bool IsKnown;
2364 A, this, IRPosition::callsite_argument(*CB, ArgNo),
2365 DepClassTy::REQUIRED, IsKnown);
2366 }
2367
2368 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) ||
2369 isa<SelectInst>(UserI)) {
2370 Follow = true;
2371 return true;
2372 }
2373 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI))
2374 return true;
2375
2376 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition())
2377 return true;
2378
2379 // Unknown user.
2380 return false;
2381 };
2382 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
2383 return indicatePessimisticFixpoint();
2384
2385 return ChangeStatus::UNCHANGED;
2386 }
2387};
2388
2389/// NoFree attribute for a call site argument.
2390struct AANoFreeArgument final : AANoFreeFloating {
2391 AANoFreeArgument(const IRPosition &IRP, Attributor &A)
2392 : AANoFreeFloating(IRP, A) {}
2393
2394 /// See AbstractAttribute::trackStatistics()
2395 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
2396};
2397
2398/// NoFree attribute for call site arguments.
2399struct AANoFreeCallSiteArgument final : AANoFreeFloating {
2400 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A)
2401 : AANoFreeFloating(IRP, A) {}
2402
2403 /// See AbstractAttribute::updateImpl(...).
2404 ChangeStatus updateImpl(Attributor &A) override {
2405 // TODO: Once we have call site specific value information we can provide
2406 // call site specific liveness information and then it makes
2407 // sense to specialize attributes for call sites arguments instead of
2408 // redirecting requests to the callee argument.
2409 Argument *Arg = getAssociatedArgument();
2410 if (!Arg)
2411 return indicatePessimisticFixpoint();
2412 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2413 bool IsKnown;
2415 DepClassTy::REQUIRED, IsKnown))
2416 return ChangeStatus::UNCHANGED;
2417 return indicatePessimisticFixpoint();
2418 }
2419
2420 /// See AbstractAttribute::trackStatistics()
2421 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) };
2422};
2423
2424/// NoFree attribute for function return value.
2425struct AANoFreeReturned final : AANoFreeFloating {
2426 AANoFreeReturned(const IRPosition &IRP, Attributor &A)
2427 : AANoFreeFloating(IRP, A) {
2428 llvm_unreachable("NoFree is not applicable to function returns!");
2429 }
2430
2431 /// See AbstractAttribute::initialize(...).
2432 void initialize(Attributor &A) override {
2433 llvm_unreachable("NoFree is not applicable to function returns!");
2434 }
2435
2436 /// See AbstractAttribute::updateImpl(...).
2437 ChangeStatus updateImpl(Attributor &A) override {
2438 llvm_unreachable("NoFree is not applicable to function returns!");
2439 }
2440
2441 /// See AbstractAttribute::trackStatistics()
2442 void trackStatistics() const override {}
2443};
2444
2445/// NoFree attribute deduction for a call site return value.
2446struct AANoFreeCallSiteReturned final : AANoFreeFloating {
2447 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A)
2448 : AANoFreeFloating(IRP, A) {}
2449
2450 ChangeStatus manifest(Attributor &A) override {
2451 return ChangeStatus::UNCHANGED;
2452 }
2453 /// See AbstractAttribute::trackStatistics()
2454 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
2455};
2456} // namespace
2457
2458/// ------------------------ NonNull Argument Attribute ------------------------
2459
2461 Attribute::AttrKind ImpliedAttributeKind,
2462 bool IgnoreSubsumingPositions) {
2464 AttrKinds.push_back(Attribute::NonNull);
2467 AttrKinds.push_back(Attribute::Dereferenceable);
2468 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull))
2469 return true;
2470
2471 DominatorTree *DT = nullptr;
2472 AssumptionCache *AC = nullptr;
2473 InformationCache &InfoCache = A.getInfoCache();
2474 if (const Function *Fn = IRP.getAnchorScope()) {
2475 if (!Fn->isDeclaration()) {
2478 }
2479 }
2480
2482 if (IRP.getPositionKind() != IRP_RETURNED) {
2483 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()});
2484 } else {
2485 bool UsedAssumedInformation = false;
2486 if (!A.checkForAllInstructions(
2487 [&](Instruction &I) {
2488 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I});
2489 return true;
2490 },
2491 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret},
2492 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true))
2493 return false;
2494 }
2495
2496 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) {
2497 return !isKnownNonZero(
2498 VAC.getValue(),
2499 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI()));
2500 }))
2501 return false;
2502
2503 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(),
2504 Attribute::NonNull)});
2505 return true;
2506}
2507
2508namespace {
2509static int64_t getKnownNonNullAndDerefBytesForUse(
2510 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue,
2511 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
2512 TrackUse = false;
2513
2514 const Value *UseV = U->get();
2515 if (!UseV->getType()->isPointerTy())
2516 return 0;
2517
2518 // We need to follow common pointer manipulation uses to the accesses they
2519 // feed into. We can try to be smart to avoid looking through things we do not
2520 // like for now, e.g., non-inbounds GEPs.
2521 if (isa<CastInst>(I)) {
2522 TrackUse = true;
2523 return 0;
2524 }
2525
2527 TrackUse = true;
2528 return 0;
2529 }
2530
2531 Type *PtrTy = UseV->getType();
2532 const Function *F = I->getFunction();
2535 const DataLayout &DL = A.getInfoCache().getDL();
2536 if (const auto *CB = dyn_cast<CallBase>(I)) {
2537 if (CB->isBundleOperand(U)) {
2538 if (RetainedKnowledge RK = getKnowledgeFromUse(
2539 U, {Attribute::NonNull, Attribute::Dereferenceable})) {
2540 IsNonNull |=
2541 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined);
2542 return RK.ArgValue;
2543 }
2544 return 0;
2545 }
2546
2547 if (CB->isCallee(U)) {
2548 IsNonNull |= !NullPointerIsDefined;
2549 return 0;
2550 }
2551
2552 unsigned ArgNo = CB->getArgOperandNo(U);
2553 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
2554 // As long as we only use known information there is no need to track
2555 // dependences here.
2556 bool IsKnownNonNull;
2558 DepClassTy::NONE, IsKnownNonNull);
2559 IsNonNull |= IsKnownNonNull;
2560 auto *DerefAA =
2561 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE);
2562 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0;
2563 }
2564
2565 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
2566 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() ||
2567 Loc->Size.isScalable() || I->isVolatile())
2568 return 0;
2569
2570 int64_t Offset;
2571 const Value *Base =
2572 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL);
2573 if (Base && Base == &AssociatedValue) {
2574 int64_t DerefBytes = Loc->Size.getValue() + Offset;
2575 IsNonNull |= !NullPointerIsDefined;
2576 return std::max(int64_t(0), DerefBytes);
2577 }
2578
2579 /// Corner case when an offset is 0.
2581 /*AllowNonInbounds*/ true);
2582 if (Base && Base == &AssociatedValue && Offset == 0) {
2583 int64_t DerefBytes = Loc->Size.getValue();
2584 IsNonNull |= !NullPointerIsDefined;
2585 return std::max(int64_t(0), DerefBytes);
2586 }
2587
2588 return 0;
2589}
2590
2591struct AANonNullImpl : AANonNull {
2592 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {}
2593
2594 /// See AbstractAttribute::initialize(...).
2595 void initialize(Attributor &A) override {
2596 Value &V = *getAssociatedValue().stripPointerCasts();
2597 if (isa<ConstantPointerNull>(V)) {
2598 indicatePessimisticFixpoint();
2599 return;
2600 }
2601
2602 if (Instruction *CtxI = getCtxI())
2603 followUsesInMBEC(*this, A, getState(), *CtxI);
2604 }
2605
2606 /// See followUsesInMBEC
2607 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
2608 AANonNull::StateType &State) {
2609 bool IsNonNull = false;
2610 bool TrackUse = false;
2611 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
2612 IsNonNull, TrackUse);
2613 State.setKnown(IsNonNull);
2614 return TrackUse;
2615 }
2616
2617 /// See AbstractAttribute::getAsStr().
2618 const std::string getAsStr(Attributor *A) const override {
2619 return getAssumed() ? "nonnull" : "may-null";
2620 }
2621};
2622
2623/// NonNull attribute for a floating value.
2624struct AANonNullFloating : public AANonNullImpl {
2625 AANonNullFloating(const IRPosition &IRP, Attributor &A)
2626 : AANonNullImpl(IRP, A) {}
2627
2628 /// See AbstractAttribute::updateImpl(...).
2629 ChangeStatus updateImpl(Attributor &A) override {
2630 auto CheckIRP = [&](const IRPosition &IRP) {
2631 bool IsKnownNonNull;
2633 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull);
2634 };
2635
2636 bool Stripped;
2637 bool UsedAssumedInformation = false;
2638 Value *AssociatedValue = &getAssociatedValue();
2640 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
2641 AA::AnyScope, UsedAssumedInformation))
2642 Stripped = false;
2643 else
2644 Stripped =
2645 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
2646
2647 if (!Stripped) {
2648 bool IsKnown;
2649 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue))
2650 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) {
2651 return AA::hasAssumedIRAttr<Attribute::NonNull>(
2652 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL,
2653 IsKnown);
2654 }))
2655 return ChangeStatus::UNCHANGED;
2656 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue))
2658 A, this, IRPosition::value(*Select->getFalseValue()),
2659 DepClassTy::OPTIONAL, IsKnown) &&
2661 A, this, IRPosition::value(*Select->getTrueValue()),
2662 DepClassTy::OPTIONAL, IsKnown))
2663 return ChangeStatus::UNCHANGED;
2664
2665 // If we haven't stripped anything we might still be able to use a
2666 // different AA, but only if the IRP changes. Effectively when we
2667 // interpret this not as a call site value but as a floating/argument
2668 // value.
2669 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
2670 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP))
2671 return indicatePessimisticFixpoint();
2672 return ChangeStatus::UNCHANGED;
2673 }
2674
2675 for (const auto &VAC : Values)
2676 if (!CheckIRP(IRPosition::value(*VAC.getValue())))
2677 return indicatePessimisticFixpoint();
2678
2679 return ChangeStatus::UNCHANGED;
2680 }
2681
2682 /// See AbstractAttribute::trackStatistics()
2683 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2684};
2685
2686/// NonNull attribute for function return value.
2687struct AANonNullReturned final
2688 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2689 false, AANonNull::IRAttributeKind, false> {
2690 AANonNullReturned(const IRPosition &IRP, Attributor &A)
2691 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType,
2692 false, Attribute::NonNull, false>(IRP, A) {
2693 }
2694
2695 /// See AbstractAttribute::getAsStr().
2696 const std::string getAsStr(Attributor *A) const override {
2697 return getAssumed() ? "nonnull" : "may-null";
2698 }
2699
2700 /// See AbstractAttribute::trackStatistics()
2701 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2702};
2703
2704/// NonNull attribute for function argument.
2705struct AANonNullArgument final
2706 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> {
2707 AANonNullArgument(const IRPosition &IRP, Attributor &A)
2708 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {}
2709
2710 /// See AbstractAttribute::trackStatistics()
2711 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
2712};
2713
2714struct AANonNullCallSiteArgument final : AANonNullFloating {
2715 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A)
2716 : AANonNullFloating(IRP, A) {}
2717
2718 /// See AbstractAttribute::trackStatistics()
2719 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
2720};
2721
2722/// NonNull attribute for a call site return position.
2723struct AANonNullCallSiteReturned final
2724 : AACalleeToCallSite<AANonNull, AANonNullImpl> {
2725 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A)
2726 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {}
2727
2728 /// See AbstractAttribute::trackStatistics()
2729 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2730};
2731} // namespace
2732
2733/// ------------------------ Must-Progress Attributes --------------------------
2734namespace {
2735struct AAMustProgressImpl : public AAMustProgress {
2736 AAMustProgressImpl(const IRPosition &IRP, Attributor &A)
2737 : AAMustProgress(IRP, A) {}
2738
2739 /// See AbstractAttribute::initialize(...).
2740 void initialize(Attributor &A) override {
2741 bool IsKnown;
2743 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2744 (void)IsKnown;
2745 }
2746
2747 /// See AbstractAttribute::getAsStr()
2748 const std::string getAsStr(Attributor *A) const override {
2749 return getAssumed() ? "mustprogress" : "may-not-progress";
2750 }
2751};
2752
2753struct AAMustProgressFunction final : AAMustProgressImpl {
2754 AAMustProgressFunction(const IRPosition &IRP, Attributor &A)
2755 : AAMustProgressImpl(IRP, A) {}
2756
2757 /// See AbstractAttribute::updateImpl(...).
2758 ChangeStatus updateImpl(Attributor &A) override {
2759 bool IsKnown;
2761 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) {
2762 if (IsKnown)
2763 return indicateOptimisticFixpoint();
2764 return ChangeStatus::UNCHANGED;
2765 }
2766
2767 auto CheckForMustProgress = [&](AbstractCallSite ACS) {
2768 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction());
2769 bool IsKnownMustProgress;
2771 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress,
2772 /* IgnoreSubsumingPositions */ true);
2773 };
2774
2775 bool AllCallSitesKnown = true;
2776 if (!A.checkForAllCallSites(CheckForMustProgress, *this,
2777 /* RequireAllCallSites */ true,
2778 AllCallSitesKnown))
2779 return indicatePessimisticFixpoint();
2780
2781 return ChangeStatus::UNCHANGED;
2782 }
2783
2784 /// See AbstractAttribute::trackStatistics()
2785 void trackStatistics() const override {
2786 STATS_DECLTRACK_FN_ATTR(mustprogress)
2787 }
2788};
2789
2790/// MustProgress attribute deduction for a call sites.
2791struct AAMustProgressCallSite final : AAMustProgressImpl {
2792 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A)
2793 : AAMustProgressImpl(IRP, A) {}
2794
2795 /// See AbstractAttribute::updateImpl(...).
2796 ChangeStatus updateImpl(Attributor &A) override {
2797 // TODO: Once we have call site specific value information we can provide
2798 // call site specific liveness information and then it makes
2799 // sense to specialize attributes for call sites arguments instead of
2800 // redirecting requests to the callee argument.
2801 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
2802 bool IsKnownMustProgress;
2804 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress))
2805 return indicatePessimisticFixpoint();
2806 return ChangeStatus::UNCHANGED;
2807 }
2808
2809 /// See AbstractAttribute::trackStatistics()
2810 void trackStatistics() const override {
2811 STATS_DECLTRACK_CS_ATTR(mustprogress);
2812 }
2813};
2814} // namespace
2815
2816/// ------------------------ No-Recurse Attributes ----------------------------
2817
2818namespace {
2819struct AANoRecurseImpl : public AANoRecurse {
2820 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {}
2821
2822 /// See AbstractAttribute::initialize(...).
2823 void initialize(Attributor &A) override {
2824 bool IsKnown;
2826 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2827 (void)IsKnown;
2828 }
2829
2830 /// See AbstractAttribute::getAsStr()
2831 const std::string getAsStr(Attributor *A) const override {
2832 return getAssumed() ? "norecurse" : "may-recurse";
2833 }
2834};
2835
2836struct AANoRecurseFunction final : AANoRecurseImpl {
2837 AANoRecurseFunction(const IRPosition &IRP, Attributor &A)
2838 : AANoRecurseImpl(IRP, A) {}
2839
2840 /// See AbstractAttribute::updateImpl(...).
2841 ChangeStatus updateImpl(Attributor &A) override {
2842
2843 // If all live call sites are known to be no-recurse, we are as well.
2844 auto CallSitePred = [&](AbstractCallSite ACS) {
2845 bool IsKnownNoRecurse;
2847 A, this,
2848 IRPosition::function(*ACS.getInstruction()->getFunction()),
2849 DepClassTy::NONE, IsKnownNoRecurse))
2850 return false;
2851 return IsKnownNoRecurse;
2852 };
2853 bool UsedAssumedInformation = false;
2854 if (A.checkForAllCallSites(CallSitePred, *this, true,
2855 UsedAssumedInformation)) {
2856 // If we know all call sites and all are known no-recurse, we are done.
2857 // If all known call sites, which might not be all that exist, are known
2858 // to be no-recurse, we are not done but we can continue to assume
2859 // no-recurse. If one of the call sites we have not visited will become
2860 // live, another update is triggered.
2861 if (!UsedAssumedInformation)
2862 indicateOptimisticFixpoint();
2863 return ChangeStatus::UNCHANGED;
2864 }
2865
2866 const AAInterFnReachability *EdgeReachability =
2867 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(),
2868 DepClassTy::REQUIRED);
2869 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope()))
2870 return indicatePessimisticFixpoint();
2871 return ChangeStatus::UNCHANGED;
2872 }
2873
2874 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2875};
2876
2877/// NoRecurse attribute deduction for a call sites.
2878struct AANoRecurseCallSite final
2879 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> {
2880 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A)
2881 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {}
2882
2883 /// See AbstractAttribute::trackStatistics()
2884 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2885};
2886} // namespace
2887
2888/// ------------------------ No-Convergent Attribute --------------------------
2889
2890namespace {
2891struct AANonConvergentImpl : public AANonConvergent {
2892 AANonConvergentImpl(const IRPosition &IRP, Attributor &A)
2893 : AANonConvergent(IRP, A) {}
2894
2895 /// See AbstractAttribute::getAsStr()
2896 const std::string getAsStr(Attributor *A) const override {
2897 return getAssumed() ? "non-convergent" : "may-be-convergent";
2898 }
2899};
2900
2901struct AANonConvergentFunction final : AANonConvergentImpl {
2902 AANonConvergentFunction(const IRPosition &IRP, Attributor &A)
2903 : AANonConvergentImpl(IRP, A) {}
2904
2905 /// See AbstractAttribute::updateImpl(...).
2906 ChangeStatus updateImpl(Attributor &A) override {
2907 // If all function calls are known to not be convergent, we are not
2908 // convergent.
2909 auto CalleeIsNotConvergent = [&](Instruction &Inst) {
2910 CallBase &CB = cast<CallBase>(Inst);
2912 if (!Callee || Callee->isIntrinsic()) {
2913 return false;
2914 }
2915 if (Callee->isDeclaration()) {
2916 return !Callee->hasFnAttribute(Attribute::Convergent);
2917 }
2918 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2919 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2920 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2921 };
2922
2923 bool UsedAssumedInformation = false;
2924 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2925 UsedAssumedInformation)) {
2926 return indicatePessimisticFixpoint();
2927 }
2928 return ChangeStatus::UNCHANGED;
2929 }
2930
2931 ChangeStatus manifest(Attributor &A) override {
2932 if (isKnownNotConvergent() &&
2933 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2934 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2935 return ChangeStatus::CHANGED;
2936 }
2937 return ChangeStatus::UNCHANGED;
2938 }
2939
2940 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2941};
2942} // namespace
2943
2944/// -------------------- Undefined-Behavior Attributes ------------------------
2945
2946namespace {
2947struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2948 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2949 : AAUndefinedBehavior(IRP, A) {}
2950
2951 /// See AbstractAttribute::updateImpl(...).
2952 // through a pointer (i.e. also branches etc.)
2953 ChangeStatus updateImpl(Attributor &A) override {
2954 const size_t UBPrevSize = KnownUBInsts.size();
2955 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2956
2957 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2958 // Volatile accesses on null are not necessarily UB.
2959 if (I.isVolatile())
2960 return true;
2961
2962 // Skip instructions that are already saved.
2963 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2964 return true;
2965
2966 // If we reach here, we know we have an instruction
2967 // that accesses memory through a pointer operand,
2968 // for which getPointerOperand() should give it to us.
2969 Value *PtrOp =
2970 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2971 assert(PtrOp &&
2972 "Expected pointer operand of memory accessing instruction");
2973
2974 // Either we stopped and the appropriate action was taken,
2975 // or we got back a simplified value to continue.
2976 std::optional<Value *> SimplifiedPtrOp =
2977 stopOnUndefOrAssumed(A, PtrOp, &I);
2978 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2979 return true;
2980 const Value *PtrOpVal = *SimplifiedPtrOp;
2981
2982 // A memory access through a pointer is considered UB
2983 // only if the pointer has constant null value.
2984 // TODO: Expand it to not only check constant values.
2985 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2986 AssumedNoUBInsts.insert(&I);
2987 return true;
2988 }
2989 const Type *PtrTy = PtrOpVal->getType();
2990
2991 // Because we only consider instructions inside functions,
2992 // assume that a parent function exists.
2993 const Function *F = I.getFunction();
2994
2995 // A memory access using constant null pointer is only considered UB
2996 // if null pointer is _not_ defined for the target platform.
2998 AssumedNoUBInsts.insert(&I);
2999 else
3000 KnownUBInsts.insert(&I);
3001 return true;
3002 };
3003
3004 auto InspectBrInstForUB = [&](Instruction &I) {
3005 // A conditional branch instruction is considered UB if it has `undef`
3006 // condition.
3007
3008 // Skip instructions that are already saved.
3009 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3010 return true;
3011
3012 // We know we have a branch instruction.
3013 auto *BrInst = cast<CondBrInst>(&I);
3014
3015 // Either we stopped and the appropriate action was taken,
3016 // or we got back a simplified value to continue.
3017 std::optional<Value *> SimplifiedCond =
3018 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3019 if (!SimplifiedCond || !*SimplifiedCond)
3020 return true;
3021 AssumedNoUBInsts.insert(&I);
3022 return true;
3023 };
3024
3025 auto InspectCallSiteForUB = [&](Instruction &I) {
3026 // Check whether a callsite always cause UB or not
3027
3028 // Skip instructions that are already saved.
3029 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3030 return true;
3031
3032 // Check nonnull and noundef argument attribute violation for each
3033 // callsite.
3034 CallBase &CB = cast<CallBase>(I);
3036 if (!Callee)
3037 return true;
3038 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3039 // If current argument is known to be simplified to null pointer and the
3040 // corresponding argument position is known to have nonnull attribute,
3041 // the argument is poison. Furthermore, if the argument is poison and
3042 // the position is known to have noundef attriubte, this callsite is
3043 // considered UB.
3044 if (idx >= Callee->arg_size())
3045 break;
3046 Value *ArgVal = CB.getArgOperand(idx);
3047 if (!ArgVal)
3048 continue;
3049 // Here, we handle three cases.
3050 // (1) Not having a value means it is dead. (we can replace the value
3051 // with undef)
3052 // (2) Simplified to undef. The argument violate noundef attriubte.
3053 // (3) Simplified to null pointer where known to be nonnull.
3054 // The argument is a poison value and violate noundef attribute.
3055 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3056 bool IsKnownNoUndef;
3058 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3059 if (!IsKnownNoUndef)
3060 continue;
3061 bool UsedAssumedInformation = false;
3062 std::optional<Value *> SimplifiedVal =
3063 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3064 UsedAssumedInformation, AA::Interprocedural);
3065 if (UsedAssumedInformation)
3066 continue;
3067 if (SimplifiedVal && !*SimplifiedVal)
3068 return true;
3069 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3070 KnownUBInsts.insert(&I);
3071 continue;
3072 }
3073 if (!ArgVal->getType()->isPointerTy() ||
3074 !isa<ConstantPointerNull>(**SimplifiedVal))
3075 continue;
3076 bool IsKnownNonNull;
3078 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3079 if (IsKnownNonNull)
3080 KnownUBInsts.insert(&I);
3081 }
3082 return true;
3083 };
3084
3085 auto InspectReturnInstForUB = [&](Instruction &I) {
3086 auto &RI = cast<ReturnInst>(I);
3087 // Either we stopped and the appropriate action was taken,
3088 // or we got back a simplified return value to continue.
3089 std::optional<Value *> SimplifiedRetValue =
3090 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3091 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3092 return true;
3093
3094 // Check if a return instruction always cause UB or not
3095 // Note: It is guaranteed that the returned position of the anchor
3096 // scope has noundef attribute when this is called.
3097 // We also ensure the return position is not "assumed dead"
3098 // because the returned value was then potentially simplified to
3099 // `undef` in AAReturnedValues without removing the `noundef`
3100 // attribute yet.
3101
3102 // When the returned position has noundef attriubte, UB occurs in the
3103 // following cases.
3104 // (1) Returned value is known to be undef.
3105 // (2) The value is known to be a null pointer and the returned
3106 // position has nonnull attribute (because the returned value is
3107 // poison).
3108 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3109 bool IsKnownNonNull;
3111 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3112 IsKnownNonNull);
3113 if (IsKnownNonNull)
3114 KnownUBInsts.insert(&I);
3115 }
3116
3117 return true;
3118 };
3119
3120 bool UsedAssumedInformation = false;
3121 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3122 {Instruction::Load, Instruction::Store,
3123 Instruction::AtomicCmpXchg,
3124 Instruction::AtomicRMW},
3125 UsedAssumedInformation,
3126 /* CheckBBLivenessOnly */ true);
3127 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::CondBr},
3128 UsedAssumedInformation,
3129 /* CheckBBLivenessOnly */ true);
3130 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3131 UsedAssumedInformation);
3132
3133 // If the returned position of the anchor scope has noundef attriubte, check
3134 // all returned instructions.
3135 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3136 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3137 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3138 bool IsKnownNoUndef;
3140 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3141 if (IsKnownNoUndef)
3142 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3143 {Instruction::Ret}, UsedAssumedInformation,
3144 /* CheckBBLivenessOnly */ true);
3145 }
3146 }
3147
3148 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3149 UBPrevSize != KnownUBInsts.size())
3150 return ChangeStatus::CHANGED;
3151 return ChangeStatus::UNCHANGED;
3152 }
3153
3154 bool isKnownToCauseUB(Instruction *I) const override {
3155 return KnownUBInsts.count(I);
3156 }
3157
3158 bool isAssumedToCauseUB(Instruction *I) const override {
3159 // In simple words, if an instruction is not in the assumed to _not_
3160 // cause UB, then it is assumed UB (that includes those
3161 // in the KnownUBInsts set). The rest is boilerplate
3162 // is to ensure that it is one of the instructions we test
3163 // for UB.
3164
3165 switch (I->getOpcode()) {
3166 case Instruction::Load:
3167 case Instruction::Store:
3168 case Instruction::AtomicCmpXchg:
3169 case Instruction::AtomicRMW:
3170 case Instruction::CondBr:
3171 return !AssumedNoUBInsts.count(I);
3172 default:
3173 return false;
3174 }
3175 return false;
3176 }
3177
3178 ChangeStatus manifest(Attributor &A) override {
3179 if (KnownUBInsts.empty())
3180 return ChangeStatus::UNCHANGED;
3181 for (Instruction *I : KnownUBInsts)
3182 A.changeToUnreachableAfterManifest(I);
3183 return ChangeStatus::CHANGED;
3184 }
3185
3186 /// See AbstractAttribute::getAsStr()
3187 const std::string getAsStr(Attributor *A) const override {
3188 return getAssumed() ? "undefined-behavior" : "no-ub";
3189 }
3190
3191 /// Note: The correctness of this analysis depends on the fact that the
3192 /// following 2 sets will stop changing after some point.
3193 /// "Change" here means that their size changes.
3194 /// The size of each set is monotonically increasing
3195 /// (we only add items to them) and it is upper bounded by the number of
3196 /// instructions in the processed function (we can never save more
3197 /// elements in either set than this number). Hence, at some point,
3198 /// they will stop increasing.
3199 /// Consequently, at some point, both sets will have stopped
3200 /// changing, effectively making the analysis reach a fixpoint.
3201
3202 /// Note: These 2 sets are disjoint and an instruction can be considered
3203 /// one of 3 things:
3204 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3205 /// the KnownUBInsts set.
3206 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3207 /// has a reason to assume it).
3208 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3209 /// could not find a reason to assume or prove that it can cause UB,
3210 /// hence it assumes it doesn't. We have a set for these instructions
3211 /// so that we don't reprocess them in every update.
3212 /// Note however that instructions in this set may cause UB.
3213
3214protected:
3215 /// A set of all live instructions _known_ to cause UB.
3216 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3217
3218private:
3219 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3220 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3221
3222 // Should be called on updates in which if we're processing an instruction
3223 // \p I that depends on a value \p V, one of the following has to happen:
3224 // - If the value is assumed, then stop.
3225 // - If the value is known but undef, then consider it UB.
3226 // - Otherwise, do specific processing with the simplified value.
3227 // We return std::nullopt in the first 2 cases to signify that an appropriate
3228 // action was taken and the caller should stop.
3229 // Otherwise, we return the simplified value that the caller should
3230 // use for specific processing.
3231 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3232 Instruction *I) {
3233 bool UsedAssumedInformation = false;
3234 std::optional<Value *> SimplifiedV =
3235 A.getAssumedSimplified(IRPosition::value(*V), *this,
3236 UsedAssumedInformation, AA::Interprocedural);
3237 if (!UsedAssumedInformation) {
3238 // Don't depend on assumed values.
3239 if (!SimplifiedV) {
3240 // If it is known (which we tested above) but it doesn't have a value,
3241 // then we can assume `undef` and hence the instruction is UB.
3242 KnownUBInsts.insert(I);
3243 return std::nullopt;
3244 }
3245 if (!*SimplifiedV)
3246 return nullptr;
3247 V = *SimplifiedV;
3248 }
3249 if (isa<UndefValue>(V)) {
3250 KnownUBInsts.insert(I);
3251 return std::nullopt;
3252 }
3253 return V;
3254 }
3255};
3256
3257struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3258 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3259 : AAUndefinedBehaviorImpl(IRP, A) {}
3260
3261 /// See AbstractAttribute::trackStatistics()
3262 void trackStatistics() const override {
3263 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3264 "Number of instructions known to have UB");
3265 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3266 KnownUBInsts.size();
3267 }
3268};
3269} // namespace
3270
3271/// ------------------------ Will-Return Attributes ----------------------------
3272
3273namespace {
3274// Helper function that checks whether a function has any cycle which we don't
3275// know if it is bounded or not.
3276// Loops with maximum trip count are considered bounded, any other cycle not.
3277static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3278 ScalarEvolution *SE =
3279 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3280 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3281 // If either SCEV or LoopInfo is not available for the function then we assume
3282 // any cycle to be unbounded cycle.
3283 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3284 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3285 if (!SE || !LI) {
3286 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3287 if (SCCI.hasCycle())
3288 return true;
3289 return false;
3290 }
3291
3292 // If there's irreducible control, the function may contain non-loop cycles.
3294 return true;
3295
3296 // Any loop that does not have a max trip count is considered unbounded cycle.
3297 for (auto *L : LI->getLoopsInPreorder()) {
3298 if (!SE->getSmallConstantMaxTripCount(L))
3299 return true;
3300 }
3301 return false;
3302}
3303
3304struct AAWillReturnImpl : public AAWillReturn {
3305 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3306 : AAWillReturn(IRP, A) {}
3307
3308 /// See AbstractAttribute::initialize(...).
3309 void initialize(Attributor &A) override {
3310 bool IsKnown;
3312 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3313 (void)IsKnown;
3314 }
3315
3316 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3317 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3318 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3319 return false;
3320
3321 bool IsKnown;
3322 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3323 return IsKnown || !KnownOnly;
3324 return false;
3325 }
3326
3327 /// See AbstractAttribute::updateImpl(...).
3328 ChangeStatus updateImpl(Attributor &A) override {
3329 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3330 return ChangeStatus::UNCHANGED;
3331
3332 auto CheckForWillReturn = [&](Instruction &I) {
3334 bool IsKnown;
3336 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3337 if (IsKnown)
3338 return true;
3339 } else {
3340 return false;
3341 }
3342 bool IsKnownNoRecurse;
3344 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3345 };
3346
3347 bool UsedAssumedInformation = false;
3348 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3349 UsedAssumedInformation))
3350 return indicatePessimisticFixpoint();
3351
3352 auto CheckForVolatile = [&](Instruction &I) {
3353 // Volatile operations are not willreturn.
3354 return !I.isVolatile();
3355 };
3356 if (!A.checkForAllInstructions(CheckForVolatile, *this,
3357 {Instruction::Load, Instruction::Store,
3358 Instruction::AtomicCmpXchg,
3359 Instruction::AtomicRMW},
3360 UsedAssumedInformation))
3361 return indicatePessimisticFixpoint();
3362
3363 return ChangeStatus::UNCHANGED;
3364 }
3365
3366 /// See AbstractAttribute::getAsStr()
3367 const std::string getAsStr(Attributor *A) const override {
3368 return getAssumed() ? "willreturn" : "may-noreturn";
3369 }
3370};
3371
3372struct AAWillReturnFunction final : AAWillReturnImpl {
3373 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3374 : AAWillReturnImpl(IRP, A) {}
3375
3376 /// See AbstractAttribute::initialize(...).
3377 void initialize(Attributor &A) override {
3378 AAWillReturnImpl::initialize(A);
3379
3380 Function *F = getAnchorScope();
3381 assert(F && "Did expect an anchor function");
3382 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3383 indicatePessimisticFixpoint();
3384 }
3385
3386 /// See AbstractAttribute::trackStatistics()
3387 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3388};
3389
3390/// WillReturn attribute deduction for a call sites.
3391struct AAWillReturnCallSite final
3392 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3393 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3394 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3395
3396 /// See AbstractAttribute::updateImpl(...).
3397 ChangeStatus updateImpl(Attributor &A) override {
3398 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3399 return ChangeStatus::UNCHANGED;
3400
3401 return AACalleeToCallSite::updateImpl(A);
3402 }
3403
3404 /// See AbstractAttribute::trackStatistics()
3405 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3406};
3407} // namespace
3408
3409/// -------------------AAIntraFnReachability Attribute--------------------------
3410
3411/// All information associated with a reachability query. This boilerplate code
3412/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3413/// different \p ToTy values.
3414template <typename ToTy> struct ReachabilityQueryInfo {
3415 enum class Reachable {
3418 };
3419
3420 /// Start here,
3421 const Instruction *From = nullptr;
3422 /// reach this place,
3423 const ToTy *To = nullptr;
3424 /// without going through any of these instructions,
3426 /// and remember if it worked:
3428
3429 /// Precomputed hash for this RQI.
3430 unsigned Hash = 0;
3431
3432 unsigned computeHashValue() const {
3433 assert(Hash == 0 && "Computed hash twice!");
3436 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3437 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3438 InstSetDMI::getHashValue(ExclusionSet));
3439 }
3440
3442 : From(From), To(To) {}
3443
3444 /// Constructor replacement to ensure unique and stable sets are used for the
3445 /// cache.
3447 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3448 : From(&From), To(&To), ExclusionSet(ES) {
3449
3450 if (!ES || ES->empty()) {
3451 ExclusionSet = nullptr;
3452 } else if (MakeUnique) {
3453 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3454 }
3455 }
3456
3459};
3460
3461namespace llvm {
3462template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3465
3468
3471 return &TombstoneKey;
3472 }
3473 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3474 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3475 }
3476 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS,
3477 const ReachabilityQueryInfo<ToTy> *RHS) {
3478 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3479 return false;
3480 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3481 }
3482};
3483
3484#define DefineKeys(ToTy) \
3485 template <> \
3486 ReachabilityQueryInfo<ToTy> \
3487 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3488 ReachabilityQueryInfo<ToTy>( \
3489 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3490 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3491 template <> \
3492 ReachabilityQueryInfo<ToTy> \
3493 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3494 ReachabilityQueryInfo<ToTy>( \
3495 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3496 DenseMapInfo<const ToTy *>::getTombstoneKey());
3497
3499#undef DefineKeys
3500
3501} // namespace llvm
3502
3503namespace {
3504
3505template <typename BaseTy, typename ToTy>
3506struct CachedReachabilityAA : public BaseTy {
3507 using RQITy = ReachabilityQueryInfo<ToTy>;
3508
3509 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3510
3511 /// See AbstractAttribute::isQueryAA.
3512 bool isQueryAA() const override { return true; }
3513
3514 /// See AbstractAttribute::updateImpl(...).
3515 ChangeStatus updateImpl(Attributor &A) override {
3516 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3517 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3518 RQITy *RQI = QueryVector[u];
3519 if (RQI->Result == RQITy::Reachable::No &&
3520 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3521 Changed = ChangeStatus::CHANGED;
3522 }
3523 return Changed;
3524 }
3525
3526 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3527 bool IsTemporaryRQI) = 0;
3528
3529 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3530 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3531 RQI.Result = Result;
3532
3533 // Remove the temporary RQI from the cache.
3534 if (IsTemporaryRQI)
3535 QueryCache.erase(&RQI);
3536
3537 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3538 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3539 // this query. 2) We did not use the exclusion set, potentially because
3540 // there is none.
3541 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3542 RQITy PlainRQI(RQI.From, RQI.To);
3543 if (!QueryCache.count(&PlainRQI)) {
3544 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3545 RQIPtr->Result = Result;
3546 QueryVector.push_back(RQIPtr);
3547 QueryCache.insert(RQIPtr);
3548 }
3549 }
3550
3551 // Check if we need to insert a new permanent RQI with the exclusion set.
3552 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3553 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3554 "Did not expect empty set!");
3555 RQITy *RQIPtr = new (A.Allocator)
3556 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3557 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3558 RQIPtr->Result = Result;
3559 assert(!QueryCache.count(RQIPtr));
3560 QueryVector.push_back(RQIPtr);
3561 QueryCache.insert(RQIPtr);
3562 }
3563
3564 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3565 A.registerForUpdate(*this);
3566 return Result == RQITy::Reachable::Yes;
3567 }
3568
3569 const std::string getAsStr(Attributor *A) const override {
3570 // TODO: Return the number of reachable queries.
3571 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3572 }
3573
3574 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3575 typename RQITy::Reachable &Result) {
3576 if (!this->getState().isValidState()) {
3577 Result = RQITy::Reachable::Yes;
3578 return true;
3579 }
3580
3581 // If we have an exclusion set we might be able to find our answer by
3582 // ignoring it first.
3583 if (StackRQI.ExclusionSet) {
3584 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3585 auto It = QueryCache.find(&PlainRQI);
3586 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3587 Result = RQITy::Reachable::No;
3588 return true;
3589 }
3590 }
3591
3592 auto It = QueryCache.find(&StackRQI);
3593 if (It != QueryCache.end()) {
3594 Result = (*It)->Result;
3595 return true;
3596 }
3597
3598 // Insert a temporary for recursive queries. We will replace it with a
3599 // permanent entry later.
3600 QueryCache.insert(&StackRQI);
3601 return false;
3602 }
3603
3604private:
3605 SmallVector<RQITy *> QueryVector;
3606 DenseSet<RQITy *> QueryCache;
3607};
3608
3609struct AAIntraFnReachabilityFunction final
3610 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3611 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3612 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3613 : Base(IRP, A) {
3614 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3615 *IRP.getAssociatedFunction());
3616 }
3617
3618 bool isAssumedReachable(
3619 Attributor &A, const Instruction &From, const Instruction &To,
3620 const AA::InstExclusionSetTy *ExclusionSet) const override {
3621 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3622 if (&From == &To)
3623 return true;
3624
3625 RQITy StackRQI(A, From, To, ExclusionSet, false);
3626 RQITy::Reachable Result;
3627 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3628 return NonConstThis->isReachableImpl(A, StackRQI,
3629 /*IsTemporaryRQI=*/true);
3630 return Result == RQITy::Reachable::Yes;
3631 }
3632
3633 ChangeStatus updateImpl(Attributor &A) override {
3634 // We only depend on liveness. DeadEdges is all we care about, check if any
3635 // of them changed.
3636 auto *LivenessAA =
3637 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3638 if (LivenessAA &&
3639 llvm::all_of(DeadEdges,
3640 [&](const auto &DeadEdge) {
3641 return LivenessAA->isEdgeDead(DeadEdge.first,
3642 DeadEdge.second);
3643 }) &&
3644 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3645 return LivenessAA->isAssumedDead(BB);
3646 })) {
3647 return ChangeStatus::UNCHANGED;
3648 }
3649 DeadEdges.clear();
3650 DeadBlocks.clear();
3651 return Base::updateImpl(A);
3652 }
3653
3654 bool isReachableImpl(Attributor &A, RQITy &RQI,
3655 bool IsTemporaryRQI) override {
3656 const Instruction *Origin = RQI.From;
3657 bool UsedExclusionSet = false;
3658
3659 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3660 const AA::InstExclusionSetTy *ExclusionSet) {
3661 const Instruction *IP = &From;
3662 while (IP && IP != &To) {
3663 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3664 UsedExclusionSet = true;
3665 break;
3666 }
3667 IP = IP->getNextNode();
3668 }
3669 return IP == &To;
3670 };
3671
3672 const BasicBlock *FromBB = RQI.From->getParent();
3673 const BasicBlock *ToBB = RQI.To->getParent();
3674 assert(FromBB->getParent() == ToBB->getParent() &&
3675 "Not an intra-procedural query!");
3676
3677 // Check intra-block reachability, however, other reaching paths are still
3678 // possible.
3679 if (FromBB == ToBB &&
3680 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3681 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3682 IsTemporaryRQI);
3683
3684 // Check if reaching the ToBB block is sufficient or if even that would not
3685 // ensure reaching the target. In the latter case we are done.
3686 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3687 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3688 IsTemporaryRQI);
3689
3690 const Function *Fn = FromBB->getParent();
3691 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks;
3692 if (RQI.ExclusionSet)
3693 for (auto *I : *RQI.ExclusionSet)
3694 if (I->getFunction() == Fn)
3695 ExclusionBlocks.insert(I->getParent());
3696
3697 // Check if we make it out of the FromBB block at all.
3698 if (ExclusionBlocks.count(FromBB) &&
3699 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3700 RQI.ExclusionSet))
3701 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3702
3703 auto *LivenessAA =
3704 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3705 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3706 DeadBlocks.insert(ToBB);
3707 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3708 IsTemporaryRQI);
3709 }
3710
3711 SmallPtrSet<const BasicBlock *, 16> Visited;
3713 Worklist.push_back(FromBB);
3714
3715 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges;
3716 while (!Worklist.empty()) {
3717 const BasicBlock *BB = Worklist.pop_back_val();
3718 if (!Visited.insert(BB).second)
3719 continue;
3720 for (const BasicBlock *SuccBB : successors(BB)) {
3721 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3722 LocalDeadEdges.insert({BB, SuccBB});
3723 continue;
3724 }
3725 // We checked before if we just need to reach the ToBB block.
3726 if (SuccBB == ToBB)
3727 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3728 IsTemporaryRQI);
3729 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3730 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3731 IsTemporaryRQI);
3732
3733 if (ExclusionBlocks.count(SuccBB)) {
3734 UsedExclusionSet = true;
3735 continue;
3736 }
3737 Worklist.push_back(SuccBB);
3738 }
3739 }
3740
3741 DeadEdges.insert_range(LocalDeadEdges);
3742 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3743 IsTemporaryRQI);
3744 }
3745
3746 /// See AbstractAttribute::trackStatistics()
3747 void trackStatistics() const override {}
3748
3749private:
3750 // Set of assumed dead blocks we used in the last query. If any changes we
3751 // update the state.
3752 DenseSet<const BasicBlock *> DeadBlocks;
3753
3754 // Set of assumed dead edges we used in the last query. If any changes we
3755 // update the state.
3756 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges;
3757
3758 /// The dominator tree of the function to short-circuit reasoning.
3759 const DominatorTree *DT = nullptr;
3760};
3761} // namespace
3762
3763/// ------------------------ NoAlias Argument Attribute ------------------------
3764
3766 Attribute::AttrKind ImpliedAttributeKind,
3767 bool IgnoreSubsumingPositions) {
3768 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3769 "Unexpected attribute kind");
3770 Value *Val = &IRP.getAssociatedValue();
3772 if (isa<AllocaInst>(Val))
3773 return true;
3774 } else {
3775 IgnoreSubsumingPositions = true;
3776 }
3777
3778 if (isa<UndefValue>(Val))
3779 return true;
3780
3781 if (isa<ConstantPointerNull>(Val) &&
3784 return true;
3785
3786 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3787 IgnoreSubsumingPositions, Attribute::NoAlias))
3788 return true;
3789
3790 return false;
3791}
3792
3793namespace {
3794struct AANoAliasImpl : AANoAlias {
3795 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3796 assert(getAssociatedType()->isPointerTy() &&
3797 "Noalias is a pointer attribute");
3798 }
3799
3800 const std::string getAsStr(Attributor *A) const override {
3801 return getAssumed() ? "noalias" : "may-alias";
3802 }
3803};
3804
3805/// NoAlias attribute for a floating value.
3806struct AANoAliasFloating final : AANoAliasImpl {
3807 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3808 : AANoAliasImpl(IRP, A) {}
3809
3810 /// See AbstractAttribute::updateImpl(...).
3811 ChangeStatus updateImpl(Attributor &A) override {
3812 // TODO: Implement this.
3813 return indicatePessimisticFixpoint();
3814 }
3815
3816 /// See AbstractAttribute::trackStatistics()
3817 void trackStatistics() const override {
3819 }
3820};
3821
3822/// NoAlias attribute for an argument.
3823struct AANoAliasArgument final
3824 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3825 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3826 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3827
3828 /// See AbstractAttribute::update(...).
3829 ChangeStatus updateImpl(Attributor &A) override {
3830 // We have to make sure no-alias on the argument does not break
3831 // synchronization when this is a callback argument, see also [1] below.
3832 // If synchronization cannot be affected, we delegate to the base updateImpl
3833 // function, otherwise we give up for now.
3834
3835 // If the function is no-sync, no-alias cannot break synchronization.
3836 bool IsKnownNoSycn;
3838 A, this, IRPosition::function_scope(getIRPosition()),
3839 DepClassTy::OPTIONAL, IsKnownNoSycn))
3840 return Base::updateImpl(A);
3841
3842 // If the argument is read-only, no-alias cannot break synchronization.
3843 bool IsKnown;
3844 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3845 return Base::updateImpl(A);
3846
3847 // If the argument is never passed through callbacks, no-alias cannot break
3848 // synchronization.
3849 bool UsedAssumedInformation = false;
3850 if (A.checkForAllCallSites(
3851 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3852 true, UsedAssumedInformation))
3853 return Base::updateImpl(A);
3854
3855 // TODO: add no-alias but make sure it doesn't break synchronization by
3856 // introducing fake uses. See:
3857 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3858 // International Workshop on OpenMP 2018,
3859 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3860
3861 return indicatePessimisticFixpoint();
3862 }
3863
3864 /// See AbstractAttribute::trackStatistics()
3865 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3866};
3867
3868struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3869 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3870 : AANoAliasImpl(IRP, A) {}
3871
3872 /// Determine if the underlying value may alias with the call site argument
3873 /// \p OtherArgNo of \p ICS (= the underlying call site).
3874 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3875 const AAMemoryBehavior &MemBehaviorAA,
3876 const CallBase &CB, unsigned OtherArgNo) {
3877 // We do not need to worry about aliasing with the underlying IRP.
3878 if (this->getCalleeArgNo() == (int)OtherArgNo)
3879 return false;
3880
3881 // If it is not a pointer or pointer vector we do not alias.
3882 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3883 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3884 return false;
3885
3886 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3887 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3888
3889 // If the argument is readnone, there is no read-write aliasing.
3890 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3891 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3892 return false;
3893 }
3894
3895 // If the argument is readonly and the underlying value is readonly, there
3896 // is no read-write aliasing.
3897 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3898 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3899 IsReadOnly) {
3900 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3901 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3902 return false;
3903 }
3904
3905 // We have to utilize actual alias analysis queries so we need the object.
3906 if (!AAR)
3907 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3908 *getAnchorScope());
3909
3910 // Try to rule it out at the call site.
3911 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3912 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3913 "callsite arguments: "
3914 << getAssociatedValue() << " " << *ArgOp << " => "
3915 << (IsAliasing ? "" : "no-") << "alias \n");
3916
3917 return IsAliasing;
3918 }
3919
3920 bool isKnownNoAliasDueToNoAliasPreservation(
3921 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3922 // We can deduce "noalias" if the following conditions hold.
3923 // (i) Associated value is assumed to be noalias in the definition.
3924 // (ii) Associated value is assumed to be no-capture in all the uses
3925 // possibly executed before this callsite.
3926 // (iii) There is no other pointer argument which could alias with the
3927 // value.
3928
3929 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3930 const Function *ScopeFn = VIRP.getAnchorScope();
3931 // Check whether the value is captured in the scope using AANoCapture.
3932 // Look at CFG and check only uses possibly executed before this
3933 // callsite.
3934 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3935 Instruction *UserI = cast<Instruction>(U.getUser());
3936
3937 // If UserI is the curr instruction and there is a single potential use of
3938 // the value in UserI we allow the use.
3939 // TODO: We should inspect the operands and allow those that cannot alias
3940 // with the value.
3941 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3942 return true;
3943
3944 if (ScopeFn) {
3945 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3946 if (CB->isArgOperand(&U)) {
3947
3948 unsigned ArgNo = CB->getArgOperandNo(&U);
3949
3950 bool IsKnownNoCapture;
3952 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3953 DepClassTy::OPTIONAL, IsKnownNoCapture))
3954 return true;
3955 }
3956 }
3957
3959 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3960 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3961 return true;
3962 }
3963
3964 // TODO: We should track the capturing uses in AANoCapture but the problem
3965 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3966 // a value in the module slice.
3967 // TODO(captures): Make this more precise.
3968 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3969 if (capturesNothing(CI))
3970 return true;
3971 if (CI.isPassthrough()) {
3972 Follow = true;
3973 return true;
3974 }
3975 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3976 return false;
3977 };
3978
3979 bool IsKnownNoCapture;
3980 const AANoCapture *NoCaptureAA = nullptr;
3981 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3982 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3983 if (!IsAssumedNoCapture &&
3984 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3985 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3986 LLVM_DEBUG(
3987 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3988 << " cannot be noalias as it is potentially captured\n");
3989 return false;
3990 }
3991 }
3992 if (NoCaptureAA)
3993 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3994
3995 // Check there is no other pointer argument which could alias with the
3996 // value passed at this call site.
3997 // TODO: AbstractCallSite
3998 const auto &CB = cast<CallBase>(getAnchorValue());
3999 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
4000 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
4001 return false;
4002
4003 return true;
4004 }
4005
4006 /// See AbstractAttribute::updateImpl(...).
4007 ChangeStatus updateImpl(Attributor &A) override {
4008 // If the argument is readnone we are done as there are no accesses via the
4009 // argument.
4010 auto *MemBehaviorAA =
4011 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4012 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4013 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4014 return ChangeStatus::UNCHANGED;
4015 }
4016
4017 bool IsKnownNoAlias;
4018 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4020 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4021 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4022 << " is not no-alias at the definition\n");
4023 return indicatePessimisticFixpoint();
4024 }
4025
4026 AAResults *AAR = nullptr;
4027 if (MemBehaviorAA &&
4028 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4029 LLVM_DEBUG(
4030 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4031 return ChangeStatus::UNCHANGED;
4032 }
4033
4034 return indicatePessimisticFixpoint();
4035 }
4036
4037 /// See AbstractAttribute::trackStatistics()
4038 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4039};
4040
4041/// NoAlias attribute for function return value.
4042struct AANoAliasReturned final : AANoAliasImpl {
4043 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4044 : AANoAliasImpl(IRP, A) {}
4045
4046 /// See AbstractAttribute::updateImpl(...).
4047 ChangeStatus updateImpl(Attributor &A) override {
4048
4049 auto CheckReturnValue = [&](Value &RV) -> bool {
4050 if (Constant *C = dyn_cast<Constant>(&RV))
4051 if (C->isNullValue() || isa<UndefValue>(C))
4052 return true;
4053
4054 /// For now, we can only deduce noalias if we have call sites.
4055 /// FIXME: add more support.
4056 if (!isa<CallBase>(&RV))
4057 return false;
4058
4059 const IRPosition &RVPos = IRPosition::value(RV);
4060 bool IsKnownNoAlias;
4062 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4063 return false;
4064
4065 bool IsKnownNoCapture;
4066 const AANoCapture *NoCaptureAA = nullptr;
4067 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4068 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4069 &NoCaptureAA);
4070 return IsAssumedNoCapture ||
4071 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4072 };
4073
4074 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4075 return indicatePessimisticFixpoint();
4076
4077 return ChangeStatus::UNCHANGED;
4078 }
4079
4080 /// See AbstractAttribute::trackStatistics()
4081 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4082};
4083
4084/// NoAlias attribute deduction for a call site return value.
4085struct AANoAliasCallSiteReturned final
4086 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4087 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4088 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4089
4090 /// See AbstractAttribute::trackStatistics()
4091 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4092};
4093} // namespace
4094
4095/// -------------------AAIsDead Function Attribute-----------------------
4096
4097namespace {
4098struct AAIsDeadValueImpl : public AAIsDead {
4099 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4100
4101 /// See AAIsDead::isAssumedDead().
4102 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4103
4104 /// See AAIsDead::isKnownDead().
4105 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4106
4107 /// See AAIsDead::isAssumedDead(BasicBlock *).
4108 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4109
4110 /// See AAIsDead::isKnownDead(BasicBlock *).
4111 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4112
4113 /// See AAIsDead::isAssumedDead(Instruction *I).
4114 bool isAssumedDead(const Instruction *I) const override {
4115 return I == getCtxI() && isAssumedDead();
4116 }
4117
4118 /// See AAIsDead::isKnownDead(Instruction *I).
4119 bool isKnownDead(const Instruction *I) const override {
4120 return isAssumedDead(I) && isKnownDead();
4121 }
4122
4123 /// See AbstractAttribute::getAsStr().
4124 const std::string getAsStr(Attributor *A) const override {
4125 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4126 }
4127
4128 /// Check if all uses are assumed dead.
4129 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4130 // Callers might not check the type, void has no uses.
4131 if (V.getType()->isVoidTy() || V.use_empty())
4132 return true;
4133
4134 // If we replace a value with a constant there are no uses left afterwards.
4135 if (!isa<Constant>(V)) {
4136 if (auto *I = dyn_cast<Instruction>(&V))
4137 if (!A.isRunOn(*I->getFunction()))
4138 return false;
4139 bool UsedAssumedInformation = false;
4140 std::optional<Constant *> C =
4141 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4142 if (!C || *C)
4143 return true;
4144 }
4145
4146 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4147 // Explicitly set the dependence class to required because we want a long
4148 // chain of N dependent instructions to be considered live as soon as one is
4149 // without going through N update cycles. This is not required for
4150 // correctness.
4151 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4152 DepClassTy::REQUIRED,
4153 /* IgnoreDroppableUses */ false);
4154 }
4155
4156 /// Determine if \p I is assumed to be side-effect free.
4157 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4159 return true;
4160
4161 if (!I->isTerminator() && !I->mayHaveSideEffects())
4162 return true;
4163
4164 auto *CB = dyn_cast<CallBase>(I);
4165 if (!CB || isa<IntrinsicInst>(CB))
4166 return false;
4167
4168 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4169
4170 bool IsKnownNoUnwind;
4172 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4173 return false;
4174
4175 bool IsKnown;
4176 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4177 }
4178};
4179
4180struct AAIsDeadFloating : public AAIsDeadValueImpl {
4181 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4182 : AAIsDeadValueImpl(IRP, A) {}
4183
4184 /// See AbstractAttribute::initialize(...).
4185 void initialize(Attributor &A) override {
4186 AAIsDeadValueImpl::initialize(A);
4187
4188 if (isa<UndefValue>(getAssociatedValue())) {
4189 indicatePessimisticFixpoint();
4190 return;
4191 }
4192
4193 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4194 if (!isAssumedSideEffectFree(A, I)) {
4196 indicatePessimisticFixpoint();
4197 else
4198 removeAssumedBits(HAS_NO_EFFECT);
4199 }
4200 }
4201
4202 bool isDeadFence(Attributor &A, FenceInst &FI) {
4203 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4204 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4205 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4206 return false;
4207 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4208 return true;
4209 }
4210
4211 bool isDeadStore(Attributor &A, StoreInst &SI,
4212 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4213 // Lang ref now states volatile store is not UB/dead, let's skip them.
4214 if (SI.isVolatile())
4215 return false;
4216
4217 // If we are collecting assumes to be deleted we are in the manifest stage.
4218 // It's problematic to collect the potential copies again now so we use the
4219 // cached ones.
4220 bool UsedAssumedInformation = false;
4221 if (!AssumeOnlyInst) {
4222 PotentialCopies.clear();
4223 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4224 UsedAssumedInformation)) {
4225 LLVM_DEBUG(
4226 dbgs()
4227 << "[AAIsDead] Could not determine potential copies of store!\n");
4228 return false;
4229 }
4230 }
4231 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4232 << " potential copies.\n");
4233
4234 InformationCache &InfoCache = A.getInfoCache();
4235 return llvm::all_of(PotentialCopies, [&](Value *V) {
4236 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4237 UsedAssumedInformation))
4238 return true;
4239 if (auto *LI = dyn_cast<LoadInst>(V)) {
4240 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4241 auto &UserI = cast<Instruction>(*U.getUser());
4242 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4243 if (AssumeOnlyInst)
4244 AssumeOnlyInst->insert(&UserI);
4245 return true;
4246 }
4247 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4248 })) {
4249 return true;
4250 }
4251 }
4252 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4253 << " is assumed live!\n");
4254 return false;
4255 });
4256 }
4257
4258 /// See AbstractAttribute::getAsStr().
4259 const std::string getAsStr(Attributor *A) const override {
4260 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4262 if (isValidState())
4263 return "assumed-dead-store";
4265 if (isValidState())
4266 return "assumed-dead-fence";
4267 return AAIsDeadValueImpl::getAsStr(A);
4268 }
4269
4270 /// See AbstractAttribute::updateImpl(...).
4271 ChangeStatus updateImpl(Attributor &A) override {
4272 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4273 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4274 if (!isDeadStore(A, *SI))
4275 return indicatePessimisticFixpoint();
4276 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4277 if (!isDeadFence(A, *FI))
4278 return indicatePessimisticFixpoint();
4279 } else {
4280 if (!isAssumedSideEffectFree(A, I))
4281 return indicatePessimisticFixpoint();
4282 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4283 return indicatePessimisticFixpoint();
4284 }
4286 }
4287
4288 bool isRemovableStore() const override {
4289 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4290 }
4291
4292 /// See AbstractAttribute::manifest(...).
4293 ChangeStatus manifest(Attributor &A) override {
4294 Value &V = getAssociatedValue();
4295 if (auto *I = dyn_cast<Instruction>(&V)) {
4296 // If we get here we basically know the users are all dead. We check if
4297 // isAssumedSideEffectFree returns true here again because it might not be
4298 // the case and only the users are dead but the instruction (=call) is
4299 // still needed.
4300 if (auto *SI = dyn_cast<StoreInst>(I)) {
4301 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4302 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4303 (void)IsDead;
4304 assert(IsDead && "Store was assumed to be dead!");
4305 A.deleteAfterManifest(*I);
4306 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4307 Instruction *AOI = AssumeOnlyInst[i];
4308 for (auto *Usr : AOI->users())
4309 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4310 A.deleteAfterManifest(*AOI);
4311 }
4312 return ChangeStatus::CHANGED;
4313 }
4314 if (auto *FI = dyn_cast<FenceInst>(I)) {
4315 assert(isDeadFence(A, *FI));
4316 A.deleteAfterManifest(*FI);
4317 return ChangeStatus::CHANGED;
4318 }
4319 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4320 A.deleteAfterManifest(*I);
4321 return ChangeStatus::CHANGED;
4322 }
4323 }
4325 }
4326
4327 /// See AbstractAttribute::trackStatistics()
4328 void trackStatistics() const override {
4330 }
4331
4332private:
4333 // The potential copies of a dead store, used for deletion during manifest.
4334 SmallSetVector<Value *, 4> PotentialCopies;
4335};
4336
4337struct AAIsDeadArgument : public AAIsDeadFloating {
4338 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4339 : AAIsDeadFloating(IRP, A) {}
4340
4341 /// See AbstractAttribute::manifest(...).
4342 ChangeStatus manifest(Attributor &A) override {
4343 Argument &Arg = *getAssociatedArgument();
4344 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4345 if (A.registerFunctionSignatureRewrite(
4346 Arg, /* ReplacementTypes */ {},
4349 return ChangeStatus::CHANGED;
4350 }
4351 return ChangeStatus::UNCHANGED;
4352 }
4353
4354 /// See AbstractAttribute::trackStatistics()
4355 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4356};
4357
4358struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4359 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4360 : AAIsDeadValueImpl(IRP, A) {}
4361
4362 /// See AbstractAttribute::initialize(...).
4363 void initialize(Attributor &A) override {
4364 AAIsDeadValueImpl::initialize(A);
4365 if (isa<UndefValue>(getAssociatedValue()))
4366 indicatePessimisticFixpoint();
4367 }
4368
4369 /// See AbstractAttribute::updateImpl(...).
4370 ChangeStatus updateImpl(Attributor &A) override {
4371 // TODO: Once we have call site specific value information we can provide
4372 // call site specific liveness information and then it makes
4373 // sense to specialize attributes for call sites arguments instead of
4374 // redirecting requests to the callee argument.
4375 Argument *Arg = getAssociatedArgument();
4376 if (!Arg)
4377 return indicatePessimisticFixpoint();
4378 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4379 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4380 if (!ArgAA)
4381 return indicatePessimisticFixpoint();
4382 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4383 }
4384
4385 /// See AbstractAttribute::manifest(...).
4386 ChangeStatus manifest(Attributor &A) override {
4387 CallBase &CB = cast<CallBase>(getAnchorValue());
4388 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4389 assert(!isa<UndefValue>(U.get()) &&
4390 "Expected undef values to be filtered out!");
4391 UndefValue &UV = *UndefValue::get(U->getType());
4392 if (A.changeUseAfterManifest(U, UV))
4393 return ChangeStatus::CHANGED;
4394 return ChangeStatus::UNCHANGED;
4395 }
4396
4397 /// See AbstractAttribute::trackStatistics()
4398 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4399};
4400
4401struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4402 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4403 : AAIsDeadFloating(IRP, A) {}
4404
4405 /// See AAIsDead::isAssumedDead().
4406 bool isAssumedDead() const override {
4407 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4408 }
4409
4410 /// See AbstractAttribute::initialize(...).
4411 void initialize(Attributor &A) override {
4412 AAIsDeadFloating::initialize(A);
4413 if (isa<UndefValue>(getAssociatedValue())) {
4414 indicatePessimisticFixpoint();
4415 return;
4416 }
4417
4418 // We track this separately as a secondary state.
4419 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4420 }
4421
4422 /// See AbstractAttribute::updateImpl(...).
4423 ChangeStatus updateImpl(Attributor &A) override {
4424 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4425 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4426 IsAssumedSideEffectFree = false;
4427 Changed = ChangeStatus::CHANGED;
4428 }
4429 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4430 return indicatePessimisticFixpoint();
4431 return Changed;
4432 }
4433
4434 /// See AbstractAttribute::trackStatistics()
4435 void trackStatistics() const override {
4436 if (IsAssumedSideEffectFree)
4438 else
4439 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4440 }
4441
4442 /// See AbstractAttribute::getAsStr().
4443 const std::string getAsStr(Attributor *A) const override {
4444 return isAssumedDead()
4445 ? "assumed-dead"
4446 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4447 }
4448
4449private:
4450 bool IsAssumedSideEffectFree = true;
4451};
4452
4453struct AAIsDeadReturned : public AAIsDeadValueImpl {
4454 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4455 : AAIsDeadValueImpl(IRP, A) {}
4456
4457 /// See AbstractAttribute::updateImpl(...).
4458 ChangeStatus updateImpl(Attributor &A) override {
4459
4460 bool UsedAssumedInformation = false;
4461 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4462 {Instruction::Ret}, UsedAssumedInformation);
4463
4464 auto PredForCallSite = [&](AbstractCallSite ACS) {
4465 if (ACS.isCallbackCall() || !ACS.getInstruction())
4466 return false;
4467 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4468 };
4469
4470 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4471 UsedAssumedInformation))
4472 return indicatePessimisticFixpoint();
4473
4474 return ChangeStatus::UNCHANGED;
4475 }
4476
4477 /// See AbstractAttribute::manifest(...).
4478 ChangeStatus manifest(Attributor &A) override {
4479 // TODO: Rewrite the signature to return void?
4480 bool AnyChange = false;
4481 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4482 auto RetInstPred = [&](Instruction &I) {
4483 ReturnInst &RI = cast<ReturnInst>(I);
4485 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4486 return true;
4487 };
4488 bool UsedAssumedInformation = false;
4489 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4490 UsedAssumedInformation);
4491 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4492 }
4493
4494 /// See AbstractAttribute::trackStatistics()
4495 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4496};
4497
4498struct AAIsDeadFunction : public AAIsDead {
4499 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4500
4501 /// See AbstractAttribute::initialize(...).
4502 void initialize(Attributor &A) override {
4503 Function *F = getAnchorScope();
4504 assert(F && "Did expect an anchor function");
4505 if (!isAssumedDeadInternalFunction(A)) {
4506 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4507 assumeLive(A, F->getEntryBlock());
4508 }
4509 }
4510
4511 bool isAssumedDeadInternalFunction(Attributor &A) {
4512 if (!getAnchorScope()->hasLocalLinkage())
4513 return false;
4514 bool UsedAssumedInformation = false;
4515 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4516 true, UsedAssumedInformation);
4517 }
4518
4519 /// See AbstractAttribute::getAsStr().
4520 const std::string getAsStr(Attributor *A) const override {
4521 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4522 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4523 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4524 std::to_string(KnownDeadEnds.size()) + "]";
4525 }
4526
4527 /// See AbstractAttribute::manifest(...).
4528 ChangeStatus manifest(Attributor &A) override {
4529 assert(getState().isValidState() &&
4530 "Attempted to manifest an invalid state!");
4531
4532 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4533 Function &F = *getAnchorScope();
4534
4535 if (AssumedLiveBlocks.empty()) {
4536 A.deleteAfterManifest(F);
4537 return ChangeStatus::CHANGED;
4538 }
4539
4540 // Flag to determine if we can change an invoke to a call assuming the
4541 // callee is nounwind. This is not possible if the personality of the
4542 // function allows to catch asynchronous exceptions.
4543 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4544
4545 KnownDeadEnds.set_union(ToBeExploredFrom);
4546 for (const Instruction *DeadEndI : KnownDeadEnds) {
4547 auto *CB = dyn_cast<CallBase>(DeadEndI);
4548 if (!CB)
4549 continue;
4550 bool IsKnownNoReturn;
4552 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4553 IsKnownNoReturn);
4554 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4555 continue;
4556
4557 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4558 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4559 else
4560 A.changeToUnreachableAfterManifest(
4561 const_cast<Instruction *>(DeadEndI->getNextNode()));
4562 HasChanged = ChangeStatus::CHANGED;
4563 }
4564
4565 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4566 for (BasicBlock &BB : F)
4567 if (!AssumedLiveBlocks.count(&BB)) {
4568 A.deleteAfterManifest(BB);
4569 ++BUILD_STAT_NAME(AAIsDead, BasicBlock);
4570 HasChanged = ChangeStatus::CHANGED;
4571 }
4572
4573 return HasChanged;
4574 }
4575
4576 /// See AbstractAttribute::updateImpl(...).
4577 ChangeStatus updateImpl(Attributor &A) override;
4578
4579 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4580 assert(From->getParent() == getAnchorScope() &&
4581 To->getParent() == getAnchorScope() &&
4582 "Used AAIsDead of the wrong function");
4583 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4584 }
4585
4586 /// See AbstractAttribute::trackStatistics()
4587 void trackStatistics() const override {}
4588
4589 /// Returns true if the function is assumed dead.
4590 bool isAssumedDead() const override { return false; }
4591
4592 /// See AAIsDead::isKnownDead().
4593 bool isKnownDead() const override { return false; }
4594
4595 /// See AAIsDead::isAssumedDead(BasicBlock *).
4596 bool isAssumedDead(const BasicBlock *BB) const override {
4597 assert(BB->getParent() == getAnchorScope() &&
4598 "BB must be in the same anchor scope function.");
4599
4600 if (!getAssumed())
4601 return false;
4602 return !AssumedLiveBlocks.count(BB);
4603 }
4604
4605 /// See AAIsDead::isKnownDead(BasicBlock *).
4606 bool isKnownDead(const BasicBlock *BB) const override {
4607 return getKnown() && isAssumedDead(BB);
4608 }
4609
4610 /// See AAIsDead::isAssumed(Instruction *I).
4611 bool isAssumedDead(const Instruction *I) const override {
4612 assert(I->getParent()->getParent() == getAnchorScope() &&
4613 "Instruction must be in the same anchor scope function.");
4614
4615 if (!getAssumed())
4616 return false;
4617
4618 // If it is not in AssumedLiveBlocks then it for sure dead.
4619 // Otherwise, it can still be after noreturn call in a live block.
4620 if (!AssumedLiveBlocks.count(I->getParent()))
4621 return true;
4622
4623 // If it is not after a liveness barrier it is live.
4624 const Instruction *PrevI = I->getPrevNode();
4625 while (PrevI) {
4626 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4627 return true;
4628 PrevI = PrevI->getPrevNode();
4629 }
4630 return false;
4631 }
4632
4633 /// See AAIsDead::isKnownDead(Instruction *I).
4634 bool isKnownDead(const Instruction *I) const override {
4635 return getKnown() && isAssumedDead(I);
4636 }
4637
4638 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4639 /// that internal function called from \p BB should now be looked at.
4640 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4641 if (!AssumedLiveBlocks.insert(&BB).second)
4642 return false;
4643
4644 // We assume that all of BB is (probably) live now and if there are calls to
4645 // internal functions we will assume that those are now live as well. This
4646 // is a performance optimization for blocks with calls to a lot of internal
4647 // functions. It can however cause dead functions to be treated as live.
4648 for (const Instruction &I : BB)
4649 if (const auto *CB = dyn_cast<CallBase>(&I))
4651 if (F->hasLocalLinkage())
4652 A.markLiveInternalFunction(*F);
4653 return true;
4654 }
4655
4656 /// Collection of instructions that need to be explored again, e.g., we
4657 /// did assume they do not transfer control to (one of their) successors.
4658 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
4659
4660 /// Collection of instructions that are known to not transfer control.
4661 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
4662
4663 /// Collection of all assumed live edges
4664 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges;
4665
4666 /// Collection of all assumed live BasicBlocks.
4667 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4668};
4669
4670static bool
4671identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4672 AbstractAttribute &AA,
4673 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4674 const IRPosition &IPos = IRPosition::callsite_function(CB);
4675
4676 bool IsKnownNoReturn;
4678 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4679 return !IsKnownNoReturn;
4680 if (CB.isTerminator())
4681 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4682 else
4683 AliveSuccessors.push_back(CB.getNextNode());
4684 return false;
4685}
4686
4687static bool
4688identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4689 AbstractAttribute &AA,
4690 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4691 bool UsedAssumedInformation =
4692 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4693
4694 // First, determine if we can change an invoke to a call assuming the
4695 // callee is nounwind. This is not possible if the personality of the
4696 // function allows to catch asynchronous exceptions.
4697 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4698 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4699 } else {
4700 const IRPosition &IPos = IRPosition::callsite_function(II);
4701
4702 bool IsKnownNoUnwind;
4704 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4705 UsedAssumedInformation |= !IsKnownNoUnwind;
4706 } else {
4707 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4708 }
4709 }
4710 return UsedAssumedInformation;
4711}
4712
4713static bool
4714identifyAliveSuccessors(Attributor &, const UncondBrInst &BI,
4715 AbstractAttribute &,
4716 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4717 AliveSuccessors.push_back(&BI.getSuccessor()->front());
4718 return false;
4719}
4720
4721static bool
4722identifyAliveSuccessors(Attributor &A, const CondBrInst &BI,
4723 AbstractAttribute &AA,
4724 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4725 bool UsedAssumedInformation = false;
4726 std::optional<Constant *> C =
4727 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4728 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4729 // No value yet, assume both edges are dead.
4730 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4731 const BasicBlock *SuccBB =
4732 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4733 AliveSuccessors.push_back(&SuccBB->front());
4734 } else {
4735 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4736 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4737 UsedAssumedInformation = false;
4738 }
4739 return UsedAssumedInformation;
4740}
4741
4742static bool
4743identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4744 AbstractAttribute &AA,
4745 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4746 bool UsedAssumedInformation = false;
4748 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4749 Values, AA::AnyScope,
4750 UsedAssumedInformation)) {
4751 // Something went wrong, assume all successors are live.
4752 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4753 AliveSuccessors.push_back(&SuccBB->front());
4754 return false;
4755 }
4756
4757 if (Values.empty() ||
4758 (Values.size() == 1 &&
4759 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4760 // No valid value yet, assume all edges are dead.
4761 return UsedAssumedInformation;
4762 }
4763
4764 Type &Ty = *SI.getCondition()->getType();
4765 SmallPtrSet<ConstantInt *, 8> Constants;
4766 auto CheckForConstantInt = [&](Value *V) {
4767 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4768 Constants.insert(CI);
4769 return true;
4770 }
4771 return false;
4772 };
4773
4774 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4775 return CheckForConstantInt(VAC.getValue());
4776 })) {
4777 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4778 AliveSuccessors.push_back(&SuccBB->front());
4779 return UsedAssumedInformation;
4780 }
4781
4782 unsigned MatchedCases = 0;
4783 for (const auto &CaseIt : SI.cases()) {
4784 if (Constants.count(CaseIt.getCaseValue())) {
4785 ++MatchedCases;
4786 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4787 }
4788 }
4789
4790 // If all potential values have been matched, we will not visit the default
4791 // case.
4792 if (MatchedCases < Constants.size())
4793 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4794 return UsedAssumedInformation;
4795}
4796
4797ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4799
4800 if (AssumedLiveBlocks.empty()) {
4801 if (isAssumedDeadInternalFunction(A))
4803
4804 Function *F = getAnchorScope();
4805 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4806 assumeLive(A, F->getEntryBlock());
4807 Change = ChangeStatus::CHANGED;
4808 }
4809
4810 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4811 << getAnchorScope()->size() << "] BBs and "
4812 << ToBeExploredFrom.size() << " exploration points and "
4813 << KnownDeadEnds.size() << " known dead ends\n");
4814
4815 // Copy and clear the list of instructions we need to explore from. It is
4816 // refilled with instructions the next update has to look at.
4817 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4818 ToBeExploredFrom.end());
4819 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4820
4822 while (!Worklist.empty()) {
4823 const Instruction *I = Worklist.pop_back_val();
4824 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4825
4826 // Fast forward for uninteresting instructions. We could look for UB here
4827 // though.
4828 while (!I->isTerminator() && !isa<CallBase>(I))
4829 I = I->getNextNode();
4830
4831 AliveSuccessors.clear();
4832
4833 bool UsedAssumedInformation = false;
4834 switch (I->getOpcode()) {
4835 // TODO: look for (assumed) UB to backwards propagate "deadness".
4836 default:
4837 assert(I->isTerminator() &&
4838 "Expected non-terminators to be handled already!");
4839 for (const BasicBlock *SuccBB : successors(I->getParent()))
4840 AliveSuccessors.push_back(&SuccBB->front());
4841 break;
4842 case Instruction::Call:
4843 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4844 *this, AliveSuccessors);
4845 break;
4846 case Instruction::Invoke:
4847 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4848 *this, AliveSuccessors);
4849 break;
4850 case Instruction::UncondBr:
4851 UsedAssumedInformation = identifyAliveSuccessors(
4852 A, cast<UncondBrInst>(*I), *this, AliveSuccessors);
4853 break;
4854 case Instruction::CondBr:
4855 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CondBrInst>(*I),
4856 *this, AliveSuccessors);
4857 break;
4858 case Instruction::Switch:
4859 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4860 *this, AliveSuccessors);
4861 break;
4862 }
4863
4864 if (UsedAssumedInformation) {
4865 NewToBeExploredFrom.insert(I);
4866 } else if (AliveSuccessors.empty() ||
4867 (I->isTerminator() &&
4868 AliveSuccessors.size() < I->getNumSuccessors())) {
4869 if (KnownDeadEnds.insert(I))
4870 Change = ChangeStatus::CHANGED;
4871 }
4872
4873 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4874 << AliveSuccessors.size() << " UsedAssumedInformation: "
4875 << UsedAssumedInformation << "\n");
4876
4877 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4878 if (!I->isTerminator()) {
4879 assert(AliveSuccessors.size() == 1 &&
4880 "Non-terminator expected to have a single successor!");
4881 Worklist.push_back(AliveSuccessor);
4882 } else {
4883 // record the assumed live edge
4884 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4885 if (AssumedLiveEdges.insert(Edge).second)
4886 Change = ChangeStatus::CHANGED;
4887 if (assumeLive(A, *AliveSuccessor->getParent()))
4888 Worklist.push_back(AliveSuccessor);
4889 }
4890 }
4891 }
4892
4893 // Check if the content of ToBeExploredFrom changed, ignore the order.
4894 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4895 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4896 return !ToBeExploredFrom.count(I);
4897 })) {
4898 Change = ChangeStatus::CHANGED;
4899 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4900 }
4901
4902 // If we know everything is live there is no need to query for liveness.
4903 // Instead, indicating a pessimistic fixpoint will cause the state to be
4904 // "invalid" and all queries to be answered conservatively without lookups.
4905 // To be in this state we have to (1) finished the exploration and (3) not
4906 // discovered any non-trivial dead end and (2) not ruled unreachable code
4907 // dead.
4908 if (ToBeExploredFrom.empty() &&
4909 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4910 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4911 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4912 }))
4913 return indicatePessimisticFixpoint();
4914 return Change;
4915}
4916
4917/// Liveness information for a call sites.
4918struct AAIsDeadCallSite final : AAIsDeadFunction {
4919 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4920 : AAIsDeadFunction(IRP, A) {}
4921
4922 /// See AbstractAttribute::initialize(...).
4923 void initialize(Attributor &A) override {
4924 // TODO: Once we have call site specific value information we can provide
4925 // call site specific liveness information and then it makes
4926 // sense to specialize attributes for call sites instead of
4927 // redirecting requests to the callee.
4928 llvm_unreachable("Abstract attributes for liveness are not "
4929 "supported for call sites yet!");
4930 }
4931
4932 /// See AbstractAttribute::updateImpl(...).
4933 ChangeStatus updateImpl(Attributor &A) override {
4934 return indicatePessimisticFixpoint();
4935 }
4936
4937 /// See AbstractAttribute::trackStatistics()
4938 void trackStatistics() const override {}
4939};
4940} // namespace
4941
4942/// -------------------- Dereferenceable Argument Attribute --------------------
4943
4944namespace {
4945struct AADereferenceableImpl : AADereferenceable {
4946 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4947 : AADereferenceable(IRP, A) {}
4948 using StateType = DerefState;
4949
4950 /// See AbstractAttribute::initialize(...).
4951 void initialize(Attributor &A) override {
4952 Value &V = *getAssociatedValue().stripPointerCasts();
4954 A.getAttrs(getIRPosition(),
4955 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4956 Attrs, /* IgnoreSubsumingPositions */ false);
4957 for (const Attribute &Attr : Attrs)
4958 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4959
4960 // Ensure we initialize the non-null AA (if necessary).
4961 bool IsKnownNonNull;
4963 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4964
4965 bool CanBeNull, CanBeFreed;
4966 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4967 A.getDataLayout(), CanBeNull, CanBeFreed));
4968
4969 if (Instruction *CtxI = getCtxI())
4970 followUsesInMBEC(*this, A, getState(), *CtxI);
4971 }
4972
4973 /// See AbstractAttribute::getState()
4974 /// {
4975 StateType &getState() override { return *this; }
4976 const StateType &getState() const override { return *this; }
4977 /// }
4978
4979 /// Helper function for collecting accessed bytes in must-be-executed-context
4980 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4981 DerefState &State) {
4982 const Value *UseV = U->get();
4983 if (!UseV->getType()->isPointerTy())
4984 return;
4985
4986 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4987 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4988 return;
4989
4990 int64_t Offset;
4992 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4993 if (Base && Base == &getAssociatedValue())
4994 State.addAccessedBytes(Offset, Loc->Size.getValue());
4995 }
4996
4997 /// See followUsesInMBEC
4998 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4999 AADereferenceable::StateType &State) {
5000 bool IsNonNull = false;
5001 bool TrackUse = false;
5002 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
5003 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
5004 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
5005 << " for instruction " << *I << "\n");
5006
5007 addAccessedBytesForUse(A, U, I, State);
5008 State.takeKnownDerefBytesMaximum(DerefBytes);
5009 return TrackUse;
5010 }
5011
5012 /// See AbstractAttribute::manifest(...).
5013 ChangeStatus manifest(Attributor &A) override {
5014 ChangeStatus Change = AADereferenceable::manifest(A);
5015 bool IsKnownNonNull;
5016 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5017 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5018 if (IsAssumedNonNull &&
5019 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5020 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5021 return ChangeStatus::CHANGED;
5022 }
5023 return Change;
5024 }
5025
5026 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5027 SmallVectorImpl<Attribute> &Attrs) const override {
5028 // TODO: Add *_globally support
5029 bool IsKnownNonNull;
5030 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5031 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5032 if (IsAssumedNonNull)
5033 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
5034 Ctx, getAssumedDereferenceableBytes()));
5035 else
5036 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
5037 Ctx, getAssumedDereferenceableBytes()));
5038 }
5039
5040 /// See AbstractAttribute::getAsStr().
5041 const std::string getAsStr(Attributor *A) const override {
5042 if (!getAssumedDereferenceableBytes())
5043 return "unknown-dereferenceable";
5044 bool IsKnownNonNull;
5045 bool IsAssumedNonNull = false;
5046 if (A)
5048 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5049 return std::string("dereferenceable") +
5050 (IsAssumedNonNull ? "" : "_or_null") +
5051 (isAssumedGlobal() ? "_globally" : "") + "<" +
5052 std::to_string(getKnownDereferenceableBytes()) + "-" +
5053 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5054 (!A ? " [non-null is unknown]" : "");
5055 }
5056};
5057
5058/// Dereferenceable attribute for a floating value.
5059struct AADereferenceableFloating : AADereferenceableImpl {
5060 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5061 : AADereferenceableImpl(IRP, A) {}
5062
5063 /// See AbstractAttribute::updateImpl(...).
5064 ChangeStatus updateImpl(Attributor &A) override {
5065 bool Stripped;
5066 bool UsedAssumedInformation = false;
5068 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5069 AA::AnyScope, UsedAssumedInformation)) {
5070 Values.push_back({getAssociatedValue(), getCtxI()});
5071 Stripped = false;
5072 } else {
5073 Stripped = Values.size() != 1 ||
5074 Values.front().getValue() != &getAssociatedValue();
5075 }
5076
5077 const DataLayout &DL = A.getDataLayout();
5078 DerefState T;
5079
5080 auto VisitValueCB = [&](const Value &V) -> bool {
5081 unsigned IdxWidth =
5082 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5083 APInt Offset(IdxWidth, 0);
5085 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5086 /* AllowNonInbounds */ true);
5087
5088 const auto *AA = A.getAAFor<AADereferenceable>(
5089 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5090 int64_t DerefBytes = 0;
5091 if (!AA || (!Stripped && this == AA)) {
5092 // Use IR information if we did not strip anything.
5093 // TODO: track globally.
5094 bool CanBeNull, CanBeFreed;
5095 DerefBytes =
5096 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5097 T.GlobalState.indicatePessimisticFixpoint();
5098 } else {
5099 const DerefState &DS = AA->getState();
5100 DerefBytes = DS.DerefBytesState.getAssumed();
5101 T.GlobalState &= DS.GlobalState;
5102 }
5103
5104 // For now we do not try to "increase" dereferenceability due to negative
5105 // indices as we first have to come up with code to deal with loops and
5106 // for overflows of the dereferenceable bytes.
5107 int64_t OffsetSExt = Offset.getSExtValue();
5108 if (OffsetSExt < 0)
5109 OffsetSExt = 0;
5110
5111 T.takeAssumedDerefBytesMinimum(
5112 std::max(int64_t(0), DerefBytes - OffsetSExt));
5113
5114 if (this == AA) {
5115 if (!Stripped) {
5116 // If nothing was stripped IR information is all we got.
5117 T.takeKnownDerefBytesMaximum(
5118 std::max(int64_t(0), DerefBytes - OffsetSExt));
5119 T.indicatePessimisticFixpoint();
5120 } else if (OffsetSExt > 0) {
5121 // If something was stripped but there is circular reasoning we look
5122 // for the offset. If it is positive we basically decrease the
5123 // dereferenceable bytes in a circular loop now, which will simply
5124 // drive them down to the known value in a very slow way which we
5125 // can accelerate.
5126 T.indicatePessimisticFixpoint();
5127 }
5128 }
5129
5130 return T.isValidState();
5131 };
5132
5133 for (const auto &VAC : Values)
5134 if (!VisitValueCB(*VAC.getValue()))
5135 return indicatePessimisticFixpoint();
5136
5137 return clampStateAndIndicateChange(getState(), T);
5138 }
5139
5140 /// See AbstractAttribute::trackStatistics()
5141 void trackStatistics() const override {
5142 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5143 }
5144};
5145
5146/// Dereferenceable attribute for a return value.
5147struct AADereferenceableReturned final
5148 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5149 using Base =
5150 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5151 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5152 : Base(IRP, A) {}
5153
5154 /// See AbstractAttribute::trackStatistics()
5155 void trackStatistics() const override {
5156 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5157 }
5158};
5159
5160/// Dereferenceable attribute for an argument
5161struct AADereferenceableArgument final
5162 : AAArgumentFromCallSiteArguments<AADereferenceable,
5163 AADereferenceableImpl> {
5164 using Base =
5165 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5166 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5167 : Base(IRP, A) {}
5168
5169 /// See AbstractAttribute::trackStatistics()
5170 void trackStatistics() const override {
5171 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5172 }
5173};
5174
5175/// Dereferenceable attribute for a call site argument.
5176struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5177 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5178 : AADereferenceableFloating(IRP, A) {}
5179
5180 /// See AbstractAttribute::trackStatistics()
5181 void trackStatistics() const override {
5182 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5183 }
5184};
5185
5186/// Dereferenceable attribute deduction for a call site return value.
5187struct AADereferenceableCallSiteReturned final
5188 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5189 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5190 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5191 : Base(IRP, A) {}
5192
5193 /// See AbstractAttribute::trackStatistics()
5194 void trackStatistics() const override {
5195 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5196 }
5197};
5198} // namespace
5199
5200// ------------------------ Align Argument Attribute ------------------------
5201
5202namespace {
5203
5204static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5205 Value &AssociatedValue, const Use *U,
5206 const Instruction *I, bool &TrackUse) {
5207 // We need to follow common pointer manipulation uses to the accesses they
5208 // feed into.
5209 if (isa<CastInst>(I)) {
5210 // Follow all but ptr2int casts.
5211 TrackUse = !isa<PtrToIntInst>(I);
5212 return 0;
5213 }
5214 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5215 if (GEP->hasAllConstantIndices())
5216 TrackUse = true;
5217 return 0;
5218 }
5219 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
5220 switch (II->getIntrinsicID()) {
5221 case Intrinsic::ptrmask: {
5222 // Is it appropriate to pull attribute in initialization?
5223 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5224 QueryingAA, IRPosition::value(*II->getOperand(1)), DepClassTy::NONE);
5225 const auto *AlignAA = A.getAAFor<AAAlign>(
5226 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5227 if (ConstVals && ConstVals->isValidState() && ConstVals->isAtFixpoint()) {
5228 unsigned ShiftValue = std::min(ConstVals->getAssumedMinTrailingZeros(),
5230 Align ConstAlign(UINT64_C(1) << ShiftValue);
5231 if (ConstAlign >= AlignAA->getKnownAlign())
5232 return Align(1).value();
5233 }
5234 if (AlignAA)
5235 return AlignAA->getKnownAlign().value();
5236 break;
5237 }
5238 case Intrinsic::amdgcn_make_buffer_rsrc: {
5239 const auto *AlignAA = A.getAAFor<AAAlign>(
5240 QueryingAA, IRPosition::value(*II), DepClassTy::NONE);
5241 if (AlignAA)
5242 return AlignAA->getKnownAlign().value();
5243 break;
5244 }
5245 default:
5246 break;
5247 }
5248
5249 MaybeAlign MA;
5250 if (const auto *CB = dyn_cast<CallBase>(I)) {
5251 if (CB->isBundleOperand(U) || CB->isCallee(U))
5252 return 0;
5253
5254 unsigned ArgNo = CB->getArgOperandNo(U);
5255 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5256 // As long as we only use known information there is no need to track
5257 // dependences here.
5258 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5259 if (AlignAA)
5260 MA = MaybeAlign(AlignAA->getKnownAlign());
5261 }
5262
5263 const DataLayout &DL = A.getDataLayout();
5264 const Value *UseV = U->get();
5265 if (auto *SI = dyn_cast<StoreInst>(I)) {
5266 if (SI->getPointerOperand() == UseV)
5267 MA = SI->getAlign();
5268 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5269 if (LI->getPointerOperand() == UseV)
5270 MA = LI->getAlign();
5271 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5272 if (AI->getPointerOperand() == UseV)
5273 MA = AI->getAlign();
5274 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5275 if (AI->getPointerOperand() == UseV)
5276 MA = AI->getAlign();
5277 }
5278
5279 if (!MA || *MA <= QueryingAA.getKnownAlign())
5280 return 0;
5281
5282 unsigned Alignment = MA->value();
5283 int64_t Offset;
5284
5285 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5286 if (Base == &AssociatedValue) {
5287 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5288 // So we can say that the maximum power of two which is a divisor of
5289 // gcd(Offset, Alignment) is an alignment.
5290
5291 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5292 Alignment = llvm::bit_floor(gcd);
5293 }
5294 }
5295
5296 return Alignment;
5297}
5298
5299struct AAAlignImpl : AAAlign {
5300 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5301
5302 /// See AbstractAttribute::initialize(...).
5303 void initialize(Attributor &A) override {
5305 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5306 for (const Attribute &Attr : Attrs)
5307 takeKnownMaximum(Attr.getValueAsInt());
5308
5309 Value &V = *getAssociatedValue().stripPointerCasts();
5310 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5311
5312 if (Instruction *CtxI = getCtxI())
5313 followUsesInMBEC(*this, A, getState(), *CtxI);
5314 }
5315
5316 /// See AbstractAttribute::manifest(...).
5317 ChangeStatus manifest(Attributor &A) override {
5318 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5319
5320 // Check for users that allow alignment annotations.
5321 Value &AssociatedValue = getAssociatedValue();
5322 if (isa<ConstantData>(AssociatedValue))
5323 return ChangeStatus::UNCHANGED;
5324
5325 for (const Use &U : AssociatedValue.uses()) {
5326 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5327 if (SI->getPointerOperand() == &AssociatedValue)
5328 if (SI->getAlign() < getAssumedAlign()) {
5329 STATS_DECLTRACK(AAAlign, Store,
5330 "Number of times alignment added to a store");
5331 SI->setAlignment(getAssumedAlign());
5332 InstrChanged = ChangeStatus::CHANGED;
5333 }
5334 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5335 if (LI->getPointerOperand() == &AssociatedValue)
5336 if (LI->getAlign() < getAssumedAlign()) {
5337 LI->setAlignment(getAssumedAlign());
5338 STATS_DECLTRACK(AAAlign, Load,
5339 "Number of times alignment added to a load");
5340 InstrChanged = ChangeStatus::CHANGED;
5341 }
5342 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5343 if (RMW->getPointerOperand() == &AssociatedValue) {
5344 if (RMW->getAlign() < getAssumedAlign()) {
5345 STATS_DECLTRACK(AAAlign, AtomicRMW,
5346 "Number of times alignment added to atomicrmw");
5347
5348 RMW->setAlignment(getAssumedAlign());
5349 InstrChanged = ChangeStatus::CHANGED;
5350 }
5351 }
5352 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5353 if (CAS->getPointerOperand() == &AssociatedValue) {
5354 if (CAS->getAlign() < getAssumedAlign()) {
5355 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5356 "Number of times alignment added to cmpxchg");
5357 CAS->setAlignment(getAssumedAlign());
5358 InstrChanged = ChangeStatus::CHANGED;
5359 }
5360 }
5361 }
5362 }
5363
5364 ChangeStatus Changed = AAAlign::manifest(A);
5365
5366 Align InheritAlign =
5367 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5368 if (InheritAlign >= getAssumedAlign())
5369 return InstrChanged;
5370 return Changed | InstrChanged;
5371 }
5372
5373 // TODO: Provide a helper to determine the implied ABI alignment and check in
5374 // the existing manifest method and a new one for AAAlignImpl that value
5375 // to avoid making the alignment explicit if it did not improve.
5376
5377 /// See AbstractAttribute::getDeducedAttributes
5378 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5379 SmallVectorImpl<Attribute> &Attrs) const override {
5380 if (getAssumedAlign() > 1)
5381 Attrs.emplace_back(
5382 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5383 }
5384
5385 /// See followUsesInMBEC
5386 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5387 AAAlign::StateType &State) {
5388 bool TrackUse = false;
5389
5390 unsigned int KnownAlign =
5391 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5392 State.takeKnownMaximum(KnownAlign);
5393
5394 return TrackUse;
5395 }
5396
5397 /// See AbstractAttribute::getAsStr().
5398 const std::string getAsStr(Attributor *A) const override {
5399 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5400 std::to_string(getAssumedAlign().value()) + ">";
5401 }
5402};
5403
5404/// Align attribute for a floating value.
5405struct AAAlignFloating : AAAlignImpl {
5406 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5407
5408 /// See AbstractAttribute::updateImpl(...).
5409 ChangeStatus updateImpl(Attributor &A) override {
5410 const DataLayout &DL = A.getDataLayout();
5411
5412 bool Stripped;
5413 bool UsedAssumedInformation = false;
5415 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5416 AA::AnyScope, UsedAssumedInformation)) {
5417 Values.push_back({getAssociatedValue(), getCtxI()});
5418 Stripped = false;
5419 } else {
5420 Stripped = Values.size() != 1 ||
5421 Values.front().getValue() != &getAssociatedValue();
5422 }
5423
5424 StateType T;
5425 auto VisitValueCB = [&](Value &V) -> bool {
5427 return true;
5428 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5429 DepClassTy::REQUIRED);
5430 if (!AA || (!Stripped && this == AA)) {
5431 int64_t Offset;
5432 unsigned Alignment = 1;
5433 if (const Value *Base =
5435 // TODO: Use AAAlign for the base too.
5436 Align PA = Base->getPointerAlignment(DL);
5437 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5438 // So we can say that the maximum power of two which is a divisor of
5439 // gcd(Offset, Alignment) is an alignment.
5440
5441 uint32_t gcd =
5442 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5443 Alignment = llvm::bit_floor(gcd);
5444 } else {
5445 Alignment = V.getPointerAlignment(DL).value();
5446 }
5447 // Use only IR information if we did not strip anything.
5448 T.takeKnownMaximum(Alignment);
5449 T.indicatePessimisticFixpoint();
5450 } else {
5451 // Use abstract attribute information.
5452 const AAAlign::StateType &DS = AA->getState();
5453 T ^= DS;
5454 }
5455 return T.isValidState();
5456 };
5457
5458 for (const auto &VAC : Values) {
5459 if (!VisitValueCB(*VAC.getValue()))
5460 return indicatePessimisticFixpoint();
5461 }
5462
5463 // TODO: If we know we visited all incoming values, thus no are assumed
5464 // dead, we can take the known information from the state T.
5465 return clampStateAndIndicateChange(getState(), T);
5466 }
5467
5468 /// See AbstractAttribute::trackStatistics()
5469 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5470};
5471
5472/// Align attribute for function return value.
5473struct AAAlignReturned final
5474 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5475 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5476 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5477
5478 /// See AbstractAttribute::trackStatistics()
5479 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5480};
5481
5482/// Align attribute for function argument.
5483struct AAAlignArgument final
5484 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5485 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5486 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5487
5488 /// See AbstractAttribute::manifest(...).
5489 ChangeStatus manifest(Attributor &A) override {
5490 // If the associated argument is involved in a must-tail call we give up
5491 // because we would need to keep the argument alignments of caller and
5492 // callee in-sync. Just does not seem worth the trouble right now.
5493 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5494 return ChangeStatus::UNCHANGED;
5495 return Base::manifest(A);
5496 }
5497
5498 /// See AbstractAttribute::trackStatistics()
5499 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5500};
5501
5502struct AAAlignCallSiteArgument final : AAAlignFloating {
5503 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5504 : AAAlignFloating(IRP, A) {}
5505
5506 /// See AbstractAttribute::manifest(...).
5507 ChangeStatus manifest(Attributor &A) override {
5508 // If the associated argument is involved in a must-tail call we give up
5509 // because we would need to keep the argument alignments of caller and
5510 // callee in-sync. Just does not seem worth the trouble right now.
5511 if (Argument *Arg = getAssociatedArgument())
5512 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5513 return ChangeStatus::UNCHANGED;
5514 ChangeStatus Changed = AAAlignImpl::manifest(A);
5515 Align InheritAlign =
5516 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5517 if (InheritAlign >= getAssumedAlign())
5518 Changed = ChangeStatus::UNCHANGED;
5519 return Changed;
5520 }
5521
5522 /// See AbstractAttribute::updateImpl(Attributor &A).
5523 ChangeStatus updateImpl(Attributor &A) override {
5524 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5525 if (Argument *Arg = getAssociatedArgument()) {
5526 // We only take known information from the argument
5527 // so we do not need to track a dependence.
5528 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5529 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5530 if (ArgAlignAA)
5531 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5532 }
5533 return Changed;
5534 }
5535
5536 /// See AbstractAttribute::trackStatistics()
5537 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5538};
5539
5540/// Align attribute deduction for a call site return value.
5541struct AAAlignCallSiteReturned final
5542 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5543 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5544 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5545 : Base(IRP, A) {}
5546
5547 ChangeStatus updateImpl(Attributor &A) override {
5548 Instruction *I = getIRPosition().getCtxI();
5549 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
5550 switch (II->getIntrinsicID()) {
5551 case Intrinsic::ptrmask: {
5552 Align Alignment;
5553 bool Valid = false;
5554
5555 const auto *ConstVals = A.getAAFor<AAPotentialConstantValues>(
5556 *this, IRPosition::value(*II->getOperand(1)), DepClassTy::REQUIRED);
5557 if (ConstVals && ConstVals->isValidState()) {
5558 unsigned ShiftValue =
5559 std::min(ConstVals->getAssumedMinTrailingZeros(),
5560 Value::MaxAlignmentExponent);
5561 Alignment = Align(UINT64_C(1) << ShiftValue);
5562 Valid = true;
5563 }
5564
5565 const auto *AlignAA =
5566 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5567 DepClassTy::REQUIRED);
5568 if (AlignAA) {
5569 Alignment = std::max(AlignAA->getAssumedAlign(), Alignment);
5570 Valid = true;
5571 }
5572
5573 if (Valid)
5575 this->getState(),
5576 std::min(this->getAssumedAlign(), Alignment).value());
5577 break;
5578 }
5579 // FIXME: Should introduce target specific sub-attributes and letting
5580 // getAAfor<AAAlign> lead to create sub-attribute to handle target
5581 // specific intrinsics.
5582 case Intrinsic::amdgcn_make_buffer_rsrc: {
5583 const auto *AlignAA =
5584 A.getAAFor<AAAlign>(*this, IRPosition::value(*(II->getOperand(0))),
5585 DepClassTy::REQUIRED);
5586 if (AlignAA)
5588 this->getState(), AlignAA->getAssumedAlign().value());
5589 break;
5590 }
5591 default:
5592 break;
5593 }
5594 }
5595 return Base::updateImpl(A);
5596 };
5597 /// See AbstractAttribute::trackStatistics()
5598 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5599};
5600} // namespace
5601
5602/// ------------------ Function No-Return Attribute ----------------------------
5603namespace {
5604struct AANoReturnImpl : public AANoReturn {
5605 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5606
5607 /// See AbstractAttribute::initialize(...).
5608 void initialize(Attributor &A) override {
5609 bool IsKnown;
5611 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5612 (void)IsKnown;
5613 }
5614
5615 /// See AbstractAttribute::getAsStr().
5616 const std::string getAsStr(Attributor *A) const override {
5617 return getAssumed() ? "noreturn" : "may-return";
5618 }
5619
5620 /// See AbstractAttribute::updateImpl(Attributor &A).
5621 ChangeStatus updateImpl(Attributor &A) override {
5622 auto CheckForNoReturn = [](Instruction &) { return false; };
5623 bool UsedAssumedInformation = false;
5624 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5625 {(unsigned)Instruction::Ret},
5626 UsedAssumedInformation))
5627 return indicatePessimisticFixpoint();
5628 return ChangeStatus::UNCHANGED;
5629 }
5630};
5631
5632struct AANoReturnFunction final : AANoReturnImpl {
5633 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5634 : AANoReturnImpl(IRP, A) {}
5635
5636 /// See AbstractAttribute::trackStatistics()
5637 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5638};
5639
5640/// NoReturn attribute deduction for a call sites.
5641struct AANoReturnCallSite final
5642 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5643 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5644 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5645
5646 /// See AbstractAttribute::trackStatistics()
5647 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5648};
5649} // namespace
5650
5651/// ----------------------- Instance Info ---------------------------------
5652
5653namespace {
5654/// A class to hold the state of for no-capture attributes.
5655struct AAInstanceInfoImpl : public AAInstanceInfo {
5656 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5657 : AAInstanceInfo(IRP, A) {}
5658
5659 /// See AbstractAttribute::initialize(...).
5660 void initialize(Attributor &A) override {
5661 Value &V = getAssociatedValue();
5662 if (auto *C = dyn_cast<Constant>(&V)) {
5663 if (C->isThreadDependent())
5664 indicatePessimisticFixpoint();
5665 else
5666 indicateOptimisticFixpoint();
5667 return;
5668 }
5669 if (auto *CB = dyn_cast<CallBase>(&V))
5670 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5671 !CB->mayReadFromMemory()) {
5672 indicateOptimisticFixpoint();
5673 return;
5674 }
5675 if (auto *I = dyn_cast<Instruction>(&V)) {
5676 const auto *CI =
5677 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5678 *I->getFunction());
5679 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5680 indicatePessimisticFixpoint();
5681 return;
5682 }
5683 }
5684 }
5685
5686 /// See AbstractAttribute::updateImpl(...).
5687 ChangeStatus updateImpl(Attributor &A) override {
5688 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5689
5690 Value &V = getAssociatedValue();
5691 const Function *Scope = nullptr;
5692 if (auto *I = dyn_cast<Instruction>(&V))
5693 Scope = I->getFunction();
5694 if (auto *A = dyn_cast<Argument>(&V)) {
5695 Scope = A->getParent();
5696 if (!Scope->hasLocalLinkage())
5697 return Changed;
5698 }
5699 if (!Scope)
5700 return indicateOptimisticFixpoint();
5701
5702 bool IsKnownNoRecurse;
5704 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5705 IsKnownNoRecurse))
5706 return Changed;
5707
5708 auto UsePred = [&](const Use &U, bool &Follow) {
5709 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5710 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5711 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5712 Follow = true;
5713 return true;
5714 }
5715 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5716 (isa<StoreInst>(UserI) &&
5717 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5718 return true;
5719 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5720 // This check is not guaranteeing uniqueness but for now that we cannot
5721 // end up with two versions of \p U thinking it was one.
5723 if (!Callee || !Callee->hasLocalLinkage())
5724 return true;
5725 if (!CB->isArgOperand(&U))
5726 return false;
5727 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5729 DepClassTy::OPTIONAL);
5730 if (!ArgInstanceInfoAA ||
5731 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5732 return false;
5733 // If this call base might reach the scope again we might forward the
5734 // argument back here. This is very conservative.
5736 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5737 [Scope](const Function &Fn) { return &Fn != Scope; }))
5738 return false;
5739 return true;
5740 }
5741 return false;
5742 };
5743
5744 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5745 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5746 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5747 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5748 AA::isDynamicallyUnique(A, *this, *Ptr))
5749 return true;
5750 }
5751 return false;
5752 };
5753
5754 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5755 DepClassTy::OPTIONAL,
5756 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5757 return indicatePessimisticFixpoint();
5758
5759 return Changed;
5760 }
5761
5762 /// See AbstractState::getAsStr().
5763 const std::string getAsStr(Attributor *A) const override {
5764 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5765 }
5766
5767 /// See AbstractAttribute::trackStatistics()
5768 void trackStatistics() const override {}
5769};
5770
5771/// InstanceInfo attribute for floating values.
5772struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5773 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5774 : AAInstanceInfoImpl(IRP, A) {}
5775};
5776
5777/// NoCapture attribute for function arguments.
5778struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5779 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5780 : AAInstanceInfoFloating(IRP, A) {}
5781};
5782
5783/// InstanceInfo attribute for call site arguments.
5784struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5785 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5786 : AAInstanceInfoImpl(IRP, A) {}
5787
5788 /// See AbstractAttribute::updateImpl(...).
5789 ChangeStatus updateImpl(Attributor &A) override {
5790 // TODO: Once we have call site specific value information we can provide
5791 // call site specific liveness information and then it makes
5792 // sense to specialize attributes for call sites arguments instead of
5793 // redirecting requests to the callee argument.
5794 Argument *Arg = getAssociatedArgument();
5795 if (!Arg)
5796 return indicatePessimisticFixpoint();
5797 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5798 auto *ArgAA =
5799 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5800 if (!ArgAA)
5801 return indicatePessimisticFixpoint();
5802 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5803 }
5804};
5805
5806/// InstanceInfo attribute for function return value.
5807struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5808 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5809 : AAInstanceInfoImpl(IRP, A) {
5810 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5811 }
5812
5813 /// See AbstractAttribute::initialize(...).
5814 void initialize(Attributor &A) override {
5815 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5816 }
5817
5818 /// See AbstractAttribute::updateImpl(...).
5819 ChangeStatus updateImpl(Attributor &A) override {
5820 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5821 }
5822};
5823
5824/// InstanceInfo attribute deduction for a call site return value.
5825struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5826 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5827 : AAInstanceInfoFloating(IRP, A) {}
5828};
5829} // namespace
5830
5831/// ----------------------- Variable Capturing ---------------------------------
5833 Attribute::AttrKind ImpliedAttributeKind,
5834 bool IgnoreSubsumingPositions) {
5835 assert(ImpliedAttributeKind == Attribute::Captures &&
5836 "Unexpected attribute kind");
5837 Value &V = IRP.getAssociatedValue();
5838 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5839 return V.use_empty();
5840
5841 // You cannot "capture" null in the default address space.
5842 //
5843 // FIXME: This should use NullPointerIsDefined to account for the function
5844 // attribute.
5846 V.getType()->getPointerAddressSpace() == 0)) {
5847 return true;
5848 }
5849
5851 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5852 /* IgnoreSubsumingPositions */ true);
5853 for (const Attribute &Attr : Attrs)
5854 if (capturesNothing(Attr.getCaptureInfo()))
5855 return true;
5856
5858 if (Argument *Arg = IRP.getAssociatedArgument()) {
5860 A.getAttrs(IRPosition::argument(*Arg),
5861 {Attribute::Captures, Attribute::ByVal}, Attrs,
5862 /* IgnoreSubsumingPositions */ true);
5863 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5864 return Attr.getKindAsEnum() == Attribute::ByVal ||
5866 });
5867 if (ArgNoCapture) {
5868 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5869 V.getContext(), CaptureInfo::none()));
5870 return true;
5871 }
5872 }
5873
5874 if (const Function *F = IRP.getAssociatedFunction()) {
5875 // Check what state the associated function can actually capture.
5878 if (State.isKnown(NO_CAPTURE)) {
5879 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5881 return true;
5882 }
5883 }
5884
5885 return false;
5886}
5887
5888/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5889/// depending on the ability of the function associated with \p IRP to capture
5890/// state in memory and through "returning/throwing", respectively.
5892 const Function &F,
5893 BitIntegerState &State) {
5894 // TODO: Once we have memory behavior attributes we should use them here.
5895
5896 // If we know we cannot communicate or write to memory, we do not care about
5897 // ptr2int anymore.
5898 bool ReadOnly = F.onlyReadsMemory();
5899 bool NoThrow = F.doesNotThrow();
5900 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5901 if (ReadOnly && NoThrow && IsVoidReturn) {
5902 State.addKnownBits(NO_CAPTURE);
5903 return;
5904 }
5905
5906 // A function cannot capture state in memory if it only reads memory, it can
5907 // however return/throw state and the state might be influenced by the
5908 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5909 if (ReadOnly)
5910 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5911
5912 // A function cannot communicate state back if it does not through
5913 // exceptions and doesn not return values.
5914 if (NoThrow && IsVoidReturn)
5915 State.addKnownBits(NOT_CAPTURED_IN_RET);
5916
5917 // Check existing "returned" attributes.
5918 int ArgNo = IRP.getCalleeArgNo();
5919 if (!NoThrow || ArgNo < 0 ||
5920 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5921 return;
5922
5923 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5924 if (F.hasParamAttribute(U, Attribute::Returned)) {
5925 if (U == unsigned(ArgNo))
5926 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5927 else if (ReadOnly)
5928 State.addKnownBits(NO_CAPTURE);
5929 else
5930 State.addKnownBits(NOT_CAPTURED_IN_RET);
5931 break;
5932 }
5933}
5934
5935namespace {
5936/// A class to hold the state of for no-capture attributes.
5937struct AANoCaptureImpl : public AANoCapture {
5938 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5939
5940 /// See AbstractAttribute::initialize(...).
5941 void initialize(Attributor &A) override {
5942 bool IsKnown;
5944 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5945 (void)IsKnown;
5946 }
5947
5948 /// See AbstractAttribute::updateImpl(...).
5949 ChangeStatus updateImpl(Attributor &A) override;
5950
5951 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5952 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5953 SmallVectorImpl<Attribute> &Attrs) const override {
5954 if (!isAssumedNoCaptureMaybeReturned())
5955 return;
5956
5957 if (isArgumentPosition()) {
5958 if (isAssumedNoCapture())
5959 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5960 else if (ManifestInternal)
5961 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5962 }
5963 }
5964
5965 /// See AbstractState::getAsStr().
5966 const std::string getAsStr(Attributor *A) const override {
5967 if (isKnownNoCapture())
5968 return "known not-captured";
5969 if (isAssumedNoCapture())
5970 return "assumed not-captured";
5971 if (isKnownNoCaptureMaybeReturned())
5972 return "known not-captured-maybe-returned";
5973 if (isAssumedNoCaptureMaybeReturned())
5974 return "assumed not-captured-maybe-returned";
5975 return "assumed-captured";
5976 }
5977
5978 /// Check the use \p U and update \p State accordingly. Return true if we
5979 /// should continue to update the state.
5980 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5981 bool &Follow) {
5982 Instruction *UInst = cast<Instruction>(U.getUser());
5983 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5984 << *UInst << "\n");
5985
5986 // Deal with ptr2int by following uses.
5987 if (isa<PtrToIntInst>(UInst)) {
5988 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5989 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5990 /* Return */ true);
5991 }
5992
5993 // For stores we already checked if we can follow them, if they make it
5994 // here we give up.
5995 if (isa<StoreInst>(UInst))
5996 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5997 /* Return */ true);
5998
5999 // Explicitly catch return instructions.
6000 if (isa<ReturnInst>(UInst)) {
6001 if (UInst->getFunction() == getAnchorScope())
6002 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6003 /* Return */ true);
6004 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6005 /* Return */ true);
6006 }
6007
6008 // For now we only use special logic for call sites. However, the tracker
6009 // itself knows about a lot of other non-capturing cases already.
6010 auto *CB = dyn_cast<CallBase>(UInst);
6011 if (!CB || !CB->isArgOperand(&U))
6012 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6013 /* Return */ true);
6014
6015 unsigned ArgNo = CB->getArgOperandNo(&U);
6016 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
6017 // If we have a abstract no-capture attribute for the argument we can use
6018 // it to justify a non-capture attribute here. This allows recursion!
6019 bool IsKnownNoCapture;
6020 const AANoCapture *ArgNoCaptureAA = nullptr;
6021 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
6022 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6023 &ArgNoCaptureAA);
6024 if (IsAssumedNoCapture)
6025 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6026 /* Return */ false);
6027 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
6028 Follow = true;
6029 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
6030 /* Return */ false);
6031 }
6032
6033 // Lastly, we could not find a reason no-capture can be assumed so we don't.
6034 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
6035 /* Return */ true);
6036 }
6037
6038 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
6039 /// \p CapturedInRet, then return true if we should continue updating the
6040 /// state.
6041 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
6042 bool CapturedInInt, bool CapturedInRet) {
6043 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
6044 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
6045 if (CapturedInMem)
6046 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
6047 if (CapturedInInt)
6048 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
6049 if (CapturedInRet)
6050 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
6051 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
6052 }
6053};
6054
6055ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
6056 const IRPosition &IRP = getIRPosition();
6057 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
6058 : &IRP.getAssociatedValue();
6059 if (!V)
6060 return indicatePessimisticFixpoint();
6061
6062 const Function *F =
6063 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
6064
6065 // TODO: Is the checkForAllUses below useful for constants?
6066 if (!F)
6067 return indicatePessimisticFixpoint();
6068
6070 const IRPosition &FnPos = IRPosition::function(*F);
6071
6072 // Readonly means we cannot capture through memory.
6073 bool IsKnown;
6074 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
6075 T.addKnownBits(NOT_CAPTURED_IN_MEM);
6076 if (IsKnown)
6077 addKnownBits(NOT_CAPTURED_IN_MEM);
6078 }
6079
6080 // Make sure all returned values are different than the underlying value.
6081 // TODO: we could do this in a more sophisticated way inside
6082 // AAReturnedValues, e.g., track all values that escape through returns
6083 // directly somehow.
6084 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
6086 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
6088 UsedAssumedInformation))
6089 return false;
6090 bool SeenConstant = false;
6091 for (const AA::ValueAndContext &VAC : Values) {
6092 if (isa<Constant>(VAC.getValue())) {
6093 if (SeenConstant)
6094 return false;
6095 SeenConstant = true;
6096 } else if (!isa<Argument>(VAC.getValue()) ||
6097 VAC.getValue() == getAssociatedArgument())
6098 return false;
6099 }
6100 return true;
6101 };
6102
6103 bool IsKnownNoUnwind;
6105 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6106 bool IsVoidTy = F->getReturnType()->isVoidTy();
6107 bool UsedAssumedInformation = false;
6108 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6109 T.addKnownBits(NOT_CAPTURED_IN_RET);
6110 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6112 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6113 addKnownBits(NOT_CAPTURED_IN_RET);
6114 if (isKnown(NOT_CAPTURED_IN_MEM))
6115 return indicateOptimisticFixpoint();
6116 }
6117 }
6118 }
6119
6120 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6121 // TODO(captures): Make this more precise.
6122 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6123 if (capturesNothing(CI))
6124 return true;
6125 if (CI.isPassthrough()) {
6126 Follow = true;
6127 return true;
6128 }
6129 return checkUse(A, T, U, Follow);
6130 };
6131
6132 if (!A.checkForAllUses(UseCheck, *this, *V))
6133 return indicatePessimisticFixpoint();
6134
6135 AANoCapture::StateType &S = getState();
6136 auto Assumed = S.getAssumed();
6137 S.intersectAssumedBits(T.getAssumed());
6138 if (!isAssumedNoCaptureMaybeReturned())
6139 return indicatePessimisticFixpoint();
6140 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6142}
6143
6144/// NoCapture attribute for function arguments.
6145struct AANoCaptureArgument final : AANoCaptureImpl {
6146 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6147 : AANoCaptureImpl(IRP, A) {}
6148
6149 /// See AbstractAttribute::trackStatistics()
6150 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6151};
6152
6153/// NoCapture attribute for call site arguments.
6154struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6155 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6156 : AANoCaptureImpl(IRP, A) {}
6157
6158 /// See AbstractAttribute::updateImpl(...).
6159 ChangeStatus updateImpl(Attributor &A) override {
6160 // TODO: Once we have call site specific value information we can provide
6161 // call site specific liveness information and then it makes
6162 // sense to specialize attributes for call sites arguments instead of
6163 // redirecting requests to the callee argument.
6164 Argument *Arg = getAssociatedArgument();
6165 if (!Arg)
6166 return indicatePessimisticFixpoint();
6167 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6168 bool IsKnownNoCapture;
6169 const AANoCapture *ArgAA = nullptr;
6171 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6172 &ArgAA))
6173 return ChangeStatus::UNCHANGED;
6174 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6175 return indicatePessimisticFixpoint();
6176 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6177 }
6178
6179 /// See AbstractAttribute::trackStatistics()
6180 void trackStatistics() const override {
6182 };
6183};
6184
6185/// NoCapture attribute for floating values.
6186struct AANoCaptureFloating final : AANoCaptureImpl {
6187 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6188 : AANoCaptureImpl(IRP, A) {}
6189
6190 /// See AbstractAttribute::trackStatistics()
6191 void trackStatistics() const override {
6193 }
6194};
6195
6196/// NoCapture attribute for function return value.
6197struct AANoCaptureReturned final : AANoCaptureImpl {
6198 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6199 : AANoCaptureImpl(IRP, A) {
6200 llvm_unreachable("NoCapture is not applicable to function returns!");
6201 }
6202
6203 /// See AbstractAttribute::initialize(...).
6204 void initialize(Attributor &A) override {
6205 llvm_unreachable("NoCapture is not applicable to function returns!");
6206 }
6207
6208 /// See AbstractAttribute::updateImpl(...).
6209 ChangeStatus updateImpl(Attributor &A) override {
6210 llvm_unreachable("NoCapture is not applicable to function returns!");
6211 }
6212
6213 /// See AbstractAttribute::trackStatistics()
6214 void trackStatistics() const override {}
6215};
6216
6217/// NoCapture attribute deduction for a call site return value.
6218struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6219 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6220 : AANoCaptureImpl(IRP, A) {}
6221
6222 /// See AbstractAttribute::initialize(...).
6223 void initialize(Attributor &A) override {
6224 const Function *F = getAnchorScope();
6225 // Check what state the associated function can actually capture.
6226 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6227 }
6228
6229 /// See AbstractAttribute::trackStatistics()
6230 void trackStatistics() const override {
6232 }
6233};
6234} // namespace
6235
6236/// ------------------ Value Simplify Attribute ----------------------------
6237
6238bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6239 // FIXME: Add a typecast support.
6242 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6243 return false;
6244
6245 LLVM_DEBUG({
6247 dbgs() << "[ValueSimplify] is assumed to be "
6248 << **SimplifiedAssociatedValue << "\n";
6249 else
6250 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6251 });
6252 return true;
6253}
6254
6255namespace {
6256struct AAValueSimplifyImpl : AAValueSimplify {
6257 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6258 : AAValueSimplify(IRP, A) {}
6259
6260 /// See AbstractAttribute::initialize(...).
6261 void initialize(Attributor &A) override {
6262 if (getAssociatedValue().getType()->isVoidTy())
6263 indicatePessimisticFixpoint();
6264 if (A.hasSimplificationCallback(getIRPosition()))
6265 indicatePessimisticFixpoint();
6266 }
6267
6268 /// See AbstractAttribute::getAsStr().
6269 const std::string getAsStr(Attributor *A) const override {
6270 LLVM_DEBUG({
6271 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6272 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6273 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6274 });
6275 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6276 : "not-simple";
6277 }
6278
6279 /// See AbstractAttribute::trackStatistics()
6280 void trackStatistics() const override {}
6281
6282 /// See AAValueSimplify::getAssumedSimplifiedValue()
6283 std::optional<Value *>
6284 getAssumedSimplifiedValue(Attributor &A) const override {
6285 return SimplifiedAssociatedValue;
6286 }
6287
6288 /// Ensure the return value is \p V with type \p Ty, if not possible return
6289 /// nullptr. If \p Check is true we will only verify such an operation would
6290 /// suceed and return a non-nullptr value if that is the case. No IR is
6291 /// generated or modified.
6292 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6293 bool Check) {
6294 if (auto *TypedV = AA::getWithType(V, Ty))
6295 return TypedV;
6296 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6297 return Check ? &V
6298 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6299 &V, &Ty, "", CtxI->getIterator());
6300 return nullptr;
6301 }
6302
6303 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6304 /// If \p Check is true we will only verify such an operation would suceed and
6305 /// return a non-nullptr value if that is the case. No IR is generated or
6306 /// modified.
6307 static Value *reproduceInst(Attributor &A,
6308 const AbstractAttribute &QueryingAA,
6309 Instruction &I, Type &Ty, Instruction *CtxI,
6310 bool Check, ValueToValueMapTy &VMap) {
6311 assert(CtxI && "Cannot reproduce an instruction without context!");
6312 if (Check && (I.mayReadFromMemory() ||
6313 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6314 /* TLI */ nullptr)))
6315 return nullptr;
6316 for (Value *Op : I.operands()) {
6317 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6318 if (!NewOp) {
6319 assert(Check && "Manifest of new value unexpectedly failed!");
6320 return nullptr;
6321 }
6322 if (!Check)
6323 VMap[Op] = NewOp;
6324 }
6325 if (Check)
6326 return &I;
6327
6328 Instruction *CloneI = I.clone();
6329 // TODO: Try to salvage debug information here.
6330 CloneI->setDebugLoc(DebugLoc());
6331 VMap[&I] = CloneI;
6332 CloneI->insertBefore(CtxI->getIterator());
6333 RemapInstruction(CloneI, VMap);
6334 return CloneI;
6335 }
6336
6337 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6338 /// If \p Check is true we will only verify such an operation would suceed and
6339 /// return a non-nullptr value if that is the case. No IR is generated or
6340 /// modified.
6341 static Value *reproduceValue(Attributor &A,
6342 const AbstractAttribute &QueryingAA, Value &V,
6343 Type &Ty, Instruction *CtxI, bool Check,
6344 ValueToValueMapTy &VMap) {
6345 if (const auto &NewV = VMap.lookup(&V))
6346 return NewV;
6347 bool UsedAssumedInformation = false;
6348 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6349 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6350 if (!SimpleV.has_value())
6351 return PoisonValue::get(&Ty);
6352 Value *EffectiveV = &V;
6353 if (*SimpleV)
6354 EffectiveV = *SimpleV;
6355 if (auto *C = dyn_cast<Constant>(EffectiveV))
6356 return C;
6357 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6358 A.getInfoCache()))
6359 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6360 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6361 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6362 return ensureType(A, *NewV, Ty, CtxI, Check);
6363 return nullptr;
6364 }
6365
6366 /// Return a value we can use as replacement for the associated one, or
6367 /// nullptr if we don't have one that makes sense.
6368 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6369 Value *NewV = SimplifiedAssociatedValue
6370 ? *SimplifiedAssociatedValue
6371 : UndefValue::get(getAssociatedType());
6372 if (NewV && NewV != &getAssociatedValue()) {
6373 ValueToValueMapTy VMap;
6374 // First verify we can reprduce the value with the required type at the
6375 // context location before we actually start modifying the IR.
6376 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6377 /* CheckOnly */ true, VMap))
6378 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6379 /* CheckOnly */ false, VMap);
6380 }
6381 return nullptr;
6382 }
6383
6384 /// Helper function for querying AAValueSimplify and updating candidate.
6385 /// \param IRP The value position we are trying to unify with SimplifiedValue
6386 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6387 const IRPosition &IRP, bool Simplify = true) {
6388 bool UsedAssumedInformation = false;
6389 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6390 if (Simplify)
6391 QueryingValueSimplified = A.getAssumedSimplified(
6392 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6393 return unionAssumed(QueryingValueSimplified);
6394 }
6395
6396 /// Returns a candidate is found or not
6397 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6398 if (!getAssociatedValue().getType()->isIntegerTy())
6399 return false;
6400
6401 // This will also pass the call base context.
6402 const auto *AA =
6403 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6404 if (!AA)
6405 return false;
6406
6407 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6408
6409 if (!COpt) {
6410 SimplifiedAssociatedValue = std::nullopt;
6411 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6412 return true;
6413 }
6414 if (auto *C = *COpt) {
6415 SimplifiedAssociatedValue = C;
6416 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6417 return true;
6418 }
6419 return false;
6420 }
6421
6422 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6423 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6424 return true;
6425 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6426 return true;
6427 return false;
6428 }
6429
6430 /// See AbstractAttribute::manifest(...).
6431 ChangeStatus manifest(Attributor &A) override {
6432 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6433 for (auto &U : getAssociatedValue().uses()) {
6434 // Check if we need to adjust the insertion point to make sure the IR is
6435 // valid.
6436 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6437 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6438 IP = PHI->getIncomingBlock(U)->getTerminator();
6439 if (auto *NewV = manifestReplacementValue(A, IP)) {
6440 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6441 << " -> " << *NewV << " :: " << *this << "\n");
6442 if (A.changeUseAfterManifest(U, *NewV))
6443 Changed = ChangeStatus::CHANGED;
6444 }
6445 }
6446
6447 return Changed | AAValueSimplify::manifest(A);
6448 }
6449
6450 /// See AbstractState::indicatePessimisticFixpoint(...).
6451 ChangeStatus indicatePessimisticFixpoint() override {
6452 SimplifiedAssociatedValue = &getAssociatedValue();
6453 return AAValueSimplify::indicatePessimisticFixpoint();
6454 }
6455};
6456
6457struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6458 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6459 : AAValueSimplifyImpl(IRP, A) {}
6460
6461 void initialize(Attributor &A) override {
6462 AAValueSimplifyImpl::initialize(A);
6463 if (A.hasAttr(getIRPosition(),
6464 {Attribute::InAlloca, Attribute::Preallocated,
6465 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6466 /* IgnoreSubsumingPositions */ true))
6467 indicatePessimisticFixpoint();
6468 }
6469
6470 /// See AbstractAttribute::updateImpl(...).
6471 ChangeStatus updateImpl(Attributor &A) override {
6472 // Byval is only replacable if it is readonly otherwise we would write into
6473 // the replaced value and not the copy that byval creates implicitly.
6474 Argument *Arg = getAssociatedArgument();
6475 if (Arg->hasByValAttr()) {
6476 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6477 // there is no race by not copying a constant byval.
6478 bool IsKnown;
6479 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6480 return indicatePessimisticFixpoint();
6481 }
6482
6483 auto Before = SimplifiedAssociatedValue;
6484
6485 auto PredForCallSite = [&](AbstractCallSite ACS) {
6486 const IRPosition &ACSArgPos =
6487 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6488 // Check if a coresponding argument was found or if it is on not
6489 // associated (which can happen for callback calls).
6490 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6491 return false;
6492
6493 // Simplify the argument operand explicitly and check if the result is
6494 // valid in the current scope. This avoids refering to simplified values
6495 // in other functions, e.g., we don't want to say a an argument in a
6496 // static function is actually an argument in a different function.
6497 bool UsedAssumedInformation = false;
6498 std::optional<Constant *> SimpleArgOp =
6499 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6500 if (!SimpleArgOp)
6501 return true;
6502 if (!*SimpleArgOp)
6503 return false;
6504 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6505 return false;
6506 return unionAssumed(*SimpleArgOp);
6507 };
6508
6509 // Generate a answer specific to a call site context.
6510 bool Success;
6511 bool UsedAssumedInformation = false;
6512 if (hasCallBaseContext() &&
6513 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6514 Success = PredForCallSite(
6515 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6516 else
6517 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6518 UsedAssumedInformation);
6519
6520 if (!Success)
6521 if (!askSimplifiedValueForOtherAAs(A))
6522 return indicatePessimisticFixpoint();
6523
6524 // If a candidate was found in this update, return CHANGED.
6525 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6526 : ChangeStatus ::CHANGED;
6527 }
6528
6529 /// See AbstractAttribute::trackStatistics()
6530 void trackStatistics() const override {
6531 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6532 }
6533};
6534
6535struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6536 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6537 : AAValueSimplifyImpl(IRP, A) {}
6538
6539 /// See AAValueSimplify::getAssumedSimplifiedValue()
6540 std::optional<Value *>
6541 getAssumedSimplifiedValue(Attributor &A) const override {
6542 if (!isValidState())
6543 return nullptr;
6544 return SimplifiedAssociatedValue;
6545 }
6546
6547 /// See AbstractAttribute::updateImpl(...).
6548 ChangeStatus updateImpl(Attributor &A) override {
6549 auto Before = SimplifiedAssociatedValue;
6550
6551 auto ReturnInstCB = [&](Instruction &I) {
6552 auto &RI = cast<ReturnInst>(I);
6553 return checkAndUpdate(
6554 A, *this,
6555 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6556 };
6557
6558 bool UsedAssumedInformation = false;
6559 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6560 UsedAssumedInformation))
6561 if (!askSimplifiedValueForOtherAAs(A))
6562 return indicatePessimisticFixpoint();
6563
6564 // If a candidate was found in this update, return CHANGED.
6565 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6566 : ChangeStatus ::CHANGED;
6567 }
6568
6569 ChangeStatus manifest(Attributor &A) override {
6570 // We queried AAValueSimplify for the returned values so they will be
6571 // replaced if a simplified form was found. Nothing to do here.
6572 return ChangeStatus::UNCHANGED;
6573 }
6574
6575 /// See AbstractAttribute::trackStatistics()
6576 void trackStatistics() const override {
6577 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6578 }
6579};
6580
6581struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6582 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6583 : AAValueSimplifyImpl(IRP, A) {}
6584
6585 /// See AbstractAttribute::initialize(...).
6586 void initialize(Attributor &A) override {
6587 AAValueSimplifyImpl::initialize(A);
6588 Value &V = getAnchorValue();
6589
6590 // TODO: add other stuffs
6591 if (isa<Constant>(V))
6592 indicatePessimisticFixpoint();
6593 }
6594
6595 /// See AbstractAttribute::updateImpl(...).
6596 ChangeStatus updateImpl(Attributor &A) override {
6597 auto Before = SimplifiedAssociatedValue;
6598 if (!askSimplifiedValueForOtherAAs(A))
6599 return indicatePessimisticFixpoint();
6600
6601 // If a candidate was found in this update, return CHANGED.
6602 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6603 : ChangeStatus ::CHANGED;
6604 }
6605
6606 /// See AbstractAttribute::trackStatistics()
6607 void trackStatistics() const override {
6608 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6609 }
6610};
6611
6612struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6613 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6614 : AAValueSimplifyImpl(IRP, A) {}
6615
6616 /// See AbstractAttribute::initialize(...).
6617 void initialize(Attributor &A) override {
6618 SimplifiedAssociatedValue = nullptr;
6619 indicateOptimisticFixpoint();
6620 }
6621 /// See AbstractAttribute::initialize(...).
6622 ChangeStatus updateImpl(Attributor &A) override {
6624 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6625 }
6626 /// See AbstractAttribute::trackStatistics()
6627 void trackStatistics() const override {
6628 STATS_DECLTRACK_FN_ATTR(value_simplify)
6629 }
6630};
6631
6632struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6633 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6634 : AAValueSimplifyFunction(IRP, A) {}
6635 /// See AbstractAttribute::trackStatistics()
6636 void trackStatistics() const override {
6637 STATS_DECLTRACK_CS_ATTR(value_simplify)
6638 }
6639};
6640
6641struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6642 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6643 : AAValueSimplifyImpl(IRP, A) {}
6644
6645 void initialize(Attributor &A) override {
6646 AAValueSimplifyImpl::initialize(A);
6647 Function *Fn = getAssociatedFunction();
6648 assert(Fn && "Did expect an associted function");
6649 for (Argument &Arg : Fn->args()) {
6650 if (Arg.hasReturnedAttr()) {
6651 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6652 Arg.getArgNo());
6654 checkAndUpdate(A, *this, IRP))
6655 indicateOptimisticFixpoint();
6656 else
6657 indicatePessimisticFixpoint();
6658 return;
6659 }
6660 }
6661 }
6662
6663 /// See AbstractAttribute::updateImpl(...).
6664 ChangeStatus updateImpl(Attributor &A) override {
6665 return indicatePessimisticFixpoint();
6666 }
6667
6668 void trackStatistics() const override {
6669 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6670 }
6671};
6672
6673struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6674 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6675 : AAValueSimplifyFloating(IRP, A) {}
6676
6677 /// See AbstractAttribute::manifest(...).
6678 ChangeStatus manifest(Attributor &A) override {
6679 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6680 // TODO: We should avoid simplification duplication to begin with.
6681 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6682 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6683 if (FloatAA && FloatAA->getState().isValidState())
6684 return Changed;
6685
6686 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6687 Use &U = cast<CallBase>(&getAnchorValue())
6688 ->getArgOperandUse(getCallSiteArgNo());
6689 if (A.changeUseAfterManifest(U, *NewV))
6690 Changed = ChangeStatus::CHANGED;
6691 }
6692
6693 return Changed | AAValueSimplify::manifest(A);
6694 }
6695
6696 void trackStatistics() const override {
6697 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6698 }
6699};
6700} // namespace
6701
6702/// ----------------------- Heap-To-Stack Conversion ---------------------------
6703namespace {
6704struct AAHeapToStackFunction final : public AAHeapToStack {
6705
6706 static bool isGlobalizedLocal(const CallBase &CB) {
6707 Attribute A = CB.getFnAttr("alloc-family");
6708 return A.isValid() && A.getValueAsString() == "__kmpc_alloc_shared";
6709 }
6710
6711 struct AllocationInfo {
6712 /// The call that allocates the memory.
6713 CallBase *const CB;
6714
6715 /// Whether this allocation is an OpenMP globalized local variable.
6716 bool IsGlobalizedLocal = false;
6717
6718 /// The status wrt. a rewrite.
6719 enum {
6720 STACK_DUE_TO_USE,
6721 STACK_DUE_TO_FREE,
6722 INVALID,
6723 } Status = STACK_DUE_TO_USE;
6724
6725 /// Flag to indicate if we encountered a use that might free this allocation
6726 /// but which is not in the deallocation infos.
6727 bool HasPotentiallyFreeingUnknownUses = false;
6728
6729 /// Flag to indicate that we should place the new alloca in the function
6730 /// entry block rather than where the call site (CB) is.
6731 bool MoveAllocaIntoEntry = true;
6732
6733 /// The set of free calls that use this allocation.
6734 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6735 };
6736
6737 struct DeallocationInfo {
6738 /// The call that deallocates the memory.
6739 CallBase *const CB;
6740 /// The value freed by the call.
6741 Value *FreedOp;
6742
6743 /// Flag to indicate if we don't know all objects this deallocation might
6744 /// free.
6745 bool MightFreeUnknownObjects = false;
6746
6747 /// The set of allocation calls that are potentially freed.
6748 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6749 };
6750
6751 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6752 : AAHeapToStack(IRP, A) {}
6753
6754 ~AAHeapToStackFunction() override {
6755 // Ensure we call the destructor so we release any memory allocated in the
6756 // sets.
6757 for (auto &It : AllocationInfos)
6758 It.second->~AllocationInfo();
6759 for (auto &It : DeallocationInfos)
6760 It.second->~DeallocationInfo();
6761 }
6762
6763 void initialize(Attributor &A) override {
6764 AAHeapToStack::initialize(A);
6765
6766 const Function *F = getAnchorScope();
6767 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6768
6769 auto AllocationIdentifierCB = [&](Instruction &I) {
6770 CallBase *CB = dyn_cast<CallBase>(&I);
6771 if (!CB)
6772 return true;
6773 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6774 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6775 return true;
6776 }
6777 // To do heap to stack, we need to know that the allocation itself is
6778 // removable once uses are rewritten, and that we can initialize the
6779 // alloca to the same pattern as the original allocation result.
6780 if (isRemovableAlloc(CB, TLI)) {
6781 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6782 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6783 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6784 AllocationInfos[CB] = AI;
6785 AI->IsGlobalizedLocal = isGlobalizedLocal(*CB);
6786 }
6787 }
6788 return true;
6789 };
6790
6791 bool UsedAssumedInformation = false;
6792 bool Success = A.checkForAllCallLikeInstructions(
6793 AllocationIdentifierCB, *this, UsedAssumedInformation,
6794 /* CheckBBLivenessOnly */ false,
6795 /* CheckPotentiallyDead */ true);
6796 (void)Success;
6797 assert(Success && "Did not expect the call base visit callback to fail!");
6798
6800 [](const IRPosition &, const AbstractAttribute *,
6801 bool &) -> std::optional<Value *> { return nullptr; };
6802 for (const auto &It : AllocationInfos)
6803 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6804 SCB);
6805 for (const auto &It : DeallocationInfos)
6806 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6807 SCB);
6808 }
6809
6810 const std::string getAsStr(Attributor *A) const override {
6811 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6812 for (const auto &It : AllocationInfos) {
6813 if (It.second->Status == AllocationInfo::INVALID)
6814 ++NumInvalidMallocs;
6815 else
6816 ++NumH2SMallocs;
6817 }
6818 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6819 std::to_string(NumInvalidMallocs);
6820 }
6821
6822 /// See AbstractAttribute::trackStatistics().
6823 void trackStatistics() const override {
6824 STATS_DECL(
6825 MallocCalls, Function,
6826 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6827 for (const auto &It : AllocationInfos)
6828 if (It.second->Status != AllocationInfo::INVALID)
6829 ++BUILD_STAT_NAME(MallocCalls, Function);
6830 }
6831
6832 bool isAssumedHeapToStack(const CallBase &CB) const override {
6833 if (isValidState())
6834 if (AllocationInfo *AI =
6835 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6836 return AI->Status != AllocationInfo::INVALID;
6837 return false;
6838 }
6839
6840 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6841 if (!isValidState())
6842 return false;
6843
6844 for (const auto &It : AllocationInfos) {
6845 AllocationInfo &AI = *It.second;
6846 if (AI.Status == AllocationInfo::INVALID)
6847 continue;
6848
6849 if (AI.PotentialFreeCalls.count(&CB))
6850 return true;
6851 }
6852
6853 return false;
6854 }
6855
6856 ChangeStatus manifest(Attributor &A) override {
6857 assert(getState().isValidState() &&
6858 "Attempted to manifest an invalid state!");
6859
6860 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6861 Function *F = getAnchorScope();
6862 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6863
6864 for (auto &It : AllocationInfos) {
6865 AllocationInfo &AI = *It.second;
6866 if (AI.Status == AllocationInfo::INVALID)
6867 continue;
6868
6869 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6870 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6871 A.deleteAfterManifest(*FreeCall);
6872 HasChanged = ChangeStatus::CHANGED;
6873 }
6874
6875 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6876 << "\n");
6877
6878 auto Remark = [&](OptimizationRemark OR) {
6879 if (AI.IsGlobalizedLocal)
6880 return OR << "Moving globalized variable to the stack.";
6881 return OR << "Moving memory allocation from the heap to the stack.";
6882 };
6883 if (AI.IsGlobalizedLocal)
6884 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6885 else
6886 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6887
6888 const DataLayout &DL = A.getInfoCache().getDL();
6889 Value *Size;
6890 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6891 if (SizeAPI) {
6892 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6893 } else {
6894 LLVMContext &Ctx = AI.CB->getContext();
6895 ObjectSizeOpts Opts;
6896 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6897 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6898 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6899 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6900 Size = SizeOffsetPair.Size;
6901 }
6902
6903 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6904 ? F->getEntryBlock().begin()
6905 : AI.CB->getIterator();
6906
6907 Align Alignment(1);
6908 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6909 Alignment = std::max(Alignment, *RetAlign);
6910 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6911 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6912 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6913 "Expected an alignment during manifest!");
6914 Alignment =
6915 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6916 }
6917
6918 // TODO: Hoist the alloca towards the function entry.
6919 unsigned AS = DL.getAllocaAddrSpace();
6920 Instruction *Alloca =
6921 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6922 AI.CB->getName() + ".h2s", IP);
6923
6924 if (Alloca->getType() != AI.CB->getType())
6925 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6926 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6927
6928 auto *I8Ty = Type::getInt8Ty(F->getContext());
6929 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6930 assert(InitVal &&
6931 "Must be able to materialize initial memory state of allocation");
6932
6933 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6934
6935 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6936 auto *NBB = II->getNormalDest();
6937 UncondBrInst::Create(NBB, AI.CB->getParent());
6938 A.deleteAfterManifest(*AI.CB);
6939 } else {
6940 A.deleteAfterManifest(*AI.CB);
6941 }
6942
6943 // Initialize the alloca with the same value as used by the allocation
6944 // function. We can skip undef as the initial value of an alloc is
6945 // undef, and the memset would simply end up being DSEd.
6946 if (!isa<UndefValue>(InitVal)) {
6947 IRBuilder<> Builder(Alloca->getNextNode());
6948 // TODO: Use alignment above if align!=1
6949 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6950 }
6951 HasChanged = ChangeStatus::CHANGED;
6952 }
6953
6954 return HasChanged;
6955 }
6956
6957 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6958 Value &V) {
6959 bool UsedAssumedInformation = false;
6960 std::optional<Constant *> SimpleV =
6961 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6962 if (!SimpleV)
6963 return APInt(64, 0);
6964 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6965 return CI->getValue();
6966 return std::nullopt;
6967 }
6968
6969 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6970 AllocationInfo &AI) {
6971 auto Mapper = [&](const Value *V) -> const Value * {
6972 bool UsedAssumedInformation = false;
6973 if (std::optional<Constant *> SimpleV =
6974 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6975 if (*SimpleV)
6976 return *SimpleV;
6977 return V;
6978 };
6979
6980 const Function *F = getAnchorScope();
6981 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6982 return getAllocSize(AI.CB, TLI, Mapper);
6983 }
6984
6985 /// Collection of all malloc-like calls in a function with associated
6986 /// information.
6987 MapVector<CallBase *, AllocationInfo *> AllocationInfos;
6988
6989 /// Collection of all free-like calls in a function with associated
6990 /// information.
6991 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos;
6992
6993 ChangeStatus updateImpl(Attributor &A) override;
6994};
6995
6996ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6998 const Function *F = getAnchorScope();
6999 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
7000
7001 const auto *LivenessAA =
7002 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
7003
7004 MustBeExecutedContextExplorer *Explorer =
7005 A.getInfoCache().getMustBeExecutedContextExplorer();
7006
7007 bool StackIsAccessibleByOtherThreads =
7008 A.getInfoCache().stackIsAccessibleByOtherThreads();
7009
7010 LoopInfo *LI =
7011 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
7012 std::optional<bool> MayContainIrreducibleControl;
7013 auto IsInLoop = [&](BasicBlock &BB) {
7014 if (&F->getEntryBlock() == &BB)
7015 return false;
7016 if (!MayContainIrreducibleControl.has_value())
7017 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
7018 if (*MayContainIrreducibleControl)
7019 return true;
7020 if (!LI)
7021 return true;
7022 return LI->getLoopFor(&BB) != nullptr;
7023 };
7024
7025 // Flag to ensure we update our deallocation information at most once per
7026 // updateImpl call and only if we use the free check reasoning.
7027 bool HasUpdatedFrees = false;
7028
7029 auto UpdateFrees = [&]() {
7030 HasUpdatedFrees = true;
7031
7032 for (auto &It : DeallocationInfos) {
7033 DeallocationInfo &DI = *It.second;
7034 // For now we cannot use deallocations that have unknown inputs, skip
7035 // them.
7036 if (DI.MightFreeUnknownObjects)
7037 continue;
7038
7039 // No need to analyze dead calls, ignore them instead.
7040 bool UsedAssumedInformation = false;
7041 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
7042 /* CheckBBLivenessOnly */ true))
7043 continue;
7044
7045 // Use the non-optimistic version to get the freed object.
7046 Value *Obj = getUnderlyingObject(DI.FreedOp);
7047 if (!Obj) {
7048 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
7049 DI.MightFreeUnknownObjects = true;
7050 continue;
7051 }
7052
7053 // Free of null and undef can be ignored as no-ops (or UB in the latter
7054 // case).
7056 continue;
7057
7058 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
7059 if (!ObjCB) {
7060 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
7061 << "\n");
7062 DI.MightFreeUnknownObjects = true;
7063 continue;
7064 }
7065
7066 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
7067 if (!AI) {
7068 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
7069 << "\n");
7070 DI.MightFreeUnknownObjects = true;
7071 continue;
7072 }
7073
7074 DI.PotentialAllocationCalls.insert(ObjCB);
7075 }
7076 };
7077
7078 auto FreeCheck = [&](AllocationInfo &AI) {
7079 // If the stack is not accessible by other threads, the "must-free" logic
7080 // doesn't apply as the pointer could be shared and needs to be places in
7081 // "shareable" memory.
7082 if (!StackIsAccessibleByOtherThreads) {
7083 bool IsKnownNoSycn;
7085 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
7086 LLVM_DEBUG(
7087 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
7088 "other threads and function is not nosync:\n");
7089 return false;
7090 }
7091 }
7092 if (!HasUpdatedFrees)
7093 UpdateFrees();
7094
7095 // TODO: Allow multi exit functions that have different free calls.
7096 if (AI.PotentialFreeCalls.size() != 1) {
7097 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7098 << AI.PotentialFreeCalls.size() << "\n");
7099 return false;
7100 }
7101 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7102 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7103 if (!DI) {
7104 LLVM_DEBUG(
7105 dbgs() << "[H2S] unique free call was not known as deallocation call "
7106 << *UniqueFree << "\n");
7107 return false;
7108 }
7109 if (DI->MightFreeUnknownObjects) {
7110 LLVM_DEBUG(
7111 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7112 return false;
7113 }
7114 if (DI->PotentialAllocationCalls.empty())
7115 return true;
7116 if (DI->PotentialAllocationCalls.size() > 1) {
7117 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7118 << DI->PotentialAllocationCalls.size()
7119 << " different allocations\n");
7120 return false;
7121 }
7122 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7123 LLVM_DEBUG(
7124 dbgs()
7125 << "[H2S] unique free call not known to free this allocation but "
7126 << **DI->PotentialAllocationCalls.begin() << "\n");
7127 return false;
7128 }
7129
7130 // __kmpc_alloc_shared and __kmpc_free_shared are by construction matched.
7131 if (!AI.IsGlobalizedLocal) {
7132 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7133 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7134 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7135 "with the allocation "
7136 << *UniqueFree << "\n");
7137 return false;
7138 }
7139 }
7140 return true;
7141 };
7142
7143 auto UsesCheck = [&](AllocationInfo &AI) {
7144 bool ValidUsesOnly = true;
7145
7146 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7147 Instruction *UserI = cast<Instruction>(U.getUser());
7148 if (isa<LoadInst>(UserI))
7149 return true;
7150 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7151 if (SI->getValueOperand() == U.get()) {
7153 << "[H2S] escaping store to memory: " << *UserI << "\n");
7154 ValidUsesOnly = false;
7155 } else {
7156 // A store into the malloc'ed memory is fine.
7157 }
7158 return true;
7159 }
7160 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7161 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7162 return true;
7163 if (DeallocationInfos.count(CB)) {
7164 AI.PotentialFreeCalls.insert(CB);
7165 return true;
7166 }
7167
7168 unsigned ArgNo = CB->getArgOperandNo(&U);
7169 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7170
7171 bool IsKnownNoCapture;
7172 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7173 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7174
7175 // If a call site argument use is nofree, we are fine.
7176 bool IsKnownNoFree;
7177 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7178 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7179
7180 if (!IsAssumedNoCapture ||
7181 (!AI.IsGlobalizedLocal && !IsAssumedNoFree)) {
7182 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7183
7184 // Emit a missed remark if this is missed OpenMP globalization.
7185 auto Remark = [&](OptimizationRemarkMissed ORM) {
7186 return ORM
7187 << "Could not move globalized variable to the stack. "
7188 "Variable is potentially captured in call. Mark "
7189 "parameter as `__attribute__((noescape))` to override.";
7190 };
7191
7192 if (ValidUsesOnly && AI.IsGlobalizedLocal)
7193 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7194
7195 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7196 ValidUsesOnly = false;
7197 }
7198 return true;
7199 }
7200
7201 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7202 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7203 Follow = true;
7204 return true;
7205 }
7206 // Unknown user for which we can not track uses further (in a way that
7207 // makes sense).
7208 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7209 ValidUsesOnly = false;
7210 return true;
7211 };
7212 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7213 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7214 [&](const Use &OldU, const Use &NewU) {
7215 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7216 return !SI || StackIsAccessibleByOtherThreads ||
7217 AA::isAssumedThreadLocalObject(
7218 A, *SI->getPointerOperand(), *this);
7219 }))
7220 return false;
7221 return ValidUsesOnly;
7222 };
7223
7224 // The actual update starts here. We look at all allocations and depending on
7225 // their status perform the appropriate check(s).
7226 for (auto &It : AllocationInfos) {
7227 AllocationInfo &AI = *It.second;
7228 if (AI.Status == AllocationInfo::INVALID)
7229 continue;
7230
7231 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7232 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7233 if (!APAlign) {
7234 // Can't generate an alloca which respects the required alignment
7235 // on the allocation.
7236 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7237 << "\n");
7238 AI.Status = AllocationInfo::INVALID;
7240 continue;
7241 }
7242 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7243 !APAlign->isPowerOf2()) {
7244 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7245 << "\n");
7246 AI.Status = AllocationInfo::INVALID;
7248 continue;
7249 }
7250 }
7251
7252 std::optional<APInt> Size = getSize(A, *this, AI);
7253 if (!AI.IsGlobalizedLocal && MaxHeapToStackSize != -1) {
7254 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7255 LLVM_DEBUG({
7256 if (!Size)
7257 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7258 else
7259 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7260 << MaxHeapToStackSize << "\n";
7261 });
7262
7263 AI.Status = AllocationInfo::INVALID;
7265 continue;
7266 }
7267 }
7268
7269 switch (AI.Status) {
7270 case AllocationInfo::STACK_DUE_TO_USE:
7271 if (UsesCheck(AI))
7272 break;
7273 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7274 [[fallthrough]];
7275 case AllocationInfo::STACK_DUE_TO_FREE:
7276 if (FreeCheck(AI))
7277 break;
7278 AI.Status = AllocationInfo::INVALID;
7280 break;
7281 case AllocationInfo::INVALID:
7282 llvm_unreachable("Invalid allocations should never reach this point!");
7283 };
7284
7285 // Check if we still think we can move it into the entry block. If the
7286 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7287 // ignore the potential complications associated with loops.
7288 bool IsGlobalizedLocal = AI.IsGlobalizedLocal;
7289 if (AI.MoveAllocaIntoEntry &&
7290 (!Size.has_value() ||
7291 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7292 AI.MoveAllocaIntoEntry = false;
7293 }
7294
7295 return Changed;
7296}
7297} // namespace
7298
7299/// ----------------------- Privatizable Pointers ------------------------------
7300namespace {
7301struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7302 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7303 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7304
7305 ChangeStatus indicatePessimisticFixpoint() override {
7306 AAPrivatizablePtr::indicatePessimisticFixpoint();
7307 PrivatizableType = nullptr;
7308 return ChangeStatus::CHANGED;
7309 }
7310
7311 /// Identify the type we can chose for a private copy of the underlying
7312 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7313 /// none.
7314 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7315
7316 /// Return a privatizable type that encloses both T0 and T1.
7317 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7318 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7319 std::optional<Type *> T1) {
7320 if (!T0)
7321 return T1;
7322 if (!T1)
7323 return T0;
7324 if (T0 == T1)
7325 return T0;
7326 return nullptr;
7327 }
7328
7329 std::optional<Type *> getPrivatizableType() const override {
7330 return PrivatizableType;
7331 }
7332
7333 const std::string getAsStr(Attributor *A) const override {
7334 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7335 }
7336
7337protected:
7338 std::optional<Type *> PrivatizableType;
7339};
7340
7341// TODO: Do this for call site arguments (probably also other values) as well.
7342
7343struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7344 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7345 : AAPrivatizablePtrImpl(IRP, A) {}
7346
7347 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7348 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7349 // If this is a byval argument and we know all the call sites (so we can
7350 // rewrite them), there is no need to check them explicitly.
7351 bool UsedAssumedInformation = false;
7353 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7354 /* IgnoreSubsumingPositions */ true);
7355 if (!Attrs.empty() &&
7356 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7357 true, UsedAssumedInformation))
7358 return Attrs[0].getValueAsType();
7359
7360 std::optional<Type *> Ty;
7361 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7362
7363 // Make sure the associated call site argument has the same type at all call
7364 // sites and it is an allocation we know is safe to privatize, for now that
7365 // means we only allow alloca instructions.
7366 // TODO: We can additionally analyze the accesses in the callee to create
7367 // the type from that information instead. That is a little more
7368 // involved and will be done in a follow up patch.
7369 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7370 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7371 // Check if a coresponding argument was found or if it is one not
7372 // associated (which can happen for callback calls).
7373 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7374 return false;
7375
7376 // Check that all call sites agree on a type.
7377 auto *PrivCSArgAA =
7378 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7379 if (!PrivCSArgAA)
7380 return false;
7381 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7382
7383 LLVM_DEBUG({
7384 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7385 if (CSTy && *CSTy)
7386 (*CSTy)->print(dbgs());
7387 else if (CSTy)
7388 dbgs() << "<nullptr>";
7389 else
7390 dbgs() << "<none>";
7391 });
7392
7393 Ty = combineTypes(Ty, CSTy);
7394
7395 LLVM_DEBUG({
7396 dbgs() << " : New Type: ";
7397 if (Ty && *Ty)
7398 (*Ty)->print(dbgs());
7399 else if (Ty)
7400 dbgs() << "<nullptr>";
7401 else
7402 dbgs() << "<none>";
7403 dbgs() << "\n";
7404 });
7405
7406 return !Ty || *Ty;
7407 };
7408
7409 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7410 UsedAssumedInformation))
7411 return nullptr;
7412 return Ty;
7413 }
7414
7415 /// See AbstractAttribute::updateImpl(...).
7416 ChangeStatus updateImpl(Attributor &A) override {
7417 PrivatizableType = identifyPrivatizableType(A);
7418 if (!PrivatizableType)
7419 return ChangeStatus::UNCHANGED;
7420 if (!*PrivatizableType)
7421 return indicatePessimisticFixpoint();
7422
7423 // The dependence is optional so we don't give up once we give up on the
7424 // alignment.
7425 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7426 DepClassTy::OPTIONAL);
7427
7428 // Avoid arguments with padding for now.
7429 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7430 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7431 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7432 return indicatePessimisticFixpoint();
7433 }
7434
7435 // Collect the types that will replace the privatizable type in the function
7436 // signature.
7437 SmallVector<Type *, 16> ReplacementTypes;
7438 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7439
7440 // Verify callee and caller agree on how the promoted argument would be
7441 // passed.
7442 Function &Fn = *getIRPosition().getAnchorScope();
7443 const auto *TTI =
7444 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7445 if (!TTI) {
7446 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7447 << Fn.getName() << "\n");
7448 return indicatePessimisticFixpoint();
7449 }
7450
7451 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7452 CallBase *CB = ACS.getInstruction();
7453 return TTI->areTypesABICompatible(
7454 CB->getCaller(),
7456 ReplacementTypes);
7457 };
7458 bool UsedAssumedInformation = false;
7459 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7460 UsedAssumedInformation)) {
7461 LLVM_DEBUG(
7462 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7463 << Fn.getName() << "\n");
7464 return indicatePessimisticFixpoint();
7465 }
7466
7467 // Register a rewrite of the argument.
7468 Argument *Arg = getAssociatedArgument();
7469 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7470 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7471 return indicatePessimisticFixpoint();
7472 }
7473
7474 unsigned ArgNo = Arg->getArgNo();
7475
7476 // Helper to check if for the given call site the associated argument is
7477 // passed to a callback where the privatization would be different.
7478 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7479 SmallVector<const Use *, 4> CallbackUses;
7480 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7481 for (const Use *U : CallbackUses) {
7482 AbstractCallSite CBACS(U);
7483 assert(CBACS && CBACS.isCallbackCall());
7484 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7485 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7486
7487 LLVM_DEBUG({
7488 dbgs()
7489 << "[AAPrivatizablePtr] Argument " << *Arg
7490 << "check if can be privatized in the context of its parent ("
7491 << Arg->getParent()->getName()
7492 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7493 "callback ("
7494 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7495 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7496 << CBACS.getCallArgOperand(CBArg) << " vs "
7497 << CB.getArgOperand(ArgNo) << "\n"
7498 << "[AAPrivatizablePtr] " << CBArg << " : "
7499 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7500 });
7501
7502 if (CBArgNo != int(ArgNo))
7503 continue;
7504 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7505 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7506 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7507 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7508 if (!CBArgPrivTy)
7509 continue;
7510 if (*CBArgPrivTy == PrivatizableType)
7511 continue;
7512 }
7513
7514 LLVM_DEBUG({
7515 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7516 << " cannot be privatized in the context of its parent ("
7517 << Arg->getParent()->getName()
7518 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7519 "callback ("
7520 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7521 << ").\n[AAPrivatizablePtr] for which the argument "
7522 "privatization is not compatible.\n";
7523 });
7524 return false;
7525 }
7526 }
7527 return true;
7528 };
7529
7530 // Helper to check if for the given call site the associated argument is
7531 // passed to a direct call where the privatization would be different.
7532 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7533 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7534 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7535 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7536 "Expected a direct call operand for callback call operand");
7537
7538 Function *DCCallee =
7540 LLVM_DEBUG({
7541 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7542 << " check if be privatized in the context of its parent ("
7543 << Arg->getParent()->getName()
7544 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7545 "direct call of ("
7546 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7547 });
7548
7549 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7550 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7551 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7552 DepClassTy::REQUIRED);
7553 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7554 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7555 if (!DCArgPrivTy)
7556 return true;
7557 if (*DCArgPrivTy == PrivatizableType)
7558 return true;
7559 }
7560 }
7561
7562 LLVM_DEBUG({
7563 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7564 << " cannot be privatized in the context of its parent ("
7565 << Arg->getParent()->getName()
7566 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7567 "direct call of ("
7569 << ").\n[AAPrivatizablePtr] for which the argument "
7570 "privatization is not compatible.\n";
7571 });
7572 return false;
7573 };
7574
7575 // Helper to check if the associated argument is used at the given abstract
7576 // call site in a way that is incompatible with the privatization assumed
7577 // here.
7578 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7579 if (ACS.isDirectCall())
7580 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7581 if (ACS.isCallbackCall())
7582 return IsCompatiblePrivArgOfDirectCS(ACS);
7583 return false;
7584 };
7585
7586 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7587 UsedAssumedInformation))
7588 return indicatePessimisticFixpoint();
7589
7590 return ChangeStatus::UNCHANGED;
7591 }
7592
7593 /// Given a type to private \p PrivType, collect the constituates (which are
7594 /// used) in \p ReplacementTypes.
7595 static void
7596 identifyReplacementTypes(Type *PrivType,
7597 SmallVectorImpl<Type *> &ReplacementTypes) {
7598 // TODO: For now we expand the privatization type to the fullest which can
7599 // lead to dead arguments that need to be removed later.
7600 assert(PrivType && "Expected privatizable type!");
7601
7602 // Traverse the type, extract constituate types on the outermost level.
7603 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7604 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7605 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7606 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7607 ReplacementTypes.append(PrivArrayType->getNumElements(),
7608 PrivArrayType->getElementType());
7609 } else {
7610 ReplacementTypes.push_back(PrivType);
7611 }
7612 }
7613
7614 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7615 /// The values needed are taken from the arguments of \p F starting at
7616 /// position \p ArgNo.
7617 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7618 unsigned ArgNo, BasicBlock::iterator IP) {
7619 assert(PrivType && "Expected privatizable type!");
7620
7621 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7622 const DataLayout &DL = F.getDataLayout();
7623
7624 // Traverse the type, build GEPs and stores.
7625 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7626 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7627 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7628 Value *Ptr =
7629 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7630 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7631 }
7632 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7633 Type *PointeeTy = PrivArrayType->getElementType();
7634 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7635 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7636 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7637 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7638 }
7639 } else {
7640 new StoreInst(F.getArg(ArgNo), &Base, IP);
7641 }
7642 }
7643
7644 /// Extract values from \p Base according to the type \p PrivType at the
7645 /// call position \p ACS. The values are appended to \p ReplacementValues.
7646 void createReplacementValues(Align Alignment, Type *PrivType,
7647 AbstractCallSite ACS, Value *Base,
7648 SmallVectorImpl<Value *> &ReplacementValues) {
7649 assert(Base && "Expected base value!");
7650 assert(PrivType && "Expected privatizable type!");
7651 Instruction *IP = ACS.getInstruction();
7652
7653 IRBuilder<NoFolder> IRB(IP);
7654 const DataLayout &DL = IP->getDataLayout();
7655
7656 // Traverse the type, build GEPs and loads.
7657 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7658 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7659 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7660 Type *PointeeTy = PrivStructType->getElementType(u);
7661 Value *Ptr =
7662 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7663 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7664 L->setAlignment(Alignment);
7665 ReplacementValues.push_back(L);
7666 }
7667 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7668 Type *PointeeTy = PrivArrayType->getElementType();
7669 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7670 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7671 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7672 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7673 L->setAlignment(Alignment);
7674 ReplacementValues.push_back(L);
7675 }
7676 } else {
7677 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7678 L->setAlignment(Alignment);
7679 ReplacementValues.push_back(L);
7680 }
7681 }
7682
7683 /// See AbstractAttribute::manifest(...)
7684 ChangeStatus manifest(Attributor &A) override {
7685 if (!PrivatizableType)
7686 return ChangeStatus::UNCHANGED;
7687 assert(*PrivatizableType && "Expected privatizable type!");
7688
7689 // Collect all tail calls in the function as we cannot allow new allocas to
7690 // escape into tail recursion.
7691 // TODO: Be smarter about new allocas escaping into tail calls.
7693 bool UsedAssumedInformation = false;
7694 if (!A.checkForAllInstructions(
7695 [&](Instruction &I) {
7696 CallInst &CI = cast<CallInst>(I);
7697 if (CI.isTailCall())
7698 TailCalls.push_back(&CI);
7699 return true;
7700 },
7701 *this, {Instruction::Call}, UsedAssumedInformation))
7702 return ChangeStatus::UNCHANGED;
7703
7704 Argument *Arg = getAssociatedArgument();
7705 // Query AAAlign attribute for alignment of associated argument to
7706 // determine the best alignment of loads.
7707 const auto *AlignAA =
7708 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7709
7710 // Callback to repair the associated function. A new alloca is placed at the
7711 // beginning and initialized with the values passed through arguments. The
7712 // new alloca replaces the use of the old pointer argument.
7714 [=](const Attributor::ArgumentReplacementInfo &ARI,
7715 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7716 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7718 const DataLayout &DL = IP->getDataLayout();
7719 unsigned AS = DL.getAllocaAddrSpace();
7720 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7721 Arg->getName() + ".priv", IP);
7722 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7723 ArgIt->getArgNo(), IP);
7724
7725 if (AI->getType() != Arg->getType())
7726 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7727 AI, Arg->getType(), "", IP);
7728 Arg->replaceAllUsesWith(AI);
7729
7730 for (CallInst *CI : TailCalls)
7731 CI->setTailCall(false);
7732 };
7733
7734 // Callback to repair a call site of the associated function. The elements
7735 // of the privatizable type are loaded prior to the call and passed to the
7736 // new function version.
7738 [=](const Attributor::ArgumentReplacementInfo &ARI,
7739 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7740 // When no alignment is specified for the load instruction,
7741 // natural alignment is assumed.
7742 createReplacementValues(
7743 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7744 *PrivatizableType, ACS,
7745 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7746 NewArgOperands);
7747 };
7748
7749 // Collect the types that will replace the privatizable type in the function
7750 // signature.
7751 SmallVector<Type *, 16> ReplacementTypes;
7752 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7753
7754 // Register a rewrite of the argument.
7755 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7756 std::move(FnRepairCB),
7757 std::move(ACSRepairCB)))
7758 return ChangeStatus::CHANGED;
7759 return ChangeStatus::UNCHANGED;
7760 }
7761
7762 /// See AbstractAttribute::trackStatistics()
7763 void trackStatistics() const override {
7764 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7765 }
7766};
7767
7768struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7769 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7770 : AAPrivatizablePtrImpl(IRP, A) {}
7771
7772 /// See AbstractAttribute::initialize(...).
7773 void initialize(Attributor &A) override {
7774 // TODO: We can privatize more than arguments.
7775 indicatePessimisticFixpoint();
7776 }
7777
7778 ChangeStatus updateImpl(Attributor &A) override {
7779 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7780 "updateImpl will not be called");
7781 }
7782
7783 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7784 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7785 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7786 if (!Obj) {
7787 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7788 return nullptr;
7789 }
7790
7791 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7792 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7793 if (CI->isOne())
7794 return AI->getAllocatedType();
7795 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7796 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7797 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7798 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7799 return PrivArgAA->getPrivatizableType();
7800 }
7801
7802 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7803 "alloca nor privatizable argument: "
7804 << *Obj << "!\n");
7805 return nullptr;
7806 }
7807
7808 /// See AbstractAttribute::trackStatistics()
7809 void trackStatistics() const override {
7810 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7811 }
7812};
7813
7814struct AAPrivatizablePtrCallSiteArgument final
7815 : public AAPrivatizablePtrFloating {
7816 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7817 : AAPrivatizablePtrFloating(IRP, A) {}
7818
7819 /// See AbstractAttribute::initialize(...).
7820 void initialize(Attributor &A) override {
7821 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7822 indicateOptimisticFixpoint();
7823 }
7824
7825 /// See AbstractAttribute::updateImpl(...).
7826 ChangeStatus updateImpl(Attributor &A) override {
7827 PrivatizableType = identifyPrivatizableType(A);
7828 if (!PrivatizableType)
7829 return ChangeStatus::UNCHANGED;
7830 if (!*PrivatizableType)
7831 return indicatePessimisticFixpoint();
7832
7833 const IRPosition &IRP = getIRPosition();
7834 bool IsKnownNoCapture;
7835 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7836 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7837 if (!IsAssumedNoCapture) {
7838 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7839 return indicatePessimisticFixpoint();
7840 }
7841
7842 bool IsKnownNoAlias;
7844 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7845 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7846 return indicatePessimisticFixpoint();
7847 }
7848
7849 bool IsKnown;
7850 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7851 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7852 return indicatePessimisticFixpoint();
7853 }
7854
7855 return ChangeStatus::UNCHANGED;
7856 }
7857
7858 /// See AbstractAttribute::trackStatistics()
7859 void trackStatistics() const override {
7860 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7861 }
7862};
7863
7864struct AAPrivatizablePtrCallSiteReturned final
7865 : public AAPrivatizablePtrFloating {
7866 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7867 : AAPrivatizablePtrFloating(IRP, A) {}
7868
7869 /// See AbstractAttribute::initialize(...).
7870 void initialize(Attributor &A) override {
7871 // TODO: We can privatize more than arguments.
7872 indicatePessimisticFixpoint();
7873 }
7874
7875 /// See AbstractAttribute::trackStatistics()
7876 void trackStatistics() const override {
7877 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7878 }
7879};
7880
7881struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7882 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7883 : AAPrivatizablePtrFloating(IRP, A) {}
7884
7885 /// See AbstractAttribute::initialize(...).
7886 void initialize(Attributor &A) override {
7887 // TODO: We can privatize more than arguments.
7888 indicatePessimisticFixpoint();
7889 }
7890
7891 /// See AbstractAttribute::trackStatistics()
7892 void trackStatistics() const override {
7893 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7894 }
7895};
7896} // namespace
7897
7898/// -------------------- Memory Behavior Attributes ----------------------------
7899/// Includes read-none, read-only, and write-only.
7900/// ----------------------------------------------------------------------------
7901namespace {
7902struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7903 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7904 : AAMemoryBehavior(IRP, A) {}
7905
7906 /// See AbstractAttribute::initialize(...).
7907 void initialize(Attributor &A) override {
7908 intersectAssumedBits(BEST_STATE);
7909 getKnownStateFromValue(A, getIRPosition(), getState());
7910 AAMemoryBehavior::initialize(A);
7911 }
7912
7913 /// Return the memory behavior information encoded in the IR for \p IRP.
7914 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7915 BitIntegerState &State,
7916 bool IgnoreSubsumingPositions = false) {
7918 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7919 for (const Attribute &Attr : Attrs) {
7920 switch (Attr.getKindAsEnum()) {
7921 case Attribute::ReadNone:
7922 State.addKnownBits(NO_ACCESSES);
7923 break;
7924 case Attribute::ReadOnly:
7925 State.addKnownBits(NO_WRITES);
7926 break;
7927 case Attribute::WriteOnly:
7928 State.addKnownBits(NO_READS);
7929 break;
7930 default:
7931 llvm_unreachable("Unexpected attribute!");
7932 }
7933 }
7934
7935 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7936 if (!I->mayReadFromMemory())
7937 State.addKnownBits(NO_READS);
7938 if (!I->mayWriteToMemory())
7939 State.addKnownBits(NO_WRITES);
7940 }
7941 }
7942
7943 /// See AbstractAttribute::getDeducedAttributes(...).
7944 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7945 SmallVectorImpl<Attribute> &Attrs) const override {
7946 assert(Attrs.size() == 0);
7947 if (isAssumedReadNone())
7948 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7949 else if (isAssumedReadOnly())
7950 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7951 else if (isAssumedWriteOnly())
7952 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7953 assert(Attrs.size() <= 1);
7954 }
7955
7956 /// See AbstractAttribute::manifest(...).
7957 ChangeStatus manifest(Attributor &A) override {
7958 const IRPosition &IRP = getIRPosition();
7959
7960 if (A.hasAttr(IRP, Attribute::ReadNone,
7961 /* IgnoreSubsumingPositions */ true))
7962 return ChangeStatus::UNCHANGED;
7963
7964 // Check if we would improve the existing attributes first.
7965 SmallVector<Attribute, 4> DeducedAttrs;
7966 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7967 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7968 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7969 /* IgnoreSubsumingPositions */ true);
7970 }))
7971 return ChangeStatus::UNCHANGED;
7972
7973 // Clear existing attributes.
7974 A.removeAttrs(IRP, AttrKinds);
7975 // Clear conflicting writable attribute.
7976 if (isAssumedReadOnly())
7977 A.removeAttrs(IRP, Attribute::Writable);
7978
7979 // Use the generic manifest method.
7980 return IRAttribute::manifest(A);
7981 }
7982
7983 /// See AbstractState::getAsStr().
7984 const std::string getAsStr(Attributor *A) const override {
7985 if (isAssumedReadNone())
7986 return "readnone";
7987 if (isAssumedReadOnly())
7988 return "readonly";
7989 if (isAssumedWriteOnly())
7990 return "writeonly";
7991 return "may-read/write";
7992 }
7993
7994 /// The set of IR attributes AAMemoryBehavior deals with.
7995 static const Attribute::AttrKind AttrKinds[3];
7996};
7997
7998const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7999 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
8000
8001/// Memory behavior attribute for a floating value.
8002struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
8003 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
8004 : AAMemoryBehaviorImpl(IRP, A) {}
8005
8006 /// See AbstractAttribute::updateImpl(...).
8007 ChangeStatus updateImpl(Attributor &A) override;
8008
8009 /// See AbstractAttribute::trackStatistics()
8010 void trackStatistics() const override {
8011 if (isAssumedReadNone())
8013 else if (isAssumedReadOnly())
8015 else if (isAssumedWriteOnly())
8017 }
8018
8019private:
8020 /// Return true if users of \p UserI might access the underlying
8021 /// variable/location described by \p U and should therefore be analyzed.
8022 bool followUsersOfUseIn(Attributor &A, const Use &U,
8023 const Instruction *UserI);
8024
8025 /// Update the state according to the effect of use \p U in \p UserI.
8026 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
8027};
8028
8029/// Memory behavior attribute for function argument.
8030struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
8031 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
8032 : AAMemoryBehaviorFloating(IRP, A) {}
8033
8034 /// See AbstractAttribute::initialize(...).
8035 void initialize(Attributor &A) override {
8036 intersectAssumedBits(BEST_STATE);
8037 const IRPosition &IRP = getIRPosition();
8038 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
8039 // can query it when we use has/getAttr. That would allow us to reuse the
8040 // initialize of the base class here.
8041 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
8042 /* IgnoreSubsumingPositions */ true);
8043 getKnownStateFromValue(A, IRP, getState(),
8044 /* IgnoreSubsumingPositions */ HasByVal);
8045 }
8046
8047 ChangeStatus manifest(Attributor &A) override {
8048 // TODO: Pointer arguments are not supported on vectors of pointers yet.
8049 if (!getAssociatedValue().getType()->isPointerTy())
8050 return ChangeStatus::UNCHANGED;
8051
8052 // TODO: From readattrs.ll: "inalloca parameters are always
8053 // considered written"
8054 if (A.hasAttr(getIRPosition(),
8055 {Attribute::InAlloca, Attribute::Preallocated})) {
8056 removeKnownBits(NO_WRITES);
8057 removeAssumedBits(NO_WRITES);
8058 }
8059 A.removeAttrs(getIRPosition(), AttrKinds);
8060 return AAMemoryBehaviorFloating::manifest(A);
8061 }
8062
8063 /// See AbstractAttribute::trackStatistics()
8064 void trackStatistics() const override {
8065 if (isAssumedReadNone())
8066 STATS_DECLTRACK_ARG_ATTR(readnone)
8067 else if (isAssumedReadOnly())
8068 STATS_DECLTRACK_ARG_ATTR(readonly)
8069 else if (isAssumedWriteOnly())
8070 STATS_DECLTRACK_ARG_ATTR(writeonly)
8071 }
8072};
8073
8074struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
8075 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
8076 : AAMemoryBehaviorArgument(IRP, A) {}
8077
8078 /// See AbstractAttribute::initialize(...).
8079 void initialize(Attributor &A) override {
8080 // If we don't have an associated attribute this is either a variadic call
8081 // or an indirect call, either way, nothing to do here.
8082 Argument *Arg = getAssociatedArgument();
8083 if (!Arg) {
8084 indicatePessimisticFixpoint();
8085 return;
8086 }
8087 if (Arg->hasByValAttr()) {
8088 addKnownBits(NO_WRITES);
8089 removeKnownBits(NO_READS);
8090 removeAssumedBits(NO_READS);
8091 }
8092 AAMemoryBehaviorArgument::initialize(A);
8093 if (getAssociatedFunction()->isDeclaration())
8094 indicatePessimisticFixpoint();
8095 }
8096
8097 /// See AbstractAttribute::updateImpl(...).
8098 ChangeStatus updateImpl(Attributor &A) override {
8099 // TODO: Once we have call site specific value information we can provide
8100 // call site specific liveness liveness information and then it makes
8101 // sense to specialize attributes for call sites arguments instead of
8102 // redirecting requests to the callee argument.
8103 Argument *Arg = getAssociatedArgument();
8104 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8105 auto *ArgAA =
8106 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8107 if (!ArgAA)
8108 return indicatePessimisticFixpoint();
8109 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8110 }
8111
8112 /// See AbstractAttribute::trackStatistics()
8113 void trackStatistics() const override {
8114 if (isAssumedReadNone())
8116 else if (isAssumedReadOnly())
8118 else if (isAssumedWriteOnly())
8120 }
8121};
8122
8123/// Memory behavior attribute for a call site return position.
8124struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8125 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8126 : AAMemoryBehaviorFloating(IRP, A) {}
8127
8128 /// See AbstractAttribute::initialize(...).
8129 void initialize(Attributor &A) override {
8130 AAMemoryBehaviorImpl::initialize(A);
8131 }
8132 /// See AbstractAttribute::manifest(...).
8133 ChangeStatus manifest(Attributor &A) override {
8134 // We do not annotate returned values.
8135 return ChangeStatus::UNCHANGED;
8136 }
8137
8138 /// See AbstractAttribute::trackStatistics()
8139 void trackStatistics() const override {}
8140};
8141
8142/// An AA to represent the memory behavior function attributes.
8143struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8144 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8145 : AAMemoryBehaviorImpl(IRP, A) {}
8146
8147 /// See AbstractAttribute::updateImpl(Attributor &A).
8148 ChangeStatus updateImpl(Attributor &A) override;
8149
8150 /// See AbstractAttribute::manifest(...).
8151 ChangeStatus manifest(Attributor &A) override {
8152 // TODO: It would be better to merge this with AAMemoryLocation, so that
8153 // we could determine read/write per location. This would also have the
8154 // benefit of only one place trying to manifest the memory attribute.
8155 Function &F = cast<Function>(getAnchorValue());
8157 if (isAssumedReadNone())
8158 ME = MemoryEffects::none();
8159 else if (isAssumedReadOnly())
8161 else if (isAssumedWriteOnly())
8163
8164 A.removeAttrs(getIRPosition(), AttrKinds);
8165 // Clear conflicting writable attribute.
8166 if (ME.onlyReadsMemory())
8167 for (Argument &Arg : F.args())
8168 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8169 return A.manifestAttrs(getIRPosition(),
8170 Attribute::getWithMemoryEffects(F.getContext(), ME));
8171 }
8172
8173 /// See AbstractAttribute::trackStatistics()
8174 void trackStatistics() const override {
8175 if (isAssumedReadNone())
8176 STATS_DECLTRACK_FN_ATTR(readnone)
8177 else if (isAssumedReadOnly())
8178 STATS_DECLTRACK_FN_ATTR(readonly)
8179 else if (isAssumedWriteOnly())
8180 STATS_DECLTRACK_FN_ATTR(writeonly)
8181 }
8182};
8183
8184/// AAMemoryBehavior attribute for call sites.
8185struct AAMemoryBehaviorCallSite final
8186 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8187 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8188 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8189
8190 /// See AbstractAttribute::manifest(...).
8191 ChangeStatus manifest(Attributor &A) override {
8192 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8193 CallBase &CB = cast<CallBase>(getAnchorValue());
8195 if (isAssumedReadNone())
8196 ME = MemoryEffects::none();
8197 else if (isAssumedReadOnly())
8199 else if (isAssumedWriteOnly())
8201
8202 A.removeAttrs(getIRPosition(), AttrKinds);
8203 // Clear conflicting writable attribute.
8204 if (ME.onlyReadsMemory())
8205 for (Use &U : CB.args())
8206 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8207 Attribute::Writable);
8208 return A.manifestAttrs(
8209 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8210 }
8211
8212 /// See AbstractAttribute::trackStatistics()
8213 void trackStatistics() const override {
8214 if (isAssumedReadNone())
8215 STATS_DECLTRACK_CS_ATTR(readnone)
8216 else if (isAssumedReadOnly())
8217 STATS_DECLTRACK_CS_ATTR(readonly)
8218 else if (isAssumedWriteOnly())
8219 STATS_DECLTRACK_CS_ATTR(writeonly)
8220 }
8221};
8222
8223ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8224
8225 // The current assumed state used to determine a change.
8226 auto AssumedState = getAssumed();
8227
8228 auto CheckRWInst = [&](Instruction &I) {
8229 // If the instruction has an own memory behavior state, use it to restrict
8230 // the local state. No further analysis is required as the other memory
8231 // state is as optimistic as it gets.
8232 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8233 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8235 if (MemBehaviorAA) {
8236 intersectAssumedBits(MemBehaviorAA->getAssumed());
8237 return !isAtFixpoint();
8238 }
8239 }
8240
8241 // Remove access kind modifiers if necessary.
8242 if (I.mayReadFromMemory())
8243 removeAssumedBits(NO_READS);
8244 if (I.mayWriteToMemory())
8245 removeAssumedBits(NO_WRITES);
8246 return !isAtFixpoint();
8247 };
8248
8249 bool UsedAssumedInformation = false;
8250 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8251 UsedAssumedInformation))
8252 return indicatePessimisticFixpoint();
8253
8254 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8256}
8257
8258ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8259
8260 const IRPosition &IRP = getIRPosition();
8261 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8262 AAMemoryBehavior::StateType &S = getState();
8263
8264 // First, check the function scope. We take the known information and we avoid
8265 // work if the assumed information implies the current assumed information for
8266 // this attribute. This is a valid for all but byval arguments.
8267 Argument *Arg = IRP.getAssociatedArgument();
8268 AAMemoryBehavior::base_t FnMemAssumedState =
8270 if (!Arg || !Arg->hasByValAttr()) {
8271 const auto *FnMemAA =
8272 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8273 if (FnMemAA) {
8274 FnMemAssumedState = FnMemAA->getAssumed();
8275 S.addKnownBits(FnMemAA->getKnown());
8276 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8278 }
8279 }
8280
8281 // The current assumed state used to determine a change.
8282 auto AssumedState = S.getAssumed();
8283
8284 // Make sure the value is not captured (except through "return"), if
8285 // it is, any information derived would be irrelevant anyway as we cannot
8286 // check the potential aliases introduced by the capture. However, no need
8287 // to fall back to anythign less optimistic than the function state.
8288 bool IsKnownNoCapture;
8289 const AANoCapture *ArgNoCaptureAA = nullptr;
8290 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8291 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8292 &ArgNoCaptureAA);
8293
8294 if (!IsAssumedNoCapture &&
8295 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8296 S.intersectAssumedBits(FnMemAssumedState);
8297 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8299 }
8300
8301 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8302 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8303 Instruction *UserI = cast<Instruction>(U.getUser());
8304 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8305 << " \n");
8306
8307 // Droppable users, e.g., llvm::assume does not actually perform any action.
8308 if (UserI->isDroppable())
8309 return true;
8310
8311 // Check if the users of UserI should also be visited.
8312 Follow = followUsersOfUseIn(A, U, UserI);
8313
8314 // If UserI might touch memory we analyze the use in detail.
8315 if (UserI->mayReadOrWriteMemory())
8316 analyzeUseIn(A, U, UserI);
8317
8318 return !isAtFixpoint();
8319 };
8320
8321 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8322 return indicatePessimisticFixpoint();
8323
8324 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8326}
8327
8328bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8329 const Instruction *UserI) {
8330 // The loaded value is unrelated to the pointer argument, no need to
8331 // follow the users of the load.
8332 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8333 return false;
8334
8335 // By default we follow all uses assuming UserI might leak information on U,
8336 // we have special handling for call sites operands though.
8337 const auto *CB = dyn_cast<CallBase>(UserI);
8338 if (!CB || !CB->isArgOperand(&U))
8339 return true;
8340
8341 // If the use is a call argument known not to be captured, the users of
8342 // the call do not need to be visited because they have to be unrelated to
8343 // the input. Note that this check is not trivial even though we disallow
8344 // general capturing of the underlying argument. The reason is that the
8345 // call might the argument "through return", which we allow and for which we
8346 // need to check call users.
8347 if (U.get()->getType()->isPointerTy()) {
8348 unsigned ArgNo = CB->getArgOperandNo(&U);
8349 bool IsKnownNoCapture;
8351 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8352 DepClassTy::OPTIONAL, IsKnownNoCapture);
8353 }
8354
8355 return true;
8356}
8357
8358void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8359 const Instruction *UserI) {
8360 assert(UserI->mayReadOrWriteMemory());
8361
8362 switch (UserI->getOpcode()) {
8363 default:
8364 // TODO: Handle all atomics and other side-effect operations we know of.
8365 break;
8366 case Instruction::Load:
8367 // Loads cause the NO_READS property to disappear.
8368 removeAssumedBits(NO_READS);
8369 return;
8370
8371 case Instruction::Store:
8372 // Stores cause the NO_WRITES property to disappear if the use is the
8373 // pointer operand. Note that while capturing was taken care of somewhere
8374 // else we need to deal with stores of the value that is not looked through.
8375 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8376 removeAssumedBits(NO_WRITES);
8377 else
8378 indicatePessimisticFixpoint();
8379 return;
8380
8381 case Instruction::Call:
8382 case Instruction::CallBr:
8383 case Instruction::Invoke: {
8384 // For call sites we look at the argument memory behavior attribute (this
8385 // could be recursive!) in order to restrict our own state.
8386 const auto *CB = cast<CallBase>(UserI);
8387
8388 // Give up on operand bundles.
8389 if (CB->isBundleOperand(&U)) {
8390 indicatePessimisticFixpoint();
8391 return;
8392 }
8393
8394 // Calling a function does read the function pointer, maybe write it if the
8395 // function is self-modifying.
8396 if (CB->isCallee(&U)) {
8397 removeAssumedBits(NO_READS);
8398 break;
8399 }
8400
8401 // Adjust the possible access behavior based on the information on the
8402 // argument.
8403 IRPosition Pos;
8404 if (U.get()->getType()->isPointerTy())
8406 else
8408 const auto *MemBehaviorAA =
8409 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8410 if (!MemBehaviorAA)
8411 break;
8412 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8413 // and at least "known".
8414 intersectAssumedBits(MemBehaviorAA->getAssumed());
8415 return;
8416 }
8417 };
8418
8419 // Generally, look at the "may-properties" and adjust the assumed state if we
8420 // did not trigger special handling before.
8421 if (UserI->mayReadFromMemory())
8422 removeAssumedBits(NO_READS);
8423 if (UserI->mayWriteToMemory())
8424 removeAssumedBits(NO_WRITES);
8425}
8426} // namespace
8427
8428/// -------------------- Memory Locations Attributes ---------------------------
8429/// Includes read-none, argmemonly, inaccessiblememonly,
8430/// inaccessiblememorargmemonly
8431/// ----------------------------------------------------------------------------
8432
8435 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8436 return "all memory";
8438 return "no memory";
8439 std::string S = "memory:";
8440 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8441 S += "stack,";
8442 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8443 S += "constant,";
8445 S += "internal global,";
8447 S += "external global,";
8448 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8449 S += "argument,";
8451 S += "inaccessible,";
8452 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8453 S += "malloced,";
8454 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8455 S += "unknown,";
8456 S.pop_back();
8457 return S;
8458}
8459
8460namespace {
8461struct AAMemoryLocationImpl : public AAMemoryLocation {
8462
8463 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8464 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) {
8465 AccessKind2Accesses.fill(nullptr);
8466 }
8467
8468 ~AAMemoryLocationImpl() override {
8469 // The AccessSets are allocated via a BumpPtrAllocator, we call
8470 // the destructor manually.
8471 for (AccessSet *AS : AccessKind2Accesses)
8472 if (AS)
8473 AS->~AccessSet();
8474 }
8475
8476 /// See AbstractAttribute::initialize(...).
8477 void initialize(Attributor &A) override {
8478 intersectAssumedBits(BEST_STATE);
8479 getKnownStateFromValue(A, getIRPosition(), getState());
8480 AAMemoryLocation::initialize(A);
8481 }
8482
8483 /// Return the memory behavior information encoded in the IR for \p IRP.
8484 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8485 BitIntegerState &State,
8486 bool IgnoreSubsumingPositions = false) {
8487 // For internal functions we ignore `argmemonly` and
8488 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8489 // constant propagation. It is unclear if this is the best way but it is
8490 // unlikely this will cause real performance problems. If we are deriving
8491 // attributes for the anchor function we even remove the attribute in
8492 // addition to ignoring it.
8493 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8494 // MemoryEffects::Other as a possible location.
8495 bool UseArgMemOnly = true;
8496 Function *AnchorFn = IRP.getAnchorScope();
8497 if (AnchorFn && A.isRunOn(*AnchorFn))
8498 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8499
8501 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8502 for (const Attribute &Attr : Attrs) {
8503 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8504 MemoryEffects ME = Attr.getMemoryEffects();
8505 if (ME.doesNotAccessMemory()) {
8506 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8507 continue;
8508 }
8509 if (ME.onlyAccessesInaccessibleMem()) {
8510 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8511 continue;
8512 }
8513 if (ME.onlyAccessesArgPointees()) {
8514 if (UseArgMemOnly)
8515 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8516 else {
8517 // Remove location information, only keep read/write info.
8518 ME = MemoryEffects(ME.getModRef());
8519 A.manifestAttrs(IRP,
8520 Attribute::getWithMemoryEffects(
8521 IRP.getAnchorValue().getContext(), ME),
8522 /*ForceReplace*/ true);
8523 }
8524 continue;
8525 }
8527 if (UseArgMemOnly)
8528 State.addKnownBits(inverseLocation(
8529 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8530 else {
8531 // Remove location information, only keep read/write info.
8532 ME = MemoryEffects(ME.getModRef());
8533 A.manifestAttrs(IRP,
8534 Attribute::getWithMemoryEffects(
8535 IRP.getAnchorValue().getContext(), ME),
8536 /*ForceReplace*/ true);
8537 }
8538 continue;
8539 }
8540 }
8541 }
8542
8543 /// See AbstractAttribute::getDeducedAttributes(...).
8544 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8545 SmallVectorImpl<Attribute> &Attrs) const override {
8546 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8547 assert(Attrs.size() == 0);
8548 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8549 if (isAssumedReadNone())
8550 Attrs.push_back(
8551 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none()));
8552 else if (isAssumedInaccessibleMemOnly())
8553 Attrs.push_back(Attribute::getWithMemoryEffects(
8555 else if (isAssumedArgMemOnly())
8556 Attrs.push_back(
8557 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly()));
8558 else if (isAssumedInaccessibleOrArgMemOnly())
8559 Attrs.push_back(Attribute::getWithMemoryEffects(
8561 }
8562 assert(Attrs.size() <= 1);
8563 }
8564
8565 /// See AbstractAttribute::manifest(...).
8566 ChangeStatus manifest(Attributor &A) override {
8567 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8568 // provide per-location modref information here.
8569 const IRPosition &IRP = getIRPosition();
8570
8571 SmallVector<Attribute, 1> DeducedAttrs;
8572 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8573 if (DeducedAttrs.size() != 1)
8574 return ChangeStatus::UNCHANGED;
8575 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8576
8577 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8578 IRP.getAnchorValue().getContext(), ME));
8579 }
8580
8581 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8582 bool checkForAllAccessesToMemoryKind(
8583 function_ref<bool(const Instruction *, const Value *, AccessKind,
8584 MemoryLocationsKind)>
8585 Pred,
8586 MemoryLocationsKind RequestedMLK) const override {
8587 if (!isValidState())
8588 return false;
8589
8590 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8591 if (AssumedMLK == NO_LOCATIONS)
8592 return true;
8593
8594 unsigned Idx = 0;
8595 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8596 CurMLK *= 2, ++Idx) {
8597 if (CurMLK & RequestedMLK)
8598 continue;
8599
8600 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8601 for (const AccessInfo &AI : *Accesses)
8602 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8603 return false;
8604 }
8605
8606 return true;
8607 }
8608
8609 ChangeStatus indicatePessimisticFixpoint() override {
8610 // If we give up and indicate a pessimistic fixpoint this instruction will
8611 // become an access for all potential access kinds:
8612 // TODO: Add pointers for argmemonly and globals to improve the results of
8613 // checkForAllAccessesToMemoryKind.
8614 bool Changed = false;
8615 MemoryLocationsKind KnownMLK = getKnown();
8616 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8617 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8618 if (!(CurMLK & KnownMLK))
8619 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8620 getAccessKindFromInst(I));
8621 return AAMemoryLocation::indicatePessimisticFixpoint();
8622 }
8623
8624protected:
8625 /// Helper struct to tie together an instruction that has a read or write
8626 /// effect with the pointer it accesses (if any).
8627 struct AccessInfo {
8628
8629 /// The instruction that caused the access.
8630 const Instruction *I;
8631
8632 /// The base pointer that is accessed, or null if unknown.
8633 const Value *Ptr;
8634
8635 /// The kind of access (read/write/read+write).
8637
8638 bool operator==(const AccessInfo &RHS) const {
8639 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8640 }
8641 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8642 if (LHS.I != RHS.I)
8643 return LHS.I < RHS.I;
8644 if (LHS.Ptr != RHS.Ptr)
8645 return LHS.Ptr < RHS.Ptr;
8646 if (LHS.Kind != RHS.Kind)
8647 return LHS.Kind < RHS.Kind;
8648 return false;
8649 }
8650 };
8651
8652 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8653 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8654 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8655 std::array<AccessSet *, llvm::ConstantLog2<VALID_STATE>()>
8656 AccessKind2Accesses;
8657
8658 /// Categorize the pointer arguments of CB that might access memory in
8659 /// AccessedLoc and update the state and access map accordingly.
8660 void
8661 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8662 AAMemoryLocation::StateType &AccessedLocs,
8663 bool &Changed);
8664
8665 /// Return the kind(s) of location that may be accessed by \p V.
8667 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8668
8669 /// Return the access kind as determined by \p I.
8670 AccessKind getAccessKindFromInst(const Instruction *I) {
8671 AccessKind AK = READ_WRITE;
8672 if (I) {
8673 AK = I->mayReadFromMemory() ? READ : NONE;
8674 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8675 }
8676 return AK;
8677 }
8678
8679 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8680 /// an access of kind \p AK to a \p MLK memory location with the access
8681 /// pointer \p Ptr.
8682 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8683 MemoryLocationsKind MLK, const Instruction *I,
8684 const Value *Ptr, bool &Changed,
8685 AccessKind AK = READ_WRITE) {
8686
8687 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8688 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8689 if (!Accesses)
8690 Accesses = new (Allocator) AccessSet();
8691 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8692 if (MLK == NO_UNKOWN_MEM)
8693 MLK = NO_LOCATIONS;
8694 State.removeAssumedBits(MLK);
8695 }
8696
8697 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8698 /// arguments, and update the state and access map accordingly.
8699 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8700 AAMemoryLocation::StateType &State, bool &Changed,
8701 unsigned AccessAS = 0);
8702
8703 /// Used to allocate access sets.
8705};
8706
8707void AAMemoryLocationImpl::categorizePtrValue(
8708 Attributor &A, const Instruction &I, const Value &Ptr,
8709 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8710 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8711 << Ptr << " ["
8712 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8713
8714 auto Pred = [&](Value &Obj) {
8715 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8716 // TODO: recognize the TBAA used for constant accesses.
8717 MemoryLocationsKind MLK = NO_LOCATIONS;
8718
8719 // Filter accesses to constant (GPU) memory if we have an AS at the access
8720 // site or the object is known to actually have the associated AS.
8721 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8722 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8723 isIdentifiedObject(&Obj))) &&
8724 AA::isGPU(*I.getModule()))
8725 return true;
8726
8727 if (isa<UndefValue>(&Obj))
8728 return true;
8729 if (isa<Argument>(&Obj)) {
8730 // TODO: For now we do not treat byval arguments as local copies performed
8731 // on the call edge, though, we should. To make that happen we need to
8732 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8733 // would also allow us to mark functions only accessing byval arguments as
8734 // readnone again, arguably their accesses have no effect outside of the
8735 // function, like accesses to allocas.
8736 MLK = NO_ARGUMENT_MEM;
8737 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8738 // Reading constant memory is not treated as a read "effect" by the
8739 // function attr pass so we won't neither. Constants defined by TBAA are
8740 // similar. (We know we do not write it because it is constant.)
8741 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8742 if (GVar->isConstant())
8743 return true;
8744
8745 if (GV->hasLocalLinkage())
8746 MLK = NO_GLOBAL_INTERNAL_MEM;
8747 else
8748 MLK = NO_GLOBAL_EXTERNAL_MEM;
8749 } else if (isa<ConstantPointerNull>(&Obj) &&
8750 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8751 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8752 return true;
8753 } else if (isa<AllocaInst>(&Obj)) {
8754 MLK = NO_LOCAL_MEM;
8755 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8756 bool IsKnownNoAlias;
8759 IsKnownNoAlias))
8760 MLK = NO_MALLOCED_MEM;
8761 else
8762 MLK = NO_UNKOWN_MEM;
8763 } else {
8764 MLK = NO_UNKOWN_MEM;
8765 }
8766
8767 assert(MLK != NO_LOCATIONS && "No location specified!");
8768 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8769 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8770 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8771 getAccessKindFromInst(&I));
8772
8773 return true;
8774 };
8775
8776 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8778 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8779 LLVM_DEBUG(
8780 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8781 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8782 getAccessKindFromInst(&I));
8783 return;
8784 }
8785
8786 LLVM_DEBUG(
8787 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8788 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8789}
8790
8791void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8792 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8793 bool &Changed) {
8794 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8795
8796 // Skip non-pointer arguments.
8797 const Value *ArgOp = CB.getArgOperand(ArgNo);
8798 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8799 continue;
8800
8801 // Skip readnone arguments.
8802 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8803 const auto *ArgOpMemLocationAA =
8804 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8805
8806 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8807 continue;
8808
8809 // Categorize potentially accessed pointer arguments as if there was an
8810 // access instruction with them as pointer.
8811 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8812 }
8813}
8814
8816AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8817 bool &Changed) {
8818 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8819 << I << "\n");
8820
8821 AAMemoryLocation::StateType AccessedLocs;
8822 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8823
8824 if (auto *CB = dyn_cast<CallBase>(&I)) {
8825
8826 // First check if we assume any memory is access is visible.
8827 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8829 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8830 << " [" << CBMemLocationAA << "]\n");
8831 if (!CBMemLocationAA) {
8832 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8833 Changed, getAccessKindFromInst(&I));
8834 return NO_UNKOWN_MEM;
8835 }
8836
8837 if (CBMemLocationAA->isAssumedReadNone())
8838 return NO_LOCATIONS;
8839
8840 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8841 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8842 Changed, getAccessKindFromInst(&I));
8843 return AccessedLocs.getAssumed();
8844 }
8845
8846 uint32_t CBAssumedNotAccessedLocs =
8847 CBMemLocationAA->getAssumedNotAccessedLocation();
8848
8849 // Set the argmemonly and global bit as we handle them separately below.
8850 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8851 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8852
8853 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8854 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8855 continue;
8856 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8857 getAccessKindFromInst(&I));
8858 }
8859
8860 // Now handle global memory if it might be accessed. This is slightly tricky
8861 // as NO_GLOBAL_MEM has multiple bits set.
8862 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8863 if (HasGlobalAccesses) {
8864 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8865 AccessKind Kind, MemoryLocationsKind MLK) {
8866 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8867 getAccessKindFromInst(&I));
8868 return true;
8869 };
8870 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8871 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8872 return AccessedLocs.getWorstState();
8873 }
8874
8875 LLVM_DEBUG(
8876 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8877 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8878
8879 // Now handle argument memory if it might be accessed.
8880 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8881 if (HasArgAccesses)
8882 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8883
8884 LLVM_DEBUG(
8885 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8886 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8887
8888 return AccessedLocs.getAssumed();
8889 }
8890
8891 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8892 LLVM_DEBUG(
8893 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8894 << I << " [" << *Ptr << "]\n");
8895 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8896 Ptr->getType()->getPointerAddressSpace());
8897 return AccessedLocs.getAssumed();
8898 }
8899
8900 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8901 << I << "\n");
8902 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8903 getAccessKindFromInst(&I));
8904 return AccessedLocs.getAssumed();
8905}
8906
8907/// An AA to represent the memory behavior function attributes.
8908struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8909 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8910 : AAMemoryLocationImpl(IRP, A) {}
8911
8912 /// See AbstractAttribute::updateImpl(Attributor &A).
8913 ChangeStatus updateImpl(Attributor &A) override {
8914
8915 const auto *MemBehaviorAA =
8916 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8917 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8918 if (MemBehaviorAA->isKnownReadNone())
8919 return indicateOptimisticFixpoint();
8921 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8922 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8923 return ChangeStatus::UNCHANGED;
8924 }
8925
8926 // The current assumed state used to determine a change.
8927 auto AssumedState = getAssumed();
8928 bool Changed = false;
8929
8930 auto CheckRWInst = [&](Instruction &I) {
8931 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8932 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8933 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8934 removeAssumedBits(inverseLocation(MLK, false, false));
8935 // Stop once only the valid bit set in the *not assumed location*, thus
8936 // once we don't actually exclude any memory locations in the state.
8937 return getAssumedNotAccessedLocation() != VALID_STATE;
8938 };
8939
8940 bool UsedAssumedInformation = false;
8941 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8942 UsedAssumedInformation))
8943 return indicatePessimisticFixpoint();
8944
8945 Changed |= AssumedState != getAssumed();
8946 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8947 }
8948
8949 /// See AbstractAttribute::trackStatistics()
8950 void trackStatistics() const override {
8951 if (isAssumedReadNone())
8952 STATS_DECLTRACK_FN_ATTR(readnone)
8953 else if (isAssumedArgMemOnly())
8954 STATS_DECLTRACK_FN_ATTR(argmemonly)
8955 else if (isAssumedInaccessibleMemOnly())
8956 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8957 else if (isAssumedInaccessibleOrArgMemOnly())
8958 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8959 }
8960};
8961
8962/// AAMemoryLocation attribute for call sites.
8963struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8964 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8965 : AAMemoryLocationImpl(IRP, A) {}
8966
8967 /// See AbstractAttribute::updateImpl(...).
8968 ChangeStatus updateImpl(Attributor &A) override {
8969 // TODO: Once we have call site specific value information we can provide
8970 // call site specific liveness liveness information and then it makes
8971 // sense to specialize attributes for call sites arguments instead of
8972 // redirecting requests to the callee argument.
8973 Function *F = getAssociatedFunction();
8974 const IRPosition &FnPos = IRPosition::function(*F);
8975 auto *FnAA =
8976 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8977 if (!FnAA)
8978 return indicatePessimisticFixpoint();
8979 bool Changed = false;
8980 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8981 AccessKind Kind, MemoryLocationsKind MLK) {
8982 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8983 getAccessKindFromInst(I));
8984 return true;
8985 };
8986 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8987 return indicatePessimisticFixpoint();
8988 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8989 }
8990
8991 /// See AbstractAttribute::trackStatistics()
8992 void trackStatistics() const override {
8993 if (isAssumedReadNone())
8994 STATS_DECLTRACK_CS_ATTR(readnone)
8995 }
8996};
8997} // namespace
8998
8999/// ------------------ denormal-fp-math Attribute -------------------------
9000
9001namespace {
9002struct AADenormalFPMathImpl : public AADenormalFPMath {
9003 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
9004 : AADenormalFPMath(IRP, A) {}
9005
9006 const std::string getAsStr(Attributor *A) const override {
9007 std::string Str("AADenormalFPMath[");
9008 raw_string_ostream OS(Str);
9009
9010 DenormalState Known = getKnown();
9011 if (Known.Mode.isValid())
9012 OS << "denormal-fp-math=" << Known.Mode;
9013 else
9014 OS << "invalid";
9015
9016 if (Known.ModeF32.isValid())
9017 OS << " denormal-fp-math-f32=" << Known.ModeF32;
9018 OS << ']';
9019 return Str;
9020 }
9021};
9022
9023struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
9024 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
9025 : AADenormalFPMathImpl(IRP, A) {}
9026
9027 void initialize(Attributor &A) override {
9028 const Function *F = getAnchorScope();
9029 DenormalFPEnv DenormEnv = F->getDenormalFPEnv();
9030
9031 Known = DenormalState{DenormEnv.DefaultMode, DenormEnv.F32Mode};
9032 if (isModeFixed())
9033 indicateFixpoint();
9034 }
9035
9036 ChangeStatus updateImpl(Attributor &A) override {
9037 ChangeStatus Change = ChangeStatus::UNCHANGED;
9038
9039 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
9040 Function *Caller = CS.getInstruction()->getFunction();
9041 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
9042 << "->" << getAssociatedFunction()->getName() << '\n');
9043
9044 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
9045 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
9046 if (!CallerInfo)
9047 return false;
9048
9049 Change = Change | clampStateAndIndicateChange(this->getState(),
9050 CallerInfo->getState());
9051 return true;
9052 };
9053
9054 bool AllCallSitesKnown = true;
9055 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
9056 return indicatePessimisticFixpoint();
9057
9058 if (Change == ChangeStatus::CHANGED && isModeFixed())
9059 indicateFixpoint();
9060 return Change;
9061 }
9062
9063 ChangeStatus manifest(Attributor &A) override {
9064 LLVMContext &Ctx = getAssociatedFunction()->getContext();
9065
9066 SmallVector<Attribute, 2> AttrToAdd;
9068
9069 // TODO: Change to use DenormalFPEnv everywhere.
9070 DenormalFPEnv KnownEnv(Known.Mode, Known.ModeF32);
9071
9072 if (KnownEnv == DenormalFPEnv::getDefault()) {
9073 AttrToRemove.push_back(Attribute::DenormalFPEnv);
9074 } else {
9075 AttrToAdd.push_back(Attribute::get(
9076 Ctx, Attribute::DenormalFPEnv,
9077 DenormalFPEnv(Known.Mode, Known.ModeF32).toIntValue()));
9078 }
9079
9080 auto &IRP = getIRPosition();
9081
9082 // TODO: There should be a combined add and remove API.
9083 return A.removeAttrs(IRP, AttrToRemove) |
9084 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9085 }
9086
9087 void trackStatistics() const override {
9088 STATS_DECLTRACK_FN_ATTR(denormal_fpenv)
9089 }
9090};
9091} // namespace
9092
9093/// ------------------ Value Constant Range Attribute -------------------------
9094
9095namespace {
9096struct AAValueConstantRangeImpl : AAValueConstantRange {
9097 using StateType = IntegerRangeState;
9098 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9099 : AAValueConstantRange(IRP, A) {}
9100
9101 /// See AbstractAttribute::initialize(..).
9102 void initialize(Attributor &A) override {
9103 if (A.hasSimplificationCallback(getIRPosition())) {
9104 indicatePessimisticFixpoint();
9105 return;
9106 }
9107
9108 // Intersect a range given by SCEV.
9109 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9110
9111 // Intersect a range given by LVI.
9112 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9113 }
9114
9115 /// See AbstractAttribute::getAsStr().
9116 const std::string getAsStr(Attributor *A) const override {
9117 std::string Str;
9118 llvm::raw_string_ostream OS(Str);
9119 OS << "range(" << getBitWidth() << ")<";
9120 getKnown().print(OS);
9121 OS << " / ";
9122 getAssumed().print(OS);
9123 OS << ">";
9124 return Str;
9125 }
9126
9127 /// Helper function to get a SCEV expr for the associated value at program
9128 /// point \p I.
9129 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9130 if (!getAnchorScope())
9131 return nullptr;
9132
9133 ScalarEvolution *SE =
9134 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9135 *getAnchorScope());
9136
9137 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9138 *getAnchorScope());
9139
9140 if (!SE || !LI)
9141 return nullptr;
9142
9143 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9144 if (!I)
9145 return S;
9146
9147 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9148 }
9149
9150 /// Helper function to get a range from SCEV for the associated value at
9151 /// program point \p I.
9152 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9153 const Instruction *I = nullptr) const {
9154 if (!getAnchorScope())
9155 return getWorstState(getBitWidth());
9156
9157 ScalarEvolution *SE =
9158 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9159 *getAnchorScope());
9160
9161 const SCEV *S = getSCEV(A, I);
9162 if (!SE || !S)
9163 return getWorstState(getBitWidth());
9164
9165 return SE->getUnsignedRange(S);
9166 }
9167
9168 /// Helper function to get a range from LVI for the associated value at
9169 /// program point \p I.
9170 ConstantRange
9171 getConstantRangeFromLVI(Attributor &A,
9172 const Instruction *CtxI = nullptr) const {
9173 if (!getAnchorScope())
9174 return getWorstState(getBitWidth());
9175
9176 LazyValueInfo *LVI =
9177 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9178 *getAnchorScope());
9179
9180 if (!LVI || !CtxI)
9181 return getWorstState(getBitWidth());
9182 return LVI->getConstantRange(&getAssociatedValue(),
9183 const_cast<Instruction *>(CtxI),
9184 /*UndefAllowed*/ false);
9185 }
9186
9187 /// Return true if \p CtxI is valid for querying outside analyses.
9188 /// This basically makes sure we do not ask intra-procedural analysis
9189 /// about a context in the wrong function or a context that violates
9190 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9191 /// if the original context of this AA is OK or should be considered invalid.
9192 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9193 const Instruction *CtxI,
9194 bool AllowAACtxI) const {
9195 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9196 return false;
9197
9198 // Our context might be in a different function, neither intra-procedural
9199 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9200 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9201 return false;
9202
9203 // If the context is not dominated by the value there are paths to the
9204 // context that do not define the value. This cannot be handled by
9205 // LazyValueInfo so we need to bail.
9206 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9207 InformationCache &InfoCache = A.getInfoCache();
9208 const DominatorTree *DT =
9209 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
9210 *I->getFunction());
9211 return DT && DT->dominates(I, CtxI);
9212 }
9213
9214 return true;
9215 }
9216
9217 /// See AAValueConstantRange::getKnownConstantRange(..).
9218 ConstantRange
9219 getKnownConstantRange(Attributor &A,
9220 const Instruction *CtxI = nullptr) const override {
9221 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9222 /* AllowAACtxI */ false))
9223 return getKnown();
9224
9225 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9226 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9227 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9228 }
9229
9230 /// See AAValueConstantRange::getAssumedConstantRange(..).
9231 ConstantRange
9232 getAssumedConstantRange(Attributor &A,
9233 const Instruction *CtxI = nullptr) const override {
9234 // TODO: Make SCEV use Attributor assumption.
9235 // We may be able to bound a variable range via assumptions in
9236 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9237 // evolve to x^2 + x, then we can say that y is in [2, 12].
9238 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9239 /* AllowAACtxI */ false))
9240 return getAssumed();
9241
9242 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9243 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9244 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9245 }
9246
9247 /// Helper function to create MDNode for range metadata.
9248 static MDNode *
9249 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9250 const ConstantRange &AssumedConstantRange) {
9251 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9252 Ty, AssumedConstantRange.getLower())),
9253 ConstantAsMetadata::get(ConstantInt::get(
9254 Ty, AssumedConstantRange.getUpper()))};
9255 return MDNode::get(Ctx, LowAndHigh);
9256 }
9257
9258 /// Return true if \p Assumed is included in ranges from instruction \p I.
9259 static bool isBetterRange(const ConstantRange &Assumed,
9260 const Instruction &I) {
9261 if (Assumed.isFullSet())
9262 return false;
9263
9264 std::optional<ConstantRange> Known;
9265
9266 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9267 Known = CB->getRange();
9268 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9269 // If multiple ranges are annotated in IR, we give up to annotate assumed
9270 // range for now.
9271
9272 // TODO: If there exists a known range which containts assumed range, we
9273 // can say assumed range is better.
9274 if (KnownRanges->getNumOperands() > 2)
9275 return false;
9276
9277 ConstantInt *Lower =
9278 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9279 ConstantInt *Upper =
9280 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9281
9282 Known.emplace(Lower->getValue(), Upper->getValue());
9283 }
9284 return !Known || (*Known != Assumed && Known->contains(Assumed));
9285 }
9286
9287 /// Helper function to set range metadata.
9288 static bool
9289 setRangeMetadataIfisBetterRange(Instruction *I,
9290 const ConstantRange &AssumedConstantRange) {
9291 if (isBetterRange(AssumedConstantRange, *I)) {
9292 I->setMetadata(LLVMContext::MD_range,
9293 getMDNodeForConstantRange(I->getType(), I->getContext(),
9294 AssumedConstantRange));
9295 return true;
9296 }
9297 return false;
9298 }
9299 /// Helper function to set range return attribute.
9300 static bool
9301 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9302 Instruction *I,
9303 const ConstantRange &AssumedConstantRange) {
9304 if (isBetterRange(AssumedConstantRange, *I)) {
9305 A.manifestAttrs(IRP,
9306 Attribute::get(I->getContext(), Attribute::Range,
9307 AssumedConstantRange),
9308 /*ForceReplace*/ true);
9309 return true;
9310 }
9311 return false;
9312 }
9313
9314 /// See AbstractAttribute::manifest()
9315 ChangeStatus manifest(Attributor &A) override {
9316 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9317 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9318 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9319
9320 auto &V = getAssociatedValue();
9321 if (!AssumedConstantRange.isEmptySet() &&
9322 !AssumedConstantRange.isSingleElement()) {
9323 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9324 assert(I == getCtxI() && "Should not annotate an instruction which is "
9325 "not the context instruction");
9326 if (isa<LoadInst>(I))
9327 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9328 Changed = ChangeStatus::CHANGED;
9329 if (isa<CallInst>(I))
9330 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9331 AssumedConstantRange))
9332 Changed = ChangeStatus::CHANGED;
9333 }
9334 }
9335
9336 return Changed;
9337 }
9338};
9339
9340struct AAValueConstantRangeArgument final
9341 : AAArgumentFromCallSiteArguments<
9342 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9343 true /* BridgeCallBaseContext */> {
9344 using Base = AAArgumentFromCallSiteArguments<
9345 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9346 true /* BridgeCallBaseContext */>;
9347 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9348 : Base(IRP, A) {}
9349
9350 /// See AbstractAttribute::trackStatistics()
9351 void trackStatistics() const override {
9352 STATS_DECLTRACK_ARG_ATTR(value_range)
9353 }
9354};
9355
9356struct AAValueConstantRangeReturned
9357 : AAReturnedFromReturnedValues<AAValueConstantRange,
9358 AAValueConstantRangeImpl,
9359 AAValueConstantRangeImpl::StateType,
9360 /* PropagateCallBaseContext */ true> {
9361 using Base =
9362 AAReturnedFromReturnedValues<AAValueConstantRange,
9363 AAValueConstantRangeImpl,
9364 AAValueConstantRangeImpl::StateType,
9365 /* PropagateCallBaseContext */ true>;
9366 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9367 : Base(IRP, A) {}
9368
9369 /// See AbstractAttribute::initialize(...).
9370 void initialize(Attributor &A) override {
9371 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9372 indicatePessimisticFixpoint();
9373 }
9374
9375 /// See AbstractAttribute::trackStatistics()
9376 void trackStatistics() const override {
9377 STATS_DECLTRACK_FNRET_ATTR(value_range)
9378 }
9379};
9380
9381struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9382 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9383 : AAValueConstantRangeImpl(IRP, A) {}
9384
9385 /// See AbstractAttribute::initialize(...).
9386 void initialize(Attributor &A) override {
9387 AAValueConstantRangeImpl::initialize(A);
9388 if (isAtFixpoint())
9389 return;
9390
9391 Value &V = getAssociatedValue();
9392
9393 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9394 unionAssumed(ConstantRange(C->getValue()));
9395 indicateOptimisticFixpoint();
9396 return;
9397 }
9398
9399 if (isa<UndefValue>(&V)) {
9400 // Collapse the undef state to 0.
9401 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9402 indicateOptimisticFixpoint();
9403 return;
9404 }
9405
9406 if (isa<CallBase>(&V))
9407 return;
9408
9409 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9410 return;
9411
9412 // If it is a load instruction with range metadata, use it.
9413 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9414 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9415 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9416 return;
9417 }
9418
9419 // We can work with PHI and select instruction as we traverse their operands
9420 // during update.
9421 if (isa<SelectInst>(V) || isa<PHINode>(V))
9422 return;
9423
9424 // Otherwise we give up.
9425 indicatePessimisticFixpoint();
9426
9427 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9428 << getAssociatedValue() << "\n");
9429 }
9430
9431 bool calculateBinaryOperator(
9432 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
9433 const Instruction *CtxI,
9434 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9435 Value *LHS = BinOp->getOperand(0);
9436 Value *RHS = BinOp->getOperand(1);
9437
9438 // Simplify the operands first.
9439 bool UsedAssumedInformation = false;
9440 const auto &SimplifiedLHS = A.getAssumedSimplified(
9441 IRPosition::value(*LHS, getCallBaseContext()), *this,
9442 UsedAssumedInformation, AA::Interprocedural);
9443 if (!SimplifiedLHS.has_value())
9444 return true;
9445 if (!*SimplifiedLHS)
9446 return false;
9447 LHS = *SimplifiedLHS;
9448
9449 const auto &SimplifiedRHS = A.getAssumedSimplified(
9450 IRPosition::value(*RHS, getCallBaseContext()), *this,
9451 UsedAssumedInformation, AA::Interprocedural);
9452 if (!SimplifiedRHS.has_value())
9453 return true;
9454 if (!*SimplifiedRHS)
9455 return false;
9456 RHS = *SimplifiedRHS;
9457
9458 // TODO: Allow non integers as well.
9459 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9460 return false;
9461
9462 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9463 *this, IRPosition::value(*LHS, getCallBaseContext()),
9464 DepClassTy::REQUIRED);
9465 if (!LHSAA)
9466 return false;
9467 QuerriedAAs.push_back(LHSAA);
9468 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9469
9470 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9471 *this, IRPosition::value(*RHS, getCallBaseContext()),
9472 DepClassTy::REQUIRED);
9473 if (!RHSAA)
9474 return false;
9475 QuerriedAAs.push_back(RHSAA);
9476 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9477
9478 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9479
9480 T.unionAssumed(AssumedRange);
9481
9482 // TODO: Track a known state too.
9483
9484 return T.isValidState();
9485 }
9486
9487 bool calculateCastInst(
9488 Attributor &A, CastInst *CastI, IntegerRangeState &T,
9489 const Instruction *CtxI,
9490 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9491 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9492 // TODO: Allow non integers as well.
9493 Value *OpV = CastI->getOperand(0);
9494
9495 // Simplify the operand first.
9496 bool UsedAssumedInformation = false;
9497 const auto &SimplifiedOpV = A.getAssumedSimplified(
9498 IRPosition::value(*OpV, getCallBaseContext()), *this,
9499 UsedAssumedInformation, AA::Interprocedural);
9500 if (!SimplifiedOpV.has_value())
9501 return true;
9502 if (!*SimplifiedOpV)
9503 return false;
9504 OpV = *SimplifiedOpV;
9505
9506 if (!OpV->getType()->isIntegerTy())
9507 return false;
9508
9509 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9510 *this, IRPosition::value(*OpV, getCallBaseContext()),
9511 DepClassTy::REQUIRED);
9512 if (!OpAA)
9513 return false;
9514 QuerriedAAs.push_back(OpAA);
9515 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9516 getState().getBitWidth()));
9517 return T.isValidState();
9518 }
9519
9520 bool
9521 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9522 const Instruction *CtxI,
9523 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
9524 Value *LHS = CmpI->getOperand(0);
9525 Value *RHS = CmpI->getOperand(1);
9526
9527 // Simplify the operands first.
9528 bool UsedAssumedInformation = false;
9529 const auto &SimplifiedLHS = A.getAssumedSimplified(
9530 IRPosition::value(*LHS, getCallBaseContext()), *this,
9531 UsedAssumedInformation, AA::Interprocedural);
9532 if (!SimplifiedLHS.has_value())
9533 return true;
9534 if (!*SimplifiedLHS)
9535 return false;
9536 LHS = *SimplifiedLHS;
9537
9538 const auto &SimplifiedRHS = A.getAssumedSimplified(
9539 IRPosition::value(*RHS, getCallBaseContext()), *this,
9540 UsedAssumedInformation, AA::Interprocedural);
9541 if (!SimplifiedRHS.has_value())
9542 return true;
9543 if (!*SimplifiedRHS)
9544 return false;
9545 RHS = *SimplifiedRHS;
9546
9547 // TODO: Allow non integers as well.
9548 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9549 return false;
9550
9551 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9552 *this, IRPosition::value(*LHS, getCallBaseContext()),
9553 DepClassTy::REQUIRED);
9554 if (!LHSAA)
9555 return false;
9556 QuerriedAAs.push_back(LHSAA);
9557 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9558 *this, IRPosition::value(*RHS, getCallBaseContext()),
9559 DepClassTy::REQUIRED);
9560 if (!RHSAA)
9561 return false;
9562 QuerriedAAs.push_back(RHSAA);
9563 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9564 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9565
9566 // If one of them is empty set, we can't decide.
9567 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9568 return true;
9569
9570 bool MustTrue = false, MustFalse = false;
9571
9572 auto AllowedRegion =
9574
9575 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9576 MustFalse = true;
9577
9578 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9579 MustTrue = true;
9580
9581 assert((!MustTrue || !MustFalse) &&
9582 "Either MustTrue or MustFalse should be false!");
9583
9584 if (MustTrue)
9585 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9586 else if (MustFalse)
9587 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9588 else
9589 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9590
9591 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9592 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9593 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9594 << *RHSAA);
9595
9596 // TODO: Track a known state too.
9597 return T.isValidState();
9598 }
9599
9600 /// See AbstractAttribute::updateImpl(...).
9601 ChangeStatus updateImpl(Attributor &A) override {
9602
9603 IntegerRangeState T(getBitWidth());
9604 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9606 if (!I || isa<CallBase>(I)) {
9607
9608 // Simplify the operand first.
9609 bool UsedAssumedInformation = false;
9610 const auto &SimplifiedOpV = A.getAssumedSimplified(
9611 IRPosition::value(V, getCallBaseContext()), *this,
9612 UsedAssumedInformation, AA::Interprocedural);
9613 if (!SimplifiedOpV.has_value())
9614 return true;
9615 if (!*SimplifiedOpV)
9616 return false;
9617 Value *VPtr = *SimplifiedOpV;
9618
9619 // If the value is not instruction, we query AA to Attributor.
9620 const auto *AA = A.getAAFor<AAValueConstantRange>(
9621 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9622 DepClassTy::REQUIRED);
9623
9624 // Clamp operator is not used to utilize a program point CtxI.
9625 if (AA)
9626 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9627 else
9628 return false;
9629
9630 return T.isValidState();
9631 }
9632
9634 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9635 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9636 return false;
9637 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9638 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9639 return false;
9640 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9641 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9642 return false;
9643 } else {
9644 // Give up with other instructions.
9645 // TODO: Add other instructions
9646
9647 T.indicatePessimisticFixpoint();
9648 return false;
9649 }
9650
9651 // Catch circular reasoning in a pessimistic way for now.
9652 // TODO: Check how the range evolves and if we stripped anything, see also
9653 // AADereferenceable or AAAlign for similar situations.
9654 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9655 if (QueriedAA != this)
9656 continue;
9657 // If we are in a stady state we do not need to worry.
9658 if (T.getAssumed() == getState().getAssumed())
9659 continue;
9660 T.indicatePessimisticFixpoint();
9661 }
9662
9663 return T.isValidState();
9664 };
9665
9666 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9667 return indicatePessimisticFixpoint();
9668
9669 // Ensure that long def-use chains can't cause circular reasoning either by
9670 // introducing a cutoff below.
9671 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9672 return ChangeStatus::UNCHANGED;
9673 if (++NumChanges > MaxNumChanges) {
9674 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9675 << " but only " << MaxNumChanges
9676 << " are allowed to avoid cyclic reasoning.");
9677 return indicatePessimisticFixpoint();
9678 }
9679 return ChangeStatus::CHANGED;
9680 }
9681
9682 /// See AbstractAttribute::trackStatistics()
9683 void trackStatistics() const override {
9685 }
9686
9687 /// Tracker to bail after too many widening steps of the constant range.
9688 int NumChanges = 0;
9689
9690 /// Upper bound for the number of allowed changes (=widening steps) for the
9691 /// constant range before we give up.
9692 static constexpr int MaxNumChanges = 5;
9693};
9694
9695struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9696 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9697 : AAValueConstantRangeImpl(IRP, A) {}
9698
9699 /// See AbstractAttribute::initialize(...).
9700 ChangeStatus updateImpl(Attributor &A) override {
9701 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9702 "not be called");
9703 }
9704
9705 /// See AbstractAttribute::trackStatistics()
9706 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9707};
9708
9709struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9710 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9711 : AAValueConstantRangeFunction(IRP, A) {}
9712
9713 /// See AbstractAttribute::trackStatistics()
9714 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9715};
9716
9717struct AAValueConstantRangeCallSiteReturned
9718 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9719 AAValueConstantRangeImpl::StateType,
9720 /* IntroduceCallBaseContext */ true> {
9721 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9722 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9723 AAValueConstantRangeImpl::StateType,
9724 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9725
9726 /// See AbstractAttribute::initialize(...).
9727 void initialize(Attributor &A) override {
9728 // If it is a call instruction with range attribute, use the range.
9729 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9730 if (std::optional<ConstantRange> Range = CI->getRange())
9731 intersectKnown(*Range);
9732 }
9733
9734 AAValueConstantRangeImpl::initialize(A);
9735 }
9736
9737 /// See AbstractAttribute::trackStatistics()
9738 void trackStatistics() const override {
9739 STATS_DECLTRACK_CSRET_ATTR(value_range)
9740 }
9741};
9742struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9743 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9744 : AAValueConstantRangeFloating(IRP, A) {}
9745
9746 /// See AbstractAttribute::manifest()
9747 ChangeStatus manifest(Attributor &A) override {
9748 return ChangeStatus::UNCHANGED;
9749 }
9750
9751 /// See AbstractAttribute::trackStatistics()
9752 void trackStatistics() const override {
9753 STATS_DECLTRACK_CSARG_ATTR(value_range)
9754 }
9755};
9756} // namespace
9757
9758/// ------------------ Potential Values Attribute -------------------------
9759
9760namespace {
9761struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9762 using StateType = PotentialConstantIntValuesState;
9763
9764 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9765 : AAPotentialConstantValues(IRP, A) {}
9766
9767 /// See AbstractAttribute::initialize(..).
9768 void initialize(Attributor &A) override {
9769 if (A.hasSimplificationCallback(getIRPosition()))
9770 indicatePessimisticFixpoint();
9771 else
9772 AAPotentialConstantValues::initialize(A);
9773 }
9774
9775 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9776 bool &ContainsUndef, bool ForSelf) {
9778 bool UsedAssumedInformation = false;
9779 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9780 UsedAssumedInformation)) {
9781 // Avoid recursion when the caller is computing constant values for this
9782 // IRP itself.
9783 if (ForSelf)
9784 return false;
9785 if (!IRP.getAssociatedType()->isIntegerTy())
9786 return false;
9787 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9788 *this, IRP, DepClassTy::REQUIRED);
9789 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9790 return false;
9791 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9792 S = PotentialValuesAA->getState().getAssumedSet();
9793 return true;
9794 }
9795
9796 // Copy all the constant values, except UndefValue. ContainsUndef is true
9797 // iff Values contains only UndefValue instances. If there are other known
9798 // constants, then UndefValue is dropped.
9799 ContainsUndef = false;
9800 for (auto &It : Values) {
9801 if (isa<UndefValue>(It.getValue())) {
9802 ContainsUndef = true;
9803 continue;
9804 }
9805 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9806 if (!CI)
9807 return false;
9808 S.insert(CI->getValue());
9809 }
9810 ContainsUndef &= S.empty();
9811
9812 return true;
9813 }
9814
9815 /// See AbstractAttribute::getAsStr().
9816 const std::string getAsStr(Attributor *A) const override {
9817 std::string Str;
9818 llvm::raw_string_ostream OS(Str);
9819 OS << getState();
9820 return Str;
9821 }
9822
9823 /// See AbstractAttribute::updateImpl(...).
9824 ChangeStatus updateImpl(Attributor &A) override {
9825 return indicatePessimisticFixpoint();
9826 }
9827};
9828
9829struct AAPotentialConstantValuesArgument final
9830 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9831 AAPotentialConstantValuesImpl,
9832 PotentialConstantIntValuesState> {
9833 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9834 AAPotentialConstantValuesImpl,
9836 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9837 : Base(IRP, A) {}
9838
9839 /// See AbstractAttribute::trackStatistics()
9840 void trackStatistics() const override {
9841 STATS_DECLTRACK_ARG_ATTR(potential_values)
9842 }
9843};
9844
9845struct AAPotentialConstantValuesReturned
9846 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9847 AAPotentialConstantValuesImpl> {
9848 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9849 AAPotentialConstantValuesImpl>;
9850 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9851 : Base(IRP, A) {}
9852
9853 void initialize(Attributor &A) override {
9854 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9855 indicatePessimisticFixpoint();
9856 Base::initialize(A);
9857 }
9858
9859 /// See AbstractAttribute::trackStatistics()
9860 void trackStatistics() const override {
9861 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9862 }
9863};
9864
9865struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9866 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9867 : AAPotentialConstantValuesImpl(IRP, A) {}
9868
9869 /// See AbstractAttribute::initialize(..).
9870 void initialize(Attributor &A) override {
9871 AAPotentialConstantValuesImpl::initialize(A);
9872 if (isAtFixpoint())
9873 return;
9874
9875 Value &V = getAssociatedValue();
9876
9877 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9878 unionAssumed(C->getValue());
9879 indicateOptimisticFixpoint();
9880 return;
9881 }
9882
9883 if (isa<UndefValue>(&V)) {
9884 unionAssumedWithUndef();
9885 indicateOptimisticFixpoint();
9886 return;
9887 }
9888
9889 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9890 return;
9891
9892 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9893 return;
9894
9895 indicatePessimisticFixpoint();
9896
9897 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9898 << getAssociatedValue() << "\n");
9899 }
9900
9901 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9902 const APInt &RHS) {
9903 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9904 }
9905
9906 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9907 uint32_t ResultBitWidth) {
9908 Instruction::CastOps CastOp = CI->getOpcode();
9909 switch (CastOp) {
9910 default:
9911 llvm_unreachable("unsupported or not integer cast");
9912 case Instruction::Trunc:
9913 return Src.trunc(ResultBitWidth);
9914 case Instruction::SExt:
9915 return Src.sext(ResultBitWidth);
9916 case Instruction::ZExt:
9917 return Src.zext(ResultBitWidth);
9918 case Instruction::BitCast:
9919 return Src;
9920 }
9921 }
9922
9923 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9924 const APInt &LHS, const APInt &RHS,
9925 bool &SkipOperation, bool &Unsupported) {
9926 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9927 // Unsupported is set to true when the binary operator is not supported.
9928 // SkipOperation is set to true when UB occur with the given operand pair
9929 // (LHS, RHS).
9930 // TODO: we should look at nsw and nuw keywords to handle operations
9931 // that create poison or undef value.
9932 switch (BinOpcode) {
9933 default:
9934 Unsupported = true;
9935 return LHS;
9936 case Instruction::Add:
9937 return LHS + RHS;
9938 case Instruction::Sub:
9939 return LHS - RHS;
9940 case Instruction::Mul:
9941 return LHS * RHS;
9942 case Instruction::UDiv:
9943 if (RHS.isZero()) {
9944 SkipOperation = true;
9945 return LHS;
9946 }
9947 return LHS.udiv(RHS);
9948 case Instruction::SDiv:
9949 if (RHS.isZero()) {
9950 SkipOperation = true;
9951 return LHS;
9952 }
9953 return LHS.sdiv(RHS);
9954 case Instruction::URem:
9955 if (RHS.isZero()) {
9956 SkipOperation = true;
9957 return LHS;
9958 }
9959 return LHS.urem(RHS);
9960 case Instruction::SRem:
9961 if (RHS.isZero()) {
9962 SkipOperation = true;
9963 return LHS;
9964 }
9965 return LHS.srem(RHS);
9966 case Instruction::Shl:
9967 return LHS.shl(RHS);
9968 case Instruction::LShr:
9969 return LHS.lshr(RHS);
9970 case Instruction::AShr:
9971 return LHS.ashr(RHS);
9972 case Instruction::And:
9973 return LHS & RHS;
9974 case Instruction::Or:
9975 return LHS | RHS;
9976 case Instruction::Xor:
9977 return LHS ^ RHS;
9978 }
9979 }
9980
9981 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9982 const APInt &LHS, const APInt &RHS) {
9983 bool SkipOperation = false;
9984 bool Unsupported = false;
9985 APInt Result =
9986 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9987 if (Unsupported)
9988 return false;
9989 // If SkipOperation is true, we can ignore this operand pair (L, R).
9990 if (!SkipOperation)
9991 unionAssumed(Result);
9992 return isValidState();
9993 }
9994
9995 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9996 auto AssumedBefore = getAssumed();
9997 Value *LHS = ICI->getOperand(0);
9998 Value *RHS = ICI->getOperand(1);
9999
10000 bool LHSContainsUndef = false, RHSContainsUndef = false;
10001 SetTy LHSAAPVS, RHSAAPVS;
10002 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10003 LHSContainsUndef, /* ForSelf */ false) ||
10004 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10005 RHSContainsUndef, /* ForSelf */ false))
10006 return indicatePessimisticFixpoint();
10007
10008 // TODO: make use of undef flag to limit potential values aggressively.
10009 bool MaybeTrue = false, MaybeFalse = false;
10010 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
10011 if (LHSContainsUndef && RHSContainsUndef) {
10012 // The result of any comparison between undefs can be soundly replaced
10013 // with undef.
10014 unionAssumedWithUndef();
10015 } else if (LHSContainsUndef) {
10016 for (const APInt &R : RHSAAPVS) {
10017 bool CmpResult = calculateICmpInst(ICI, Zero, R);
10018 MaybeTrue |= CmpResult;
10019 MaybeFalse |= !CmpResult;
10020 if (MaybeTrue & MaybeFalse)
10021 return indicatePessimisticFixpoint();
10022 }
10023 } else if (RHSContainsUndef) {
10024 for (const APInt &L : LHSAAPVS) {
10025 bool CmpResult = calculateICmpInst(ICI, L, Zero);
10026 MaybeTrue |= CmpResult;
10027 MaybeFalse |= !CmpResult;
10028 if (MaybeTrue & MaybeFalse)
10029 return indicatePessimisticFixpoint();
10030 }
10031 } else {
10032 for (const APInt &L : LHSAAPVS) {
10033 for (const APInt &R : RHSAAPVS) {
10034 bool CmpResult = calculateICmpInst(ICI, L, R);
10035 MaybeTrue |= CmpResult;
10036 MaybeFalse |= !CmpResult;
10037 if (MaybeTrue & MaybeFalse)
10038 return indicatePessimisticFixpoint();
10039 }
10040 }
10041 }
10042 if (MaybeTrue)
10043 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
10044 if (MaybeFalse)
10045 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
10046 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10047 : ChangeStatus::CHANGED;
10048 }
10049
10050 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
10051 auto AssumedBefore = getAssumed();
10052 Value *LHS = SI->getTrueValue();
10053 Value *RHS = SI->getFalseValue();
10054
10055 bool UsedAssumedInformation = false;
10056 std::optional<Constant *> C = A.getAssumedConstant(
10057 *SI->getCondition(), *this, UsedAssumedInformation);
10058
10059 // Check if we only need one operand.
10060 bool OnlyLeft = false, OnlyRight = false;
10061 if (C && *C && (*C)->isOneValue())
10062 OnlyLeft = true;
10063 else if (C && *C && (*C)->isNullValue())
10064 OnlyRight = true;
10065
10066 bool LHSContainsUndef = false, RHSContainsUndef = false;
10067 SetTy LHSAAPVS, RHSAAPVS;
10068 if (!OnlyRight &&
10069 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10070 LHSContainsUndef, /* ForSelf */ false))
10071 return indicatePessimisticFixpoint();
10072
10073 if (!OnlyLeft &&
10074 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10075 RHSContainsUndef, /* ForSelf */ false))
10076 return indicatePessimisticFixpoint();
10077
10078 if (OnlyLeft || OnlyRight) {
10079 // select (true/false), lhs, rhs
10080 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
10081 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
10082
10083 if (Undef)
10084 unionAssumedWithUndef();
10085 else {
10086 for (const auto &It : *OpAA)
10087 unionAssumed(It);
10088 }
10089
10090 } else if (LHSContainsUndef && RHSContainsUndef) {
10091 // select i1 *, undef , undef => undef
10092 unionAssumedWithUndef();
10093 } else {
10094 for (const auto &It : LHSAAPVS)
10095 unionAssumed(It);
10096 for (const auto &It : RHSAAPVS)
10097 unionAssumed(It);
10098 }
10099 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10100 : ChangeStatus::CHANGED;
10101 }
10102
10103 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10104 auto AssumedBefore = getAssumed();
10105 if (!CI->isIntegerCast())
10106 return indicatePessimisticFixpoint();
10107 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10108 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10109 Value *Src = CI->getOperand(0);
10110
10111 bool SrcContainsUndef = false;
10112 SetTy SrcPVS;
10113 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10114 SrcContainsUndef, /* ForSelf */ false))
10115 return indicatePessimisticFixpoint();
10116
10117 if (SrcContainsUndef)
10118 unionAssumedWithUndef();
10119 else {
10120 for (const APInt &S : SrcPVS) {
10121 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10122 unionAssumed(T);
10123 }
10124 }
10125 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10126 : ChangeStatus::CHANGED;
10127 }
10128
10129 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10130 auto AssumedBefore = getAssumed();
10131 Value *LHS = BinOp->getOperand(0);
10132 Value *RHS = BinOp->getOperand(1);
10133
10134 bool LHSContainsUndef = false, RHSContainsUndef = false;
10135 SetTy LHSAAPVS, RHSAAPVS;
10136 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10137 LHSContainsUndef, /* ForSelf */ false) ||
10138 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10139 RHSContainsUndef, /* ForSelf */ false))
10140 return indicatePessimisticFixpoint();
10141
10142 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10143
10144 // TODO: make use of undef flag to limit potential values aggressively.
10145 if (LHSContainsUndef && RHSContainsUndef) {
10146 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10147 return indicatePessimisticFixpoint();
10148 } else if (LHSContainsUndef) {
10149 for (const APInt &R : RHSAAPVS) {
10150 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10151 return indicatePessimisticFixpoint();
10152 }
10153 } else if (RHSContainsUndef) {
10154 for (const APInt &L : LHSAAPVS) {
10155 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10156 return indicatePessimisticFixpoint();
10157 }
10158 } else {
10159 for (const APInt &L : LHSAAPVS) {
10160 for (const APInt &R : RHSAAPVS) {
10161 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10162 return indicatePessimisticFixpoint();
10163 }
10164 }
10165 }
10166 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10167 : ChangeStatus::CHANGED;
10168 }
10169
10170 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10171 auto AssumedBefore = getAssumed();
10172 SetTy Incoming;
10173 bool ContainsUndef;
10174 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10175 ContainsUndef, /* ForSelf */ true))
10176 return indicatePessimisticFixpoint();
10177 if (ContainsUndef) {
10178 unionAssumedWithUndef();
10179 } else {
10180 for (const auto &It : Incoming)
10181 unionAssumed(It);
10182 }
10183 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10184 : ChangeStatus::CHANGED;
10185 }
10186
10187 /// See AbstractAttribute::updateImpl(...).
10188 ChangeStatus updateImpl(Attributor &A) override {
10189 Value &V = getAssociatedValue();
10191
10192 if (auto *ICI = dyn_cast<ICmpInst>(I))
10193 return updateWithICmpInst(A, ICI);
10194
10195 if (auto *SI = dyn_cast<SelectInst>(I))
10196 return updateWithSelectInst(A, SI);
10197
10198 if (auto *CI = dyn_cast<CastInst>(I))
10199 return updateWithCastInst(A, CI);
10200
10201 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10202 return updateWithBinaryOperator(A, BinOp);
10203
10204 if (isa<PHINode>(I) || isa<LoadInst>(I))
10205 return updateWithInstruction(A, I);
10206
10207 return indicatePessimisticFixpoint();
10208 }
10209
10210 /// See AbstractAttribute::trackStatistics()
10211 void trackStatistics() const override {
10212 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10213 }
10214};
10215
10216struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10217 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10218 : AAPotentialConstantValuesImpl(IRP, A) {}
10219
10220 /// See AbstractAttribute::initialize(...).
10221 ChangeStatus updateImpl(Attributor &A) override {
10223 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10224 "not be called");
10225 }
10226
10227 /// See AbstractAttribute::trackStatistics()
10228 void trackStatistics() const override {
10229 STATS_DECLTRACK_FN_ATTR(potential_values)
10230 }
10231};
10232
10233struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10234 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10235 : AAPotentialConstantValuesFunction(IRP, A) {}
10236
10237 /// See AbstractAttribute::trackStatistics()
10238 void trackStatistics() const override {
10239 STATS_DECLTRACK_CS_ATTR(potential_values)
10240 }
10241};
10242
10243struct AAPotentialConstantValuesCallSiteReturned
10244 : AACalleeToCallSite<AAPotentialConstantValues,
10245 AAPotentialConstantValuesImpl> {
10246 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10247 Attributor &A)
10248 : AACalleeToCallSite<AAPotentialConstantValues,
10249 AAPotentialConstantValuesImpl>(IRP, A) {}
10250
10251 /// See AbstractAttribute::trackStatistics()
10252 void trackStatistics() const override {
10253 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10254 }
10255};
10256
10257struct AAPotentialConstantValuesCallSiteArgument
10258 : AAPotentialConstantValuesFloating {
10259 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10260 Attributor &A)
10261 : AAPotentialConstantValuesFloating(IRP, A) {}
10262
10263 /// See AbstractAttribute::initialize(..).
10264 void initialize(Attributor &A) override {
10265 AAPotentialConstantValuesImpl::initialize(A);
10266 if (isAtFixpoint())
10267 return;
10268
10269 Value &V = getAssociatedValue();
10270
10271 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10272 unionAssumed(C->getValue());
10273 indicateOptimisticFixpoint();
10274 return;
10275 }
10276
10277 if (isa<UndefValue>(&V)) {
10278 unionAssumedWithUndef();
10279 indicateOptimisticFixpoint();
10280 return;
10281 }
10282 }
10283
10284 /// See AbstractAttribute::updateImpl(...).
10285 ChangeStatus updateImpl(Attributor &A) override {
10286 Value &V = getAssociatedValue();
10287 auto AssumedBefore = getAssumed();
10288 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10289 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10290 if (!AA)
10291 return indicatePessimisticFixpoint();
10292 const auto &S = AA->getAssumed();
10293 unionAssumed(S);
10294 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10295 : ChangeStatus::CHANGED;
10296 }
10297
10298 /// See AbstractAttribute::trackStatistics()
10299 void trackStatistics() const override {
10300 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10301 }
10302};
10303} // namespace
10304
10305/// ------------------------ NoUndef Attribute ---------------------------------
10307 Attribute::AttrKind ImpliedAttributeKind,
10308 bool IgnoreSubsumingPositions) {
10309 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10310 "Unexpected attribute kind");
10311 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10312 Attribute::NoUndef))
10313 return true;
10314
10315 Value &Val = IRP.getAssociatedValue();
10318 LLVMContext &Ctx = Val.getContext();
10319 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10320 return true;
10321 }
10322
10323 return false;
10324}
10325
10326namespace {
10327struct AANoUndefImpl : AANoUndef {
10328 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10329
10330 /// See AbstractAttribute::initialize(...).
10331 void initialize(Attributor &A) override {
10332 Value &V = getAssociatedValue();
10333 if (isa<UndefValue>(V))
10334 indicatePessimisticFixpoint();
10335 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10336 }
10337
10338 /// See followUsesInMBEC
10339 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10340 AANoUndef::StateType &State) {
10341 const Value *UseV = U->get();
10342 const DominatorTree *DT = nullptr;
10343 AssumptionCache *AC = nullptr;
10344 InformationCache &InfoCache = A.getInfoCache();
10345 if (Function *F = getAnchorScope()) {
10346 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10347 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10348 }
10349 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10350 bool TrackUse = false;
10351 // Track use for instructions which must produce undef or poison bits when
10352 // at least one operand contains such bits.
10354 TrackUse = true;
10355 return TrackUse;
10356 }
10357
10358 /// See AbstractAttribute::getAsStr().
10359 const std::string getAsStr(Attributor *A) const override {
10360 return getAssumed() ? "noundef" : "may-undef-or-poison";
10361 }
10362
10363 ChangeStatus manifest(Attributor &A) override {
10364 // We don't manifest noundef attribute for dead positions because the
10365 // associated values with dead positions would be replaced with undef
10366 // values.
10367 bool UsedAssumedInformation = false;
10368 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10369 UsedAssumedInformation))
10370 return ChangeStatus::UNCHANGED;
10371 // A position whose simplified value does not have any value is
10372 // considered to be dead. We don't manifest noundef in such positions for
10373 // the same reason above.
10374 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10376 .has_value())
10377 return ChangeStatus::UNCHANGED;
10378 return AANoUndef::manifest(A);
10379 }
10380};
10381
10382struct AANoUndefFloating : public AANoUndefImpl {
10383 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10384 : AANoUndefImpl(IRP, A) {}
10385
10386 /// See AbstractAttribute::initialize(...).
10387 void initialize(Attributor &A) override {
10388 AANoUndefImpl::initialize(A);
10389 if (!getState().isAtFixpoint() && getAnchorScope() &&
10390 !getAnchorScope()->isDeclaration())
10391 if (Instruction *CtxI = getCtxI())
10392 followUsesInMBEC(*this, A, getState(), *CtxI);
10393 }
10394
10395 /// See AbstractAttribute::updateImpl(...).
10396 ChangeStatus updateImpl(Attributor &A) override {
10397 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10398 bool IsKnownNoUndef;
10400 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10401 };
10402
10403 bool Stripped;
10404 bool UsedAssumedInformation = false;
10405 Value *AssociatedValue = &getAssociatedValue();
10407 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10408 AA::AnyScope, UsedAssumedInformation))
10409 Stripped = false;
10410 else
10411 Stripped =
10412 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10413
10414 if (!Stripped) {
10415 // If we haven't stripped anything we might still be able to use a
10416 // different AA, but only if the IRP changes. Effectively when we
10417 // interpret this not as a call site value but as a floating/argument
10418 // value.
10419 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10420 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10421 return indicatePessimisticFixpoint();
10422 return ChangeStatus::UNCHANGED;
10423 }
10424
10425 for (const auto &VAC : Values)
10426 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10427 return indicatePessimisticFixpoint();
10428
10429 return ChangeStatus::UNCHANGED;
10430 }
10431
10432 /// See AbstractAttribute::trackStatistics()
10433 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10434};
10435
10436struct AANoUndefReturned final
10437 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10438 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10439 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10440
10441 /// See AbstractAttribute::trackStatistics()
10442 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10443};
10444
10445struct AANoUndefArgument final
10446 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10447 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10448 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10449
10450 /// See AbstractAttribute::trackStatistics()
10451 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10452};
10453
10454struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10455 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10456 : AANoUndefFloating(IRP, A) {}
10457
10458 /// See AbstractAttribute::trackStatistics()
10459 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10460};
10461
10462struct AANoUndefCallSiteReturned final
10463 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10464 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10465 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10466
10467 /// See AbstractAttribute::trackStatistics()
10468 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10469};
10470
10471/// ------------------------ NoFPClass Attribute -------------------------------
10472
10473struct AANoFPClassImpl : AANoFPClass {
10474 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10475
10476 void initialize(Attributor &A) override {
10477 const IRPosition &IRP = getIRPosition();
10478
10479 Value &V = IRP.getAssociatedValue();
10480 if (isa<UndefValue>(V)) {
10481 indicateOptimisticFixpoint();
10482 return;
10483 }
10484
10486 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10487 for (const auto &Attr : Attrs) {
10488 addKnownBits(Attr.getNoFPClass());
10489 }
10490
10491 Instruction *CtxI = getCtxI();
10492
10493 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10494 const DataLayout &DL = A.getDataLayout();
10495 InformationCache &InfoCache = A.getInfoCache();
10496
10497 const DominatorTree *DT = nullptr;
10498 AssumptionCache *AC = nullptr;
10499 const TargetLibraryInfo *TLI = nullptr;
10500 Function *F = getAnchorScope();
10501 if (F) {
10502 TLI = InfoCache.getTargetLibraryInfoForFunction(*F);
10503 if (!F->isDeclaration()) {
10504 DT =
10505 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
10506 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
10507 }
10508 }
10509
10510 SimplifyQuery Q(DL, TLI, DT, AC, CtxI);
10511
10512 KnownFPClass KnownFPClass = computeKnownFPClass(&V, fcAllFlags, Q);
10513 addKnownBits(~KnownFPClass.KnownFPClasses);
10514 }
10515
10516 if (CtxI)
10517 followUsesInMBEC(*this, A, getState(), *CtxI);
10518 }
10519
10520 /// See followUsesInMBEC
10521 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10522 AANoFPClass::StateType &State) {
10523 // TODO: Determine what instructions can be looked through.
10524 auto *CB = dyn_cast<CallBase>(I);
10525 if (!CB)
10526 return false;
10527
10528 if (!CB->isArgOperand(U))
10529 return false;
10530
10531 unsigned ArgNo = CB->getArgOperandNo(U);
10532 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10533 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10534 State.addKnownBits(NoFPAA->getState().getKnown());
10535 return false;
10536 }
10537
10538 const std::string getAsStr(Attributor *A) const override {
10539 std::string Result = "nofpclass";
10540 raw_string_ostream OS(Result);
10541 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10542 return Result;
10543 }
10544
10545 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10546 SmallVectorImpl<Attribute> &Attrs) const override {
10547 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10548 }
10549};
10550
10551struct AANoFPClassFloating : public AANoFPClassImpl {
10552 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10553 : AANoFPClassImpl(IRP, A) {}
10554
10555 /// See AbstractAttribute::updateImpl(...).
10556 ChangeStatus updateImpl(Attributor &A) override {
10558 bool UsedAssumedInformation = false;
10559 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10560 AA::AnyScope, UsedAssumedInformation)) {
10561 Values.push_back({getAssociatedValue(), getCtxI()});
10562 }
10563
10564 StateType T;
10565 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10566 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10567 DepClassTy::REQUIRED);
10568 if (!AA || this == AA) {
10569 T.indicatePessimisticFixpoint();
10570 } else {
10571 const AANoFPClass::StateType &S =
10572 static_cast<const AANoFPClass::StateType &>(AA->getState());
10573 T ^= S;
10574 }
10575 return T.isValidState();
10576 };
10577
10578 for (const auto &VAC : Values)
10579 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10580 return indicatePessimisticFixpoint();
10581
10582 return clampStateAndIndicateChange(getState(), T);
10583 }
10584
10585 /// See AbstractAttribute::trackStatistics()
10586 void trackStatistics() const override {
10588 }
10589};
10590
10591struct AANoFPClassReturned final
10592 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10593 AANoFPClassImpl::StateType, false,
10594 Attribute::None, false> {
10595 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10596 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10597 AANoFPClassImpl::StateType, false,
10598 Attribute::None, false>(IRP, A) {}
10599
10600 /// See AbstractAttribute::trackStatistics()
10601 void trackStatistics() const override {
10603 }
10604};
10605
10606struct AANoFPClassArgument final
10607 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10608 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10609 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10610
10611 /// See AbstractAttribute::trackStatistics()
10612 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10613};
10614
10615struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10616 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10617 : AANoFPClassFloating(IRP, A) {}
10618
10619 /// See AbstractAttribute::trackStatistics()
10620 void trackStatistics() const override {
10622 }
10623};
10624
10625struct AANoFPClassCallSiteReturned final
10626 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10627 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10628 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10629
10630 /// See AbstractAttribute::trackStatistics()
10631 void trackStatistics() const override {
10633 }
10634};
10635
10636struct AACallEdgesImpl : public AACallEdges {
10637 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10638
10639 const SetVector<Function *> &getOptimisticEdges() const override {
10640 return CalledFunctions;
10641 }
10642
10643 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10644
10645 bool hasNonAsmUnknownCallee() const override {
10646 return HasUnknownCalleeNonAsm;
10647 }
10648
10649 const std::string getAsStr(Attributor *A) const override {
10650 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10651 std::to_string(CalledFunctions.size()) + "]";
10652 }
10653
10654 void trackStatistics() const override {}
10655
10656protected:
10657 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10658 if (CalledFunctions.insert(Fn)) {
10659 Change = ChangeStatus::CHANGED;
10660 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10661 << "\n");
10662 }
10663 }
10664
10665 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10666 if (!HasUnknownCallee)
10667 Change = ChangeStatus::CHANGED;
10668 if (NonAsm && !HasUnknownCalleeNonAsm)
10669 Change = ChangeStatus::CHANGED;
10670 HasUnknownCalleeNonAsm |= NonAsm;
10671 HasUnknownCallee = true;
10672 }
10673
10674private:
10675 /// Optimistic set of functions that might be called by this position.
10676 SetVector<Function *> CalledFunctions;
10677
10678 /// Is there any call with a unknown callee.
10679 bool HasUnknownCallee = false;
10680
10681 /// Is there any call with a unknown callee, excluding any inline asm.
10682 bool HasUnknownCalleeNonAsm = false;
10683};
10684
10685struct AACallEdgesCallSite : public AACallEdgesImpl {
10686 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10687 : AACallEdgesImpl(IRP, A) {}
10688 /// See AbstractAttribute::updateImpl(...).
10689 ChangeStatus updateImpl(Attributor &A) override {
10690 ChangeStatus Change = ChangeStatus::UNCHANGED;
10691
10692 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10693 if (Function *Fn = dyn_cast<Function>(&V)) {
10694 addCalledFunction(Fn, Change);
10695 } else {
10696 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10697 setHasUnknownCallee(true, Change);
10698 }
10699
10700 // Explore all values.
10701 return true;
10702 };
10703
10705 // Process any value that we might call.
10706 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10707 if (isa<Constant>(V)) {
10708 VisitValue(*V, CtxI);
10709 return;
10710 }
10711
10712 bool UsedAssumedInformation = false;
10713 Values.clear();
10714 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10715 AA::AnyScope, UsedAssumedInformation)) {
10716 Values.push_back({*V, CtxI});
10717 }
10718 for (auto &VAC : Values)
10719 VisitValue(*VAC.getValue(), VAC.getCtxI());
10720 };
10721
10722 CallBase *CB = cast<CallBase>(getCtxI());
10723
10724 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10725 if (IA->hasSideEffects() &&
10726 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10727 !hasAssumption(*CB, "ompx_no_call_asm")) {
10728 setHasUnknownCallee(false, Change);
10729 }
10730 return Change;
10731 }
10732
10733 if (CB->isIndirectCall())
10734 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10735 *this, getIRPosition(), DepClassTy::OPTIONAL))
10736 if (IndirectCallAA->foreachCallee(
10737 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10738 return Change;
10739
10740 // The most simple case.
10741 ProcessCalledOperand(CB->getCalledOperand(), CB);
10742
10743 // Process callback functions.
10744 SmallVector<const Use *, 4u> CallbackUses;
10745 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10746 for (const Use *U : CallbackUses)
10747 ProcessCalledOperand(U->get(), CB);
10748
10749 return Change;
10750 }
10751};
10752
10753struct AACallEdgesFunction : public AACallEdgesImpl {
10754 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10755 : AACallEdgesImpl(IRP, A) {}
10756
10757 /// See AbstractAttribute::updateImpl(...).
10758 ChangeStatus updateImpl(Attributor &A) override {
10759 ChangeStatus Change = ChangeStatus::UNCHANGED;
10760
10761 auto ProcessCallInst = [&](Instruction &Inst) {
10762 CallBase &CB = cast<CallBase>(Inst);
10763
10764 auto *CBEdges = A.getAAFor<AACallEdges>(
10765 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10766 if (!CBEdges)
10767 return false;
10768 if (CBEdges->hasNonAsmUnknownCallee())
10769 setHasUnknownCallee(true, Change);
10770 if (CBEdges->hasUnknownCallee())
10771 setHasUnknownCallee(false, Change);
10772
10773 for (Function *F : CBEdges->getOptimisticEdges())
10774 addCalledFunction(F, Change);
10775
10776 return true;
10777 };
10778
10779 // Visit all callable instructions.
10780 bool UsedAssumedInformation = false;
10781 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10782 UsedAssumedInformation,
10783 /* CheckBBLivenessOnly */ true)) {
10784 // If we haven't looked at all call like instructions, assume that there
10785 // are unknown callees.
10786 setHasUnknownCallee(true, Change);
10787 }
10788
10789 return Change;
10790 }
10791};
10792
10793/// -------------------AAInterFnReachability Attribute--------------------------
10794
10795struct AAInterFnReachabilityFunction
10796 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10797 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10798 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10799 : Base(IRP, A) {}
10800
10801 bool instructionCanReach(
10802 Attributor &A, const Instruction &From, const Function &To,
10803 const AA::InstExclusionSetTy *ExclusionSet) const override {
10804 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10805 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10806
10807 RQITy StackRQI(A, From, To, ExclusionSet, false);
10808 RQITy::Reachable Result;
10809 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10810 return NonConstThis->isReachableImpl(A, StackRQI,
10811 /*IsTemporaryRQI=*/true);
10812 return Result == RQITy::Reachable::Yes;
10813 }
10814
10815 bool isReachableImpl(Attributor &A, RQITy &RQI,
10816 bool IsTemporaryRQI) override {
10817 const Instruction *EntryI =
10818 &RQI.From->getFunction()->getEntryBlock().front();
10819 if (EntryI != RQI.From &&
10820 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10821 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10822 IsTemporaryRQI);
10823
10824 auto CheckReachableCallBase = [&](CallBase *CB) {
10825 auto *CBEdges = A.getAAFor<AACallEdges>(
10826 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10827 if (!CBEdges || !CBEdges->getState().isValidState())
10828 return false;
10829 // TODO Check To backwards in this case.
10830 if (CBEdges->hasUnknownCallee())
10831 return false;
10832
10833 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10834 if (Fn == RQI.To)
10835 return false;
10836
10837 if (Fn->isDeclaration()) {
10838 if (Fn->hasFnAttribute(Attribute::NoCallback))
10839 continue;
10840 // TODO Check To backwards in this case.
10841 return false;
10842 }
10843
10844 if (Fn == getAnchorScope()) {
10845 if (EntryI == RQI.From)
10846 continue;
10847 return false;
10848 }
10849
10850 const AAInterFnReachability *InterFnReachability =
10851 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10852 DepClassTy::OPTIONAL);
10853
10854 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10855 if (!InterFnReachability ||
10856 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10857 RQI.ExclusionSet))
10858 return false;
10859 }
10860 return true;
10861 };
10862
10863 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10864 *this, IRPosition::function(*RQI.From->getFunction()),
10865 DepClassTy::OPTIONAL);
10866
10867 // Determine call like instructions that we can reach from the inst.
10868 auto CheckCallBase = [&](Instruction &CBInst) {
10869 // There are usually less nodes in the call graph, check inter function
10870 // reachability first.
10871 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10872 return true;
10873 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10874 A, *RQI.From, CBInst, RQI.ExclusionSet);
10875 };
10876
10877 bool UsedExclusionSet = /* conservative */ true;
10878 bool UsedAssumedInformation = false;
10879 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10880 UsedAssumedInformation,
10881 /* CheckBBLivenessOnly */ true))
10882 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10883 IsTemporaryRQI);
10884
10885 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10886 IsTemporaryRQI);
10887 }
10888
10889 void trackStatistics() const override {}
10890};
10891} // namespace
10892
10893template <typename AAType>
10894static std::optional<Constant *>
10896 const IRPosition &IRP, Type &Ty) {
10897 if (!Ty.isIntegerTy())
10898 return nullptr;
10899
10900 // This will also pass the call base context.
10901 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10902 if (!AA)
10903 return nullptr;
10904
10905 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10906
10907 if (!COpt.has_value()) {
10908 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10909 return std::nullopt;
10910 }
10911 if (auto *C = *COpt) {
10912 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10913 return C;
10914 }
10915 return nullptr;
10916}
10917
10919 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10921 Type &Ty = *IRP.getAssociatedType();
10922 std::optional<Value *> V;
10923 for (auto &It : Values) {
10924 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10925 if (V.has_value() && !*V)
10926 break;
10927 }
10928 if (!V.has_value())
10929 return UndefValue::get(&Ty);
10930 return *V;
10931}
10932
10933namespace {
10934struct AAPotentialValuesImpl : AAPotentialValues {
10935 using StateType = PotentialLLVMValuesState;
10936
10937 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10938 : AAPotentialValues(IRP, A) {}
10939
10940 /// See AbstractAttribute::initialize(..).
10941 void initialize(Attributor &A) override {
10942 if (A.hasSimplificationCallback(getIRPosition())) {
10943 indicatePessimisticFixpoint();
10944 return;
10945 }
10946 Value *Stripped = getAssociatedValue().stripPointerCasts();
10947 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10948 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10949 getAnchorScope());
10950 indicateOptimisticFixpoint();
10951 return;
10952 }
10953 AAPotentialValues::initialize(A);
10954 }
10955
10956 /// See AbstractAttribute::getAsStr().
10957 const std::string getAsStr(Attributor *A) const override {
10958 std::string Str;
10959 llvm::raw_string_ostream OS(Str);
10960 OS << getState();
10961 return Str;
10962 }
10963
10964 template <typename AAType>
10965 static std::optional<Value *> askOtherAA(Attributor &A,
10966 const AbstractAttribute &AA,
10967 const IRPosition &IRP, Type &Ty) {
10969 return &IRP.getAssociatedValue();
10970 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10971 if (!C)
10972 return std::nullopt;
10973 if (*C)
10974 if (auto *CC = AA::getWithType(**C, Ty))
10975 return CC;
10976 return nullptr;
10977 }
10978
10979 virtual void addValue(Attributor &A, StateType &State, Value &V,
10980 const Instruction *CtxI, AA::ValueScope S,
10981 Function *AnchorScope) const {
10982
10983 IRPosition ValIRP = IRPosition::value(V);
10984 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10985 for (const auto &U : CB->args()) {
10986 if (U.get() != &V)
10987 continue;
10988 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10989 break;
10990 }
10991 }
10992
10993 Value *VPtr = &V;
10994 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10995 Type &Ty = *getAssociatedType();
10996 std::optional<Value *> SimpleV =
10997 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10998 if (SimpleV.has_value() && !*SimpleV) {
10999 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
11000 *this, ValIRP, DepClassTy::OPTIONAL);
11001 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
11002 for (const auto &It : PotentialConstantsAA->getAssumedSet())
11003 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
11004 if (PotentialConstantsAA->undefIsContained())
11005 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
11006 return;
11007 }
11008 }
11009 if (!SimpleV.has_value())
11010 return;
11011
11012 if (*SimpleV)
11013 VPtr = *SimpleV;
11014 }
11015
11016 if (isa<ConstantInt>(VPtr))
11017 CtxI = nullptr;
11018 if (!AA::isValidInScope(*VPtr, AnchorScope))
11020
11021 State.unionAssumed({{*VPtr, CtxI}, S});
11022 }
11023
11024 /// Helper struct to tie a value+context pair together with the scope for
11025 /// which this is the simplified version.
11026 struct ItemInfo {
11027 AA::ValueAndContext I;
11029
11030 bool operator==(const ItemInfo &II) const {
11031 return II.I == I && II.S == S;
11032 };
11033 bool operator<(const ItemInfo &II) const {
11034 return std::tie(I, S) < std::tie(II.I, II.S);
11035 };
11036 };
11037
11038 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
11039 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap;
11040 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
11041 if (!(CS & S))
11042 continue;
11043
11044 bool UsedAssumedInformation = false;
11046 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
11047 UsedAssumedInformation))
11048 return false;
11049
11050 for (auto &It : Values)
11051 ValueScopeMap[It] += CS;
11052 }
11053 for (auto &It : ValueScopeMap)
11054 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
11055 AA::ValueScope(It.second), getAnchorScope());
11056
11057 return true;
11058 }
11059
11060 void giveUpOnIntraprocedural(Attributor &A) {
11061 auto NewS = StateType::getBestState(getState());
11062 for (const auto &It : getAssumedSet()) {
11063 if (It.second == AA::Intraprocedural)
11064 continue;
11065 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
11066 AA::Interprocedural, getAnchorScope());
11067 }
11068 assert(!undefIsContained() && "Undef should be an explicit value!");
11069 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
11070 getAnchorScope());
11071 getState() = NewS;
11072 }
11073
11074 /// See AbstractState::indicatePessimisticFixpoint(...).
11075 ChangeStatus indicatePessimisticFixpoint() override {
11076 getState() = StateType::getBestState(getState());
11077 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
11078 AAPotentialValues::indicateOptimisticFixpoint();
11079 return ChangeStatus::CHANGED;
11080 }
11081
11082 /// See AbstractAttribute::updateImpl(...).
11083 ChangeStatus updateImpl(Attributor &A) override {
11084 return indicatePessimisticFixpoint();
11085 }
11086
11087 /// See AbstractAttribute::manifest(...).
11088 ChangeStatus manifest(Attributor &A) override {
11091 Values.clear();
11092 if (!getAssumedSimplifiedValues(A, Values, S))
11093 continue;
11094 Value &OldV = getAssociatedValue();
11095 if (isa<UndefValue>(OldV))
11096 continue;
11097 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
11098 if (!NewV || NewV == &OldV)
11099 continue;
11100 if (getCtxI() &&
11101 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
11102 continue;
11103 if (A.changeAfterManifest(getIRPosition(), *NewV))
11104 return ChangeStatus::CHANGED;
11105 }
11106 return ChangeStatus::UNCHANGED;
11107 }
11108
11109 bool getAssumedSimplifiedValues(
11110 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values,
11111 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11112 if (!isValidState())
11113 return false;
11114 bool UsedAssumedInformation = false;
11115 for (const auto &It : getAssumedSet())
11116 if (It.second & S) {
11117 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11118 isa<SelectInst>(It.first.getValue()))) {
11119 if (A.getAssumedSimplifiedValues(
11120 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11121 this, Values, S, UsedAssumedInformation))
11122 continue;
11123 }
11124 Values.push_back(It.first);
11125 }
11126 assert(!undefIsContained() && "Undef should be an explicit value!");
11127 return true;
11128 }
11129};
11130
11131struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11132 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11133 : AAPotentialValuesImpl(IRP, A) {}
11134
11135 /// See AbstractAttribute::updateImpl(...).
11136 ChangeStatus updateImpl(Attributor &A) override {
11137 auto AssumedBefore = getAssumed();
11138
11139 genericValueTraversal(A, &getAssociatedValue());
11140
11141 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11142 : ChangeStatus::CHANGED;
11143 }
11144
11145 /// Helper struct to remember which AAIsDead instances we actually used.
11146 struct LivenessInfo {
11147 const AAIsDead *LivenessAA = nullptr;
11148 bool AnyDead = false;
11149 };
11150
11151 /// Check if \p Cmp is a comparison we can simplify.
11152 ///
11153 /// We handle multiple cases, one in which at least one operand is an
11154 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11155 /// operand. Return true if successful, in that case Worklist will be updated.
11156 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11157 CmpInst::Predicate Pred, ItemInfo II,
11158 SmallVectorImpl<ItemInfo> &Worklist) {
11159
11160 // Simplify the operands first.
11161 bool UsedAssumedInformation = false;
11162 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11163 auto GetSimplifiedValues = [&](Value &V,
11165 if (!A.getAssumedSimplifiedValues(
11166 IRPosition::value(V, getCallBaseContext()), this, Values,
11167 AA::Intraprocedural, UsedAssumedInformation)) {
11168 Values.clear();
11169 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11170 }
11171 return Values.empty();
11172 };
11173 if (GetSimplifiedValues(*LHS, LHSValues))
11174 return true;
11175 if (GetSimplifiedValues(*RHS, RHSValues))
11176 return true;
11177
11178 LLVMContext &Ctx = LHS->getContext();
11179
11180 InformationCache &InfoCache = A.getInfoCache();
11181 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11182 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11183 const auto *DT =
11184 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F)
11185 : nullptr;
11186 const auto *TLI =
11187 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11188 auto *AC =
11189 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F)
11190 : nullptr;
11191
11192 const DataLayout &DL = A.getDataLayout();
11193 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11194
11195 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11196 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11197 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11198 /* CtxI */ nullptr, II.S, getAnchorScope());
11199 return true;
11200 }
11201
11202 // Handle the trivial case first in which we don't even need to think
11203 // about null or non-null.
11204 if (&LHSV == &RHSV &&
11206 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11208 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11209 getAnchorScope());
11210 return true;
11211 }
11212
11213 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11214 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11215 if (TypedLHS && TypedRHS) {
11216 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11217 if (NewV && NewV != &Cmp) {
11218 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11219 getAnchorScope());
11220 return true;
11221 }
11222 }
11223
11224 // From now on we only handle equalities (==, !=).
11225 if (!CmpInst::isEquality(Pred))
11226 return false;
11227
11228 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11229 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11230 if (!LHSIsNull && !RHSIsNull)
11231 return false;
11232
11233 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11234 // non-nullptr operand and if we assume it's non-null we can conclude the
11235 // result of the comparison.
11236 assert((LHSIsNull || RHSIsNull) &&
11237 "Expected nullptr versus non-nullptr comparison at this point");
11238
11239 // The index is the operand that we assume is not null.
11240 unsigned PtrIdx = LHSIsNull;
11241 bool IsKnownNonNull;
11242 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11243 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11244 DepClassTy::REQUIRED, IsKnownNonNull);
11245 if (!IsAssumedNonNull)
11246 return false;
11247
11248 // The new value depends on the predicate, true for != and false for ==.
11249 Constant *NewV =
11250 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11251 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11252 getAnchorScope());
11253 return true;
11254 };
11255
11256 for (auto &LHSValue : LHSValues)
11257 for (auto &RHSValue : RHSValues)
11258 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11259 return false;
11260 return true;
11261 }
11262
11263 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11264 SmallVectorImpl<ItemInfo> &Worklist) {
11265 const Instruction *CtxI = II.I.getCtxI();
11266 bool UsedAssumedInformation = false;
11267
11268 std::optional<Constant *> C =
11269 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11270 bool NoValueYet = !C.has_value();
11271 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11272 return true;
11273 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11274 if (CI->isZero())
11275 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11276 else
11277 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11278 } else if (&SI == &getAssociatedValue()) {
11279 // We could not simplify the condition, assume both values.
11280 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11281 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11282 } else {
11283 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11284 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11285 if (!SimpleV.has_value())
11286 return true;
11287 if (*SimpleV) {
11288 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11289 return true;
11290 }
11291 return false;
11292 }
11293 return true;
11294 }
11295
11296 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11297 SmallVectorImpl<ItemInfo> &Worklist) {
11298 SmallSetVector<Value *, 4> PotentialCopies;
11299 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11300 bool UsedAssumedInformation = false;
11301 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11302 PotentialValueOrigins, *this,
11303 UsedAssumedInformation,
11304 /* OnlyExact */ true)) {
11305 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11306 "loaded values for load instruction "
11307 << LI << "\n");
11308 return false;
11309 }
11310
11311 // Do not simplify loads that are only used in llvm.assume if we cannot also
11312 // remove all stores that may feed into the load. The reason is that the
11313 // assume is probably worth something as long as the stores are around.
11314 InformationCache &InfoCache = A.getInfoCache();
11315 if (InfoCache.isOnlyUsedByAssume(LI)) {
11316 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11317 if (!I || isa<AssumeInst>(I))
11318 return true;
11319 if (auto *SI = dyn_cast<StoreInst>(I))
11320 return A.isAssumedDead(SI->getOperandUse(0), this,
11321 /* LivenessAA */ nullptr,
11322 UsedAssumedInformation,
11323 /* CheckBBLivenessOnly */ false);
11324 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11325 UsedAssumedInformation,
11326 /* CheckBBLivenessOnly */ false);
11327 })) {
11328 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11329 "and we cannot delete all the stores: "
11330 << LI << "\n");
11331 return false;
11332 }
11333 }
11334
11335 // Values have to be dynamically unique or we loose the fact that a
11336 // single llvm::Value might represent two runtime values (e.g.,
11337 // stack locations in different recursive calls).
11338 const Instruction *CtxI = II.I.getCtxI();
11339 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11340 bool AllLocal = ScopeIsLocal;
11341 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11342 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11343 return AA::isDynamicallyUnique(A, *this, *PC);
11344 });
11345 if (!DynamicallyUnique) {
11346 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11347 "values are dynamically unique: "
11348 << LI << "\n");
11349 return false;
11350 }
11351
11352 for (auto *PotentialCopy : PotentialCopies) {
11353 if (AllLocal) {
11354 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11355 } else {
11356 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11357 }
11358 }
11359 if (!AllLocal && ScopeIsLocal)
11360 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11361 return true;
11362 }
11363
11364 bool handlePHINode(
11365 Attributor &A, PHINode &PHI, ItemInfo II,
11366 SmallVectorImpl<ItemInfo> &Worklist,
11367 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11368 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11369 LivenessInfo &LI = LivenessAAs[&F];
11370 if (!LI.LivenessAA)
11371 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11372 DepClassTy::NONE);
11373 return LI;
11374 };
11375
11376 if (&PHI == &getAssociatedValue()) {
11377 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11378 const auto *CI =
11379 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11380 *PHI.getFunction());
11381
11382 Cycle *C = nullptr;
11383 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11384 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11385 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11386 if (LI.LivenessAA &&
11387 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11388 LI.AnyDead = true;
11389 continue;
11390 }
11391 Value *V = PHI.getIncomingValue(u);
11392 if (V == &PHI)
11393 continue;
11394
11395 // If the incoming value is not the PHI but an instruction in the same
11396 // cycle we might have multiple versions of it flying around.
11397 if (CyclePHI && isa<Instruction>(V) &&
11398 (!C || C->contains(cast<Instruction>(V)->getParent())))
11399 return false;
11400
11401 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11402 }
11403 return true;
11404 }
11405
11406 bool UsedAssumedInformation = false;
11407 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11408 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11409 if (!SimpleV.has_value())
11410 return true;
11411 if (!(*SimpleV))
11412 return false;
11413 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11414 return true;
11415 }
11416
11417 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11418 /// simplify any operand of the instruction \p I. Return true if successful,
11419 /// in that case Worklist will be updated.
11420 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11421 SmallVectorImpl<ItemInfo> &Worklist) {
11422 bool SomeSimplified = false;
11423 bool UsedAssumedInformation = false;
11424
11425 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11426 int Idx = 0;
11427 for (Value *Op : I.operands()) {
11428 const auto &SimplifiedOp = A.getAssumedSimplified(
11429 IRPosition::value(*Op, getCallBaseContext()), *this,
11430 UsedAssumedInformation, AA::Intraprocedural);
11431 // If we are not sure about any operand we are not sure about the entire
11432 // instruction, we'll wait.
11433 if (!SimplifiedOp.has_value())
11434 return true;
11435
11436 if (*SimplifiedOp)
11437 NewOps[Idx] = *SimplifiedOp;
11438 else
11439 NewOps[Idx] = Op;
11440
11441 SomeSimplified |= (NewOps[Idx] != Op);
11442 ++Idx;
11443 }
11444
11445 // We won't bother with the InstSimplify interface if we didn't simplify any
11446 // operand ourselves.
11447 if (!SomeSimplified)
11448 return false;
11449
11450 InformationCache &InfoCache = A.getInfoCache();
11451 Function *F = I.getFunction();
11452 const auto *DT =
11453 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F);
11454 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11455 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11456
11457 const DataLayout &DL = I.getDataLayout();
11458 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11459 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11460 if (!NewV || NewV == &I)
11461 return false;
11462
11463 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11464 << *NewV << "\n");
11465 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11466 return true;
11467 }
11468
11470 Attributor &A, Instruction &I, ItemInfo II,
11471 SmallVectorImpl<ItemInfo> &Worklist,
11472 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) {
11473 if (auto *CI = dyn_cast<CmpInst>(&I))
11474 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11475 CI->getPredicate(), II, Worklist);
11476
11477 switch (I.getOpcode()) {
11478 case Instruction::Select:
11479 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11480 case Instruction::PHI:
11481 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11482 case Instruction::Load:
11483 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11484 default:
11485 return handleGenericInst(A, I, II, Worklist);
11486 };
11487 return false;
11488 }
11489
11490 void genericValueTraversal(Attributor &A, Value *InitialV) {
11491 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs;
11492
11493 SmallSet<ItemInfo, 16> Visited;
11495 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11496
11497 int Iteration = 0;
11498 do {
11499 ItemInfo II = Worklist.pop_back_val();
11500 Value *V = II.I.getValue();
11501 assert(V);
11502 const Instruction *CtxI = II.I.getCtxI();
11503 AA::ValueScope S = II.S;
11504
11505 // Check if we should process the current value. To prevent endless
11506 // recursion keep a record of the values we followed!
11507 if (!Visited.insert(II).second)
11508 continue;
11509
11510 // Make sure we limit the compile time for complex expressions.
11511 if (Iteration++ >= MaxPotentialValuesIterations) {
11512 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11513 << Iteration << "!\n");
11514 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11515 continue;
11516 }
11517
11518 // Explicitly look through calls with a "returned" attribute if we do
11519 // not have a pointer as stripPointerCasts only works on them.
11520 Value *NewV = nullptr;
11521 if (V->getType()->isPointerTy()) {
11522 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11523 } else {
11524 if (auto *CB = dyn_cast<CallBase>(V))
11525 if (auto *Callee =
11527 for (Argument &Arg : Callee->args())
11528 if (Arg.hasReturnedAttr()) {
11529 NewV = CB->getArgOperand(Arg.getArgNo());
11530 break;
11531 }
11532 }
11533 }
11534 if (NewV && NewV != V) {
11535 Worklist.push_back({{*NewV, CtxI}, S});
11536 continue;
11537 }
11538
11539 if (auto *I = dyn_cast<Instruction>(V)) {
11540 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11541 continue;
11542 }
11543
11544 if (V != InitialV || isa<Argument>(V))
11545 if (recurseForValue(A, IRPosition::value(*V), II.S))
11546 continue;
11547
11548 // If we haven't stripped anything we give up.
11549 if (V == InitialV && CtxI == getCtxI()) {
11550 indicatePessimisticFixpoint();
11551 return;
11552 }
11553
11554 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11555 } while (!Worklist.empty());
11556
11557 // If we actually used liveness information so we have to record a
11558 // dependence.
11559 for (auto &It : LivenessAAs)
11560 if (It.second.AnyDead)
11561 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11562 }
11563
11564 /// See AbstractAttribute::trackStatistics()
11565 void trackStatistics() const override {
11566 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11567 }
11568};
11569
11570struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11571 using Base = AAPotentialValuesImpl;
11572 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11573 : Base(IRP, A) {}
11574
11575 /// See AbstractAttribute::initialize(..).
11576 void initialize(Attributor &A) override {
11577 auto &Arg = cast<Argument>(getAssociatedValue());
11579 indicatePessimisticFixpoint();
11580 }
11581
11582 /// See AbstractAttribute::updateImpl(...).
11583 ChangeStatus updateImpl(Attributor &A) override {
11584 auto AssumedBefore = getAssumed();
11585
11586 unsigned ArgNo = getCalleeArgNo();
11587
11588 bool UsedAssumedInformation = false;
11590 auto CallSitePred = [&](AbstractCallSite ACS) {
11591 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11592 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11593 return false;
11594
11595 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11597 UsedAssumedInformation))
11598 return false;
11599
11600 return isValidState();
11601 };
11602
11603 if (!A.checkForAllCallSites(CallSitePred, *this,
11604 /* RequireAllCallSites */ true,
11605 UsedAssumedInformation))
11606 return indicatePessimisticFixpoint();
11607
11608 Function *Fn = getAssociatedFunction();
11609 bool AnyNonLocal = false;
11610 for (auto &It : Values) {
11611 if (isa<Constant>(It.getValue())) {
11612 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11613 getAnchorScope());
11614 continue;
11615 }
11616 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11617 return indicatePessimisticFixpoint();
11618
11619 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11620 if (Arg->getParent() == Fn) {
11621 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11622 getAnchorScope());
11623 continue;
11624 }
11625 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11626 getAnchorScope());
11627 AnyNonLocal = true;
11628 }
11629 assert(!undefIsContained() && "Undef should be an explicit value!");
11630 if (AnyNonLocal)
11631 giveUpOnIntraprocedural(A);
11632
11633 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11634 : ChangeStatus::CHANGED;
11635 }
11636
11637 /// See AbstractAttribute::trackStatistics()
11638 void trackStatistics() const override {
11639 STATS_DECLTRACK_ARG_ATTR(potential_values)
11640 }
11641};
11642
11643struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11644 using Base = AAPotentialValuesFloating;
11645 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11646 : Base(IRP, A) {}
11647
11648 /// See AbstractAttribute::initialize(..).
11649 void initialize(Attributor &A) override {
11650 Function *F = getAssociatedFunction();
11651 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11652 indicatePessimisticFixpoint();
11653 return;
11654 }
11655
11656 for (Argument &Arg : F->args())
11657 if (Arg.hasReturnedAttr()) {
11658 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11659 ReturnedArg = &Arg;
11660 break;
11661 }
11662 if (!A.isFunctionIPOAmendable(*F) ||
11663 A.hasSimplificationCallback(getIRPosition())) {
11664 if (!ReturnedArg)
11665 indicatePessimisticFixpoint();
11666 else
11667 indicateOptimisticFixpoint();
11668 }
11669 }
11670
11671 /// See AbstractAttribute::updateImpl(...).
11672 ChangeStatus updateImpl(Attributor &A) override {
11673 auto AssumedBefore = getAssumed();
11674 bool UsedAssumedInformation = false;
11675
11677 Function *AnchorScope = getAnchorScope();
11678 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11679 bool AddValues) {
11681 Values.clear();
11682 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11683 UsedAssumedInformation,
11684 /* RecurseForSelectAndPHI */ true))
11685 return false;
11686 if (!AddValues)
11687 continue;
11688
11689 bool AllInterAreIntra = false;
11690 if (S == AA::Interprocedural)
11691 AllInterAreIntra =
11692 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11693 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11694 });
11695
11696 for (const AA::ValueAndContext &VAC : Values) {
11697 addValue(A, getState(), *VAC.getValue(),
11698 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11699 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11700 }
11701 if (AllInterAreIntra)
11702 break;
11703 }
11704 return true;
11705 };
11706
11707 if (ReturnedArg) {
11708 HandleReturnedValue(*ReturnedArg, nullptr, true);
11709 } else {
11710 auto RetInstPred = [&](Instruction &RetI) {
11711 bool AddValues = true;
11712 if (isa<PHINode>(RetI.getOperand(0)) ||
11713 isa<SelectInst>(RetI.getOperand(0))) {
11714 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11715 AnchorScope);
11716 AddValues = false;
11717 }
11718 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11719 };
11720
11721 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11722 UsedAssumedInformation,
11723 /* CheckBBLivenessOnly */ true))
11724 return indicatePessimisticFixpoint();
11725 }
11726
11727 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11728 : ChangeStatus::CHANGED;
11729 }
11730
11731 ChangeStatus manifest(Attributor &A) override {
11732 if (ReturnedArg)
11733 return ChangeStatus::UNCHANGED;
11735 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11736 /* RecurseForSelectAndPHI */ true))
11737 return ChangeStatus::UNCHANGED;
11738 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11739 if (!NewVal)
11740 return ChangeStatus::UNCHANGED;
11741
11742 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11743 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11744 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11745 "Number of function with unique return");
11746 Changed |= A.manifestAttrs(
11748 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11749 STATS_DECLTRACK_ARG_ATTR(returned);
11750 }
11751
11752 auto RetInstPred = [&](Instruction &RetI) {
11753 Value *RetOp = RetI.getOperand(0);
11754 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11755 return true;
11756 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11757 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11758 Changed = ChangeStatus::CHANGED;
11759 return true;
11760 };
11761 bool UsedAssumedInformation = false;
11762 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11763 UsedAssumedInformation,
11764 /* CheckBBLivenessOnly */ true);
11765 return Changed;
11766 }
11767
11768 ChangeStatus indicatePessimisticFixpoint() override {
11769 return AAPotentialValues::indicatePessimisticFixpoint();
11770 }
11771
11772 /// See AbstractAttribute::trackStatistics()
11773 void trackStatistics() const override{
11774 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11775
11776 /// The argumented with an existing `returned` attribute.
11777 Argument *ReturnedArg = nullptr;
11778};
11779
11780struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11781 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11782 : AAPotentialValuesImpl(IRP, A) {}
11783
11784 /// See AbstractAttribute::updateImpl(...).
11785 ChangeStatus updateImpl(Attributor &A) override {
11786 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11787 "not be called");
11788 }
11789
11790 /// See AbstractAttribute::trackStatistics()
11791 void trackStatistics() const override {
11792 STATS_DECLTRACK_FN_ATTR(potential_values)
11793 }
11794};
11795
11796struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11797 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11798 : AAPotentialValuesFunction(IRP, A) {}
11799
11800 /// See AbstractAttribute::trackStatistics()
11801 void trackStatistics() const override {
11802 STATS_DECLTRACK_CS_ATTR(potential_values)
11803 }
11804};
11805
11806struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11807 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11808 : AAPotentialValuesImpl(IRP, A) {}
11809
11810 /// See AbstractAttribute::updateImpl(...).
11811 ChangeStatus updateImpl(Attributor &A) override {
11812 auto AssumedBefore = getAssumed();
11813
11814 Function *Callee = getAssociatedFunction();
11815 if (!Callee)
11816 return indicatePessimisticFixpoint();
11817
11818 bool UsedAssumedInformation = false;
11819 auto *CB = cast<CallBase>(getCtxI());
11820 if (CB->isMustTailCall() &&
11821 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11822 UsedAssumedInformation))
11823 return indicatePessimisticFixpoint();
11824
11825 Function *Caller = CB->getCaller();
11826
11827 auto AddScope = [&](AA::ValueScope S) {
11829 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11830 Values, S, UsedAssumedInformation))
11831 return false;
11832
11833 for (auto &It : Values) {
11834 Value *V = It.getValue();
11835 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11836 V, *CB, *this, UsedAssumedInformation);
11837 if (!CallerV.has_value()) {
11838 // Nothing to do as long as no value was determined.
11839 continue;
11840 }
11841 V = *CallerV ? *CallerV : V;
11842 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11843 if (recurseForValue(A, IRPosition::value(*V), S))
11844 continue;
11845 }
11846 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11847 giveUpOnIntraprocedural(A);
11848 return true;
11849 }
11850 addValue(A, getState(), *V, CB, S, getAnchorScope());
11851 }
11852 return true;
11853 };
11854 if (!AddScope(AA::Intraprocedural))
11855 return indicatePessimisticFixpoint();
11856 if (!AddScope(AA::Interprocedural))
11857 return indicatePessimisticFixpoint();
11858 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11859 : ChangeStatus::CHANGED;
11860 }
11861
11862 ChangeStatus indicatePessimisticFixpoint() override {
11863 return AAPotentialValues::indicatePessimisticFixpoint();
11864 }
11865
11866 /// See AbstractAttribute::trackStatistics()
11867 void trackStatistics() const override {
11868 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11869 }
11870};
11871
11872struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11873 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11874 : AAPotentialValuesFloating(IRP, A) {}
11875
11876 /// See AbstractAttribute::trackStatistics()
11877 void trackStatistics() const override {
11878 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11879 }
11880};
11881} // namespace
11882
11883/// ---------------------- Assumption Propagation ------------------------------
11884namespace {
11885struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11886 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11887 const DenseSet<StringRef> &Known)
11888 : AAAssumptionInfo(IRP, A, Known) {}
11889
11890 /// See AbstractAttribute::manifest(...).
11891 ChangeStatus manifest(Attributor &A) override {
11892 // Don't manifest a universal set if it somehow made it here.
11893 if (getKnown().isUniversal())
11894 return ChangeStatus::UNCHANGED;
11895
11896 const IRPosition &IRP = getIRPosition();
11897 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11898 getAssumed().getSet().end());
11899 llvm::sort(Set);
11900 return A.manifestAttrs(IRP,
11901 Attribute::get(IRP.getAnchorValue().getContext(),
11903 llvm::join(Set, ",")),
11904 /*ForceReplace=*/true);
11905 }
11906
11907 bool hasAssumption(const StringRef Assumption) const override {
11908 return isValidState() && setContains(Assumption);
11909 }
11910
11911 /// See AbstractAttribute::getAsStr()
11912 const std::string getAsStr(Attributor *A) const override {
11913 const SetContents &Known = getKnown();
11914 const SetContents &Assumed = getAssumed();
11915
11916 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11917 llvm::sort(Set);
11918 const std::string KnownStr = llvm::join(Set, ",");
11919
11920 std::string AssumedStr = "Universal";
11921 if (!Assumed.isUniversal()) {
11922 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11923 AssumedStr = llvm::join(Set, ",");
11924 }
11925 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11926 }
11927};
11928
11929/// Propagates assumption information from parent functions to all of their
11930/// successors. An assumption can be propagated if the containing function
11931/// dominates the called function.
11932///
11933/// We start with a "known" set of assumptions already valid for the associated
11934/// function and an "assumed" set that initially contains all possible
11935/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11936/// contents as concrete values are known. The concrete values are seeded by the
11937/// first nodes that are either entries into the call graph, or contains no
11938/// assumptions. Each node is updated as the intersection of the assumed state
11939/// with all of its predecessors.
11940struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11941 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11942 : AAAssumptionInfoImpl(IRP, A,
11943 getAssumptions(*IRP.getAssociatedFunction())) {}
11944
11945 /// See AbstractAttribute::updateImpl(...).
11946 ChangeStatus updateImpl(Attributor &A) override {
11947 bool Changed = false;
11948
11949 auto CallSitePred = [&](AbstractCallSite ACS) {
11950 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11951 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11952 DepClassTy::REQUIRED);
11953 if (!AssumptionAA)
11954 return false;
11955 // Get the set of assumptions shared by all of this function's callers.
11956 Changed |= getIntersection(AssumptionAA->getAssumed());
11957 return !getAssumed().empty() || !getKnown().empty();
11958 };
11959
11960 bool UsedAssumedInformation = false;
11961 // Get the intersection of all assumptions held by this node's predecessors.
11962 // If we don't know all the call sites then this is either an entry into the
11963 // call graph or an empty node. This node is known to only contain its own
11964 // assumptions and can be propagated to its successors.
11965 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11966 UsedAssumedInformation))
11967 return indicatePessimisticFixpoint();
11968
11969 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11970 }
11971
11972 void trackStatistics() const override {}
11973};
11974
11975/// Assumption Info defined for call sites.
11976struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11977
11978 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11979 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11980
11981 /// See AbstractAttribute::initialize(...).
11982 void initialize(Attributor &A) override {
11983 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11984 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11985 }
11986
11987 /// See AbstractAttribute::updateImpl(...).
11988 ChangeStatus updateImpl(Attributor &A) override {
11989 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11990 auto *AssumptionAA =
11991 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11992 if (!AssumptionAA)
11993 return indicatePessimisticFixpoint();
11994 bool Changed = getIntersection(AssumptionAA->getAssumed());
11995 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11996 }
11997
11998 /// See AbstractAttribute::trackStatistics()
11999 void trackStatistics() const override {}
12000
12001private:
12002 /// Helper to initialized the known set as all the assumptions this call and
12003 /// the callee contain.
12004 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
12005 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
12006 auto Assumptions = getAssumptions(CB);
12007 if (const Function *F = CB.getCaller())
12008 set_union(Assumptions, getAssumptions(*F));
12009 if (Function *F = IRP.getAssociatedFunction())
12010 set_union(Assumptions, getAssumptions(*F));
12011 return Assumptions;
12012 }
12013};
12014} // namespace
12015
12017 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
12018 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
12019}
12020
12022
12023/// ------------------------ UnderlyingObjects ---------------------------------
12024
12025namespace {
12026struct AAUnderlyingObjectsImpl
12027 : StateWrapper<BooleanState, AAUnderlyingObjects> {
12029 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
12030
12031 /// See AbstractAttribute::getAsStr().
12032 const std::string getAsStr(Attributor *A) const override {
12033 if (!isValidState())
12034 return "<invalid>";
12035 std::string Str;
12037 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
12038 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
12039 << " objects.\n";
12040 if (!InterAssumedUnderlyingObjects.empty()) {
12041 OS << "inter objects:\n";
12042 for (auto *Obj : InterAssumedUnderlyingObjects)
12043 OS << *Obj << '\n';
12044 }
12045 if (!IntraAssumedUnderlyingObjects.empty()) {
12046 OS << "intra objects:\n";
12047 for (auto *Obj : IntraAssumedUnderlyingObjects)
12048 OS << *Obj << '\n';
12049 }
12050 return Str;
12051 }
12052
12053 /// See AbstractAttribute::trackStatistics()
12054 void trackStatistics() const override {}
12055
12056 /// See AbstractAttribute::updateImpl(...).
12057 ChangeStatus updateImpl(Attributor &A) override {
12058 auto &Ptr = getAssociatedValue();
12059
12060 bool UsedAssumedInformation = false;
12061 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
12063 SmallPtrSet<Value *, 8> SeenObjects;
12065
12066 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
12067 Scope, UsedAssumedInformation))
12068 return UnderlyingObjects.insert(&Ptr);
12069
12070 bool Changed = false;
12071
12072 for (unsigned I = 0; I < Values.size(); ++I) {
12073 auto &VAC = Values[I];
12074 auto *Obj = VAC.getValue();
12075 Value *UO = getUnderlyingObject(Obj);
12076 if (!SeenObjects.insert(UO ? UO : Obj).second)
12077 continue;
12078 if (UO && UO != Obj) {
12079 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
12080 Changed |= UnderlyingObjects.insert(UO);
12081 continue;
12082 }
12083
12084 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
12085 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
12086 auto Pred = [&](Value &V) {
12087 if (&V == UO)
12088 Changed |= UnderlyingObjects.insert(UO);
12089 else
12090 Values.emplace_back(V, nullptr);
12091 return true;
12092 };
12093
12094 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
12096 "The forall call should not return false at this position");
12097 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
12098 continue;
12099 }
12100
12101 if (isa<SelectInst>(Obj)) {
12102 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12103 UsedAssumedInformation);
12104 continue;
12105 }
12106 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12107 // Explicitly look through PHIs as we do not care about dynamically
12108 // uniqueness.
12109 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12110 Changed |=
12111 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12112 Scope, UsedAssumedInformation);
12113 }
12114 continue;
12115 }
12116
12117 Changed |= UnderlyingObjects.insert(Obj);
12118 }
12119
12120 return Changed;
12121 };
12122
12123 bool Changed = false;
12124 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12125 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12126 if (!UsedAssumedInformation)
12127 indicateOptimisticFixpoint();
12128 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12129 }
12130
12131 bool forallUnderlyingObjects(
12132 function_ref<bool(Value &)> Pred,
12133 AA::ValueScope Scope = AA::Interprocedural) const override {
12134 if (!isValidState())
12135 return Pred(getAssociatedValue());
12136
12137 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12138 ? IntraAssumedUnderlyingObjects
12139 : InterAssumedUnderlyingObjects;
12140 for (Value *Obj : AssumedUnderlyingObjects)
12141 if (!Pred(*Obj))
12142 return false;
12143
12144 return true;
12145 }
12146
12147private:
12148 /// Handle the case where the value is not the actual underlying value, such
12149 /// as a phi node or a select instruction.
12150 bool handleIndirect(Attributor &A, Value &V,
12151 SmallSetVector<Value *, 8> &UnderlyingObjects,
12152 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12153 bool Changed = false;
12154 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12155 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12156 auto Pred = [&](Value &V) {
12157 Changed |= UnderlyingObjects.insert(&V);
12158 return true;
12159 };
12160 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12162 "The forall call should not return false at this position");
12163 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12164 return Changed;
12165 }
12166
12167 /// All the underlying objects collected so far via intra procedural scope.
12168 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12169 /// All the underlying objects collected so far via inter procedural scope.
12170 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12171};
12172
12173struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12174 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12175 : AAUnderlyingObjectsImpl(IRP, A) {}
12176};
12177
12178struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12179 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12180 : AAUnderlyingObjectsImpl(IRP, A) {}
12181};
12182
12183struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12184 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12185 : AAUnderlyingObjectsImpl(IRP, A) {}
12186};
12187
12188struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12189 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12190 : AAUnderlyingObjectsImpl(IRP, A) {}
12191};
12192
12193struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12194 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12195 : AAUnderlyingObjectsImpl(IRP, A) {}
12196};
12197
12198struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12199 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12200 : AAUnderlyingObjectsImpl(IRP, A) {}
12201};
12202
12203struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12204 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12205 : AAUnderlyingObjectsImpl(IRP, A) {}
12206};
12207} // namespace
12208
12209/// ------------------------ Global Value Info -------------------------------
12210namespace {
12211struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12212 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12213 : AAGlobalValueInfo(IRP, A) {}
12214
12215 /// See AbstractAttribute::initialize(...).
12216 void initialize(Attributor &A) override {}
12217
12218 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12219 SmallVectorImpl<const Value *> &Worklist) {
12220 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12221 if (!UInst) {
12222 Follow = true;
12223 return true;
12224 }
12225
12226 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12227 << *UInst << "\n");
12228
12229 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12230 int Idx = &Cmp->getOperandUse(0) == &U;
12231 if (isa<Constant>(Cmp->getOperand(Idx)))
12232 return true;
12233 return U == &getAnchorValue();
12234 }
12235
12236 // Explicitly catch return instructions.
12237 if (isa<ReturnInst>(UInst)) {
12238 auto CallSitePred = [&](AbstractCallSite ACS) {
12239 Worklist.push_back(ACS.getInstruction());
12240 return true;
12241 };
12242 bool UsedAssumedInformation = false;
12243 // TODO: We should traverse the uses or add a "non-call-site" CB.
12244 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12245 /*RequireAllCallSites=*/true, this,
12246 UsedAssumedInformation))
12247 return false;
12248 return true;
12249 }
12250
12251 // For now we only use special logic for call sites. However, the tracker
12252 // itself knows about a lot of other non-capturing cases already.
12253 auto *CB = dyn_cast<CallBase>(UInst);
12254 if (!CB)
12255 return false;
12256 // Direct calls are OK uses.
12257 if (CB->isCallee(&U))
12258 return true;
12259 // Non-argument uses are scary.
12260 if (!CB->isArgOperand(&U))
12261 return false;
12262 // TODO: Iterate callees.
12263 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12264 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12265 return false;
12266
12267 unsigned ArgNo = CB->getArgOperandNo(&U);
12268 Worklist.push_back(Fn->getArg(ArgNo));
12269 return true;
12270 }
12271
12272 ChangeStatus updateImpl(Attributor &A) override {
12273 unsigned NumUsesBefore = Uses.size();
12274
12275 SmallPtrSet<const Value *, 8> Visited;
12277 Worklist.push_back(&getAnchorValue());
12278
12279 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12280 Uses.insert(&U);
12281 // TODO(captures): Make this more precise.
12282 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12283 if (CI.isPassthrough()) {
12284 Follow = true;
12285 return true;
12286 }
12287 return checkUse(A, U, Follow, Worklist);
12288 };
12289 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12290 Uses.insert(&OldU);
12291 return true;
12292 };
12293
12294 while (!Worklist.empty()) {
12295 const Value *V = Worklist.pop_back_val();
12296 if (!Visited.insert(V).second)
12297 continue;
12298 if (!A.checkForAllUses(UsePred, *this, *V,
12299 /* CheckBBLivenessOnly */ true,
12300 DepClassTy::OPTIONAL,
12301 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12302 return indicatePessimisticFixpoint();
12303 }
12304 }
12305
12306 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12307 : ChangeStatus::CHANGED;
12308 }
12309
12310 bool isPotentialUse(const Use &U) const override {
12311 return !isValidState() || Uses.contains(&U);
12312 }
12313
12314 /// See AbstractAttribute::manifest(...).
12315 ChangeStatus manifest(Attributor &A) override {
12316 return ChangeStatus::UNCHANGED;
12317 }
12318
12319 /// See AbstractAttribute::getAsStr().
12320 const std::string getAsStr(Attributor *A) const override {
12321 return "[" + std::to_string(Uses.size()) + " uses]";
12322 }
12323
12324 void trackStatistics() const override {
12325 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12326 }
12327
12328private:
12329 /// Set of (transitive) uses of this GlobalValue.
12330 SmallPtrSet<const Use *, 8> Uses;
12331};
12332} // namespace
12333
12334/// ------------------------ Indirect Call Info -------------------------------
12335namespace {
12336struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12337 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12338 : AAIndirectCallInfo(IRP, A) {}
12339
12340 /// See AbstractAttribute::initialize(...).
12341 void initialize(Attributor &A) override {
12342 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12343 if (!MD && !A.isClosedWorldModule())
12344 return;
12345
12346 if (MD) {
12347 for (const auto &Op : MD->operands())
12348 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12349 PotentialCallees.insert(Callee);
12350 } else if (A.isClosedWorldModule()) {
12351 ArrayRef<Function *> IndirectlyCallableFunctions =
12352 A.getInfoCache().getIndirectlyCallableFunctions(A);
12353 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12354 }
12355
12356 if (PotentialCallees.empty())
12357 indicateOptimisticFixpoint();
12358 }
12359
12360 ChangeStatus updateImpl(Attributor &A) override {
12361 CallBase *CB = cast<CallBase>(getCtxI());
12362 const Use &CalleeUse = CB->getCalledOperandUse();
12363 Value *FP = CB->getCalledOperand();
12364
12365 SmallSetVector<Function *, 4> AssumedCalleesNow;
12366 bool AllCalleesKnownNow = AllCalleesKnown;
12367
12368 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12369 bool &UsedAssumedInformation) {
12370 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12371 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12372 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12373 return true;
12374 UsedAssumedInformation = !GIAA->isAtFixpoint();
12375 return false;
12376 };
12377
12378 auto AddPotentialCallees = [&]() {
12379 for (auto *PotentialCallee : PotentialCallees) {
12380 bool UsedAssumedInformation = false;
12381 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12382 AssumedCalleesNow.insert(PotentialCallee);
12383 }
12384 };
12385
12386 // Use simplification to find potential callees, if !callees was present,
12387 // fallback to that set if necessary.
12388 bool UsedAssumedInformation = false;
12390 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12391 AA::ValueScope::AnyScope,
12392 UsedAssumedInformation)) {
12393 if (PotentialCallees.empty())
12394 return indicatePessimisticFixpoint();
12395 AddPotentialCallees();
12396 }
12397
12398 // Try to find a reason for \p Fn not to be a potential callee. If none was
12399 // found, add it to the assumed callees set.
12400 auto CheckPotentialCallee = [&](Function &Fn) {
12401 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12402 return false;
12403
12404 auto &CachedResult = FilterResults[&Fn];
12405 if (CachedResult.has_value())
12406 return CachedResult.value();
12407
12408 bool UsedAssumedInformation = false;
12409 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12410 if (!UsedAssumedInformation)
12411 CachedResult = false;
12412 return false;
12413 }
12414
12415 int NumFnArgs = Fn.arg_size();
12416 int NumCBArgs = CB->arg_size();
12417
12418 // Check if any excess argument (which we fill up with poison) is known to
12419 // be UB on undef.
12420 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12421 bool IsKnown = false;
12423 A, this, IRPosition::argument(*Fn.getArg(I)),
12424 DepClassTy::OPTIONAL, IsKnown)) {
12425 if (IsKnown)
12426 CachedResult = false;
12427 return false;
12428 }
12429 }
12430
12431 CachedResult = true;
12432 return true;
12433 };
12434
12435 // Check simplification result, prune known UB callees, also restrict it to
12436 // the !callees set, if present.
12437 for (auto &VAC : Values) {
12438 if (isa<UndefValue>(VAC.getValue()))
12439 continue;
12441 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12442 continue;
12443 // TODO: Check for known UB, e.g., poison + noundef.
12444 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12445 if (CheckPotentialCallee(*VACFn))
12446 AssumedCalleesNow.insert(VACFn);
12447 continue;
12448 }
12449 if (!PotentialCallees.empty()) {
12450 AddPotentialCallees();
12451 break;
12452 }
12453 AllCalleesKnownNow = false;
12454 }
12455
12456 if (AssumedCalleesNow == AssumedCallees &&
12457 AllCalleesKnown == AllCalleesKnownNow)
12458 return ChangeStatus::UNCHANGED;
12459
12460 std::swap(AssumedCallees, AssumedCalleesNow);
12461 AllCalleesKnown = AllCalleesKnownNow;
12462 return ChangeStatus::CHANGED;
12463 }
12464
12465 /// See AbstractAttribute::manifest(...).
12466 ChangeStatus manifest(Attributor &A) override {
12467 // If we can't specialize at all, give up now.
12468 if (!AllCalleesKnown && AssumedCallees.empty())
12469 return ChangeStatus::UNCHANGED;
12470
12471 CallBase *CB = cast<CallBase>(getCtxI());
12472 bool UsedAssumedInformation = false;
12473 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12474 UsedAssumedInformation))
12475 return ChangeStatus::UNCHANGED;
12476
12477 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12478 Value *FP = CB->getCalledOperand();
12479 if (FP->getType()->getPointerAddressSpace())
12480 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12481 FP->getName() + ".as0", CB->getIterator());
12482
12483 bool CBIsVoid = CB->getType()->isVoidTy();
12485 FunctionType *CSFT = CB->getFunctionType();
12486 SmallVector<Value *> CSArgs(CB->args());
12487
12488 // If we know all callees and there are none, the call site is (effectively)
12489 // dead (or UB).
12490 if (AssumedCallees.empty()) {
12491 assert(AllCalleesKnown &&
12492 "Expected all callees to be known if there are none.");
12493 A.changeToUnreachableAfterManifest(CB);
12494 return ChangeStatus::CHANGED;
12495 }
12496
12497 // Special handling for the single callee case.
12498 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12499 auto *NewCallee = AssumedCallees.front();
12500 if (isLegalToPromote(*CB, NewCallee)) {
12501 promoteCall(*CB, NewCallee, nullptr);
12502 NumIndirectCallsPromoted++;
12503 return ChangeStatus::CHANGED;
12504 }
12505 Instruction *NewCall =
12506 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12507 CB->getName(), CB->getIterator());
12508 if (!CBIsVoid)
12509 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12510 A.deleteAfterManifest(*CB);
12511 return ChangeStatus::CHANGED;
12512 }
12513
12514 // For each potential value we create a conditional
12515 //
12516 // ```
12517 // if (ptr == value) value(args);
12518 // else ...
12519 // ```
12520 //
12521 bool SpecializedForAnyCallees = false;
12522 bool SpecializedForAllCallees = AllCalleesKnown;
12523 ICmpInst *LastCmp = nullptr;
12524 SmallVector<Function *, 8> SkippedAssumedCallees;
12526 for (Function *NewCallee : AssumedCallees) {
12527 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12528 AssumedCallees.size())) {
12529 SkippedAssumedCallees.push_back(NewCallee);
12530 SpecializedForAllCallees = false;
12531 continue;
12532 }
12533 SpecializedForAnyCallees = true;
12534
12535 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12536 Instruction *ThenTI =
12537 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12538 BasicBlock *CBBB = CB->getParent();
12539 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12540 A.registerManifestAddedBasicBlock(*IP->getParent());
12541 auto *SplitTI = cast<CondBrInst>(LastCmp->getNextNode());
12542 BasicBlock *ElseBB;
12543 if (&*IP == CB) {
12544 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12545 ThenTI->getFunction(), CBBB);
12546 A.registerManifestAddedBasicBlock(*ElseBB);
12547 IP = UncondBrInst::Create(CBBB, ElseBB)->getIterator();
12548 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12549 } else {
12550 ElseBB = IP->getParent();
12551 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12552 }
12553 CastInst *RetBC = nullptr;
12554 CallInst *NewCall = nullptr;
12555 if (isLegalToPromote(*CB, NewCallee)) {
12556 auto *CBClone = cast<CallBase>(CB->clone());
12557 CBClone->insertBefore(ThenTI->getIterator());
12558 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12559 NumIndirectCallsPromoted++;
12560 } else {
12561 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12562 CB->getName(), ThenTI->getIterator());
12563 }
12564 NewCalls.push_back({NewCall, RetBC});
12565 }
12566
12567 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12568 if (!AllCalleesKnown)
12569 return ChangeStatus::UNCHANGED;
12570 MDBuilder MDB(IndirectCB.getContext());
12571 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12572 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12573 return ChangeStatus::CHANGED;
12574 };
12575
12576 if (!SpecializedForAnyCallees)
12577 return AttachCalleeMetadata(*CB);
12578
12579 // Check if we need the fallback indirect call still.
12580 if (SpecializedForAllCallees) {
12582 LastCmp->eraseFromParent();
12583 new UnreachableInst(IP->getContext(), IP);
12584 IP->eraseFromParent();
12585 } else {
12586 auto *CBClone = cast<CallInst>(CB->clone());
12587 CBClone->setName(CB->getName());
12588 CBClone->insertBefore(*IP->getParent(), IP);
12589 NewCalls.push_back({CBClone, nullptr});
12590 AttachCalleeMetadata(*CBClone);
12591 }
12592
12593 // Check if we need a PHI to merge the results.
12594 if (!CBIsVoid) {
12595 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12596 CB->getName() + ".phi",
12597 CB->getParent()->getFirstInsertionPt());
12598 for (auto &It : NewCalls) {
12599 CallBase *NewCall = It.first;
12600 Instruction *CallRet = It.second ? It.second : It.first;
12601 if (CallRet->getType() == CB->getType())
12602 PHI->addIncoming(CallRet, CallRet->getParent());
12603 else if (NewCall->getType()->isVoidTy())
12604 PHI->addIncoming(PoisonValue::get(CB->getType()),
12605 NewCall->getParent());
12606 else
12607 llvm_unreachable("Call return should match or be void!");
12608 }
12609 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12610 }
12611
12612 A.deleteAfterManifest(*CB);
12613 Changed = ChangeStatus::CHANGED;
12614
12615 return Changed;
12616 }
12617
12618 /// See AbstractAttribute::getAsStr().
12619 const std::string getAsStr(Attributor *A) const override {
12620 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12621 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12622 " functions";
12623 }
12624
12625 void trackStatistics() const override {
12626 if (AllCalleesKnown) {
12628 Eliminated, CallSites,
12629 "Number of indirect call sites eliminated via specialization")
12630 } else {
12631 STATS_DECLTRACK(Specialized, CallSites,
12632 "Number of indirect call sites specialized")
12633 }
12634 }
12635
12636 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12637 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12638 }
12639
12640private:
12641 /// Map to remember filter results.
12642 DenseMap<Function *, std::optional<bool>> FilterResults;
12643
12644 /// If the !callee metadata was present, this set will contain all potential
12645 /// callees (superset).
12646 SmallSetVector<Function *, 4> PotentialCallees;
12647
12648 /// This set contains all currently assumed calllees, which might grow over
12649 /// time.
12650 SmallSetVector<Function *, 4> AssumedCallees;
12651
12652 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12653 /// if there could be others.
12654 bool AllCalleesKnown = true;
12655};
12656} // namespace
12657
12658/// --------------------- Invariant Load Pointer -------------------------------
12659namespace {
12660
12661struct AAInvariantLoadPointerImpl
12662 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12663 AAInvariantLoadPointer> {
12664
12665 enum {
12666 // pointer does not alias within the bounds of the function
12667 IS_NOALIAS = 1 << 0,
12668 // pointer is not involved in any effectful instructions within the bounds
12669 // of the function
12670 IS_NOEFFECT = 1 << 1,
12671 // loads are invariant within the bounds of the function
12672 IS_LOCALLY_INVARIANT = 1 << 2,
12673 // memory lifetime is constrained within the bounds of the function
12674 IS_LOCALLY_CONSTRAINED = 1 << 3,
12675
12676 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12677 IS_LOCALLY_CONSTRAINED,
12678 };
12679 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12680
12681 using Base =
12682 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>;
12683
12684 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12685 // pessimistic about IS_KNOWN_INVARIANT
12686 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12687 : Base(IRP) {}
12688
12689 bool isKnownInvariant() const final {
12690 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12691 }
12692
12693 bool isKnownLocallyInvariant() const final {
12694 if (isKnown(IS_LOCALLY_INVARIANT))
12695 return true;
12696 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12697 }
12698
12699 bool isAssumedInvariant() const final {
12700 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12701 }
12702
12703 bool isAssumedLocallyInvariant() const final {
12704 if (isAssumed(IS_LOCALLY_INVARIANT))
12705 return true;
12706 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12707 }
12708
12709 ChangeStatus updateImpl(Attributor &A) override {
12710 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12711
12712 Changed |= updateNoAlias(A);
12713 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12714 return indicatePessimisticFixpoint();
12715
12716 Changed |= updateNoEffect(A);
12717
12718 Changed |= updateLocalInvariance(A);
12719
12720 return Changed;
12721 }
12722
12723 ChangeStatus manifest(Attributor &A) override {
12724 if (!isKnownInvariant())
12725 return ChangeStatus::UNCHANGED;
12726
12727 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12728 const Value *Ptr = &getAssociatedValue();
12729 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12730 if (U.get() != Ptr)
12731 return true;
12732 auto *I = dyn_cast<Instruction>(U.getUser());
12733 if (!I)
12734 return true;
12735
12736 // Ensure that we are only changing uses from the corresponding callgraph
12737 // SSC in the case that the AA isn't run on the entire module
12738 if (!A.isRunOn(I->getFunction()))
12739 return true;
12740
12741 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12742 return true;
12743
12744 if (auto *LI = dyn_cast<LoadInst>(I)) {
12745 LI->setMetadata(LLVMContext::MD_invariant_load,
12746 MDNode::get(LI->getContext(), {}));
12747 Changed = ChangeStatus::CHANGED;
12748 }
12749 return true;
12750 };
12751
12752 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12753 return Changed;
12754 }
12755
12756 /// See AbstractAttribute::getAsStr().
12757 const std::string getAsStr(Attributor *) const override {
12758 if (isKnownInvariant())
12759 return "load-invariant pointer";
12760 return "non-invariant pointer";
12761 }
12762
12763 /// See AbstractAttribute::trackStatistics().
12764 void trackStatistics() const override {}
12765
12766private:
12767 /// Indicate that noalias is required for the pointer to be invariant.
12768 bool requiresNoAlias() const {
12769 switch (getPositionKind()) {
12770 default:
12771 // Conservatively default to require noalias.
12772 return true;
12773 case IRP_FLOAT:
12774 case IRP_RETURNED:
12775 case IRP_CALL_SITE:
12776 return false;
12777 case IRP_CALL_SITE_RETURNED: {
12778 const auto &CB = cast<CallBase>(getAnchorValue());
12780 &CB, /*MustPreserveNullness=*/false);
12781 }
12782 case IRP_ARGUMENT: {
12783 const Function *F = getAssociatedFunction();
12784 assert(F && "no associated function for argument");
12785 return !isCallableCC(F->getCallingConv());
12786 }
12787 }
12788 }
12789
12790 bool isExternal() const {
12791 const Function *F = getAssociatedFunction();
12792 if (!F)
12793 return true;
12794 return isCallableCC(F->getCallingConv()) &&
12795 getPositionKind() != IRP_CALL_SITE_RETURNED;
12796 }
12797
12798 ChangeStatus updateNoAlias(Attributor &A) {
12799 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12800 return ChangeStatus::UNCHANGED;
12801
12802 // Try to use AANoAlias.
12803 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12804 getIRPosition(), this, DepClassTy::REQUIRED)) {
12805 if (ANoAlias->isKnownNoAlias()) {
12806 addKnownBits(IS_NOALIAS);
12807 return ChangeStatus::CHANGED;
12808 }
12809
12810 if (!ANoAlias->isAssumedNoAlias()) {
12811 removeAssumedBits(IS_NOALIAS);
12812 return ChangeStatus::CHANGED;
12813 }
12814
12815 return ChangeStatus::UNCHANGED;
12816 }
12817
12818 // Try to infer noalias from argument attribute, since it is applicable for
12819 // the duration of the function.
12820 if (const Argument *Arg = getAssociatedArgument()) {
12821 if (Arg->hasNoAliasAttr()) {
12822 addKnownBits(IS_NOALIAS);
12823 return ChangeStatus::UNCHANGED;
12824 }
12825
12826 // Noalias information is not provided, and cannot be inferred,
12827 // so we conservatively assume the pointer aliases.
12828 removeAssumedBits(IS_NOALIAS);
12829 return ChangeStatus::CHANGED;
12830 }
12831
12832 return ChangeStatus::UNCHANGED;
12833 }
12834
12835 ChangeStatus updateNoEffect(Attributor &A) {
12836 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12837 return ChangeStatus::UNCHANGED;
12838
12839 if (!getAssociatedFunction())
12840 return indicatePessimisticFixpoint();
12841
12842 if (isa<AllocaInst>(&getAssociatedValue()))
12843 return indicatePessimisticFixpoint();
12844
12845 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12846 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12847 return !LI || !LI->mayHaveSideEffects();
12848 };
12849 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12850 return indicatePessimisticFixpoint();
12851
12852 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12853 getIRPosition(), this, DepClassTy::REQUIRED)) {
12854 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12855 // attribute
12856 if (!AMemoryBehavior->isAssumedReadOnly())
12857 return indicatePessimisticFixpoint();
12858
12859 if (AMemoryBehavior->isKnownReadOnly()) {
12860 addKnownBits(IS_NOEFFECT);
12861 return ChangeStatus::UNCHANGED;
12862 }
12863
12864 return ChangeStatus::UNCHANGED;
12865 }
12866
12867 if (const Argument *Arg = getAssociatedArgument()) {
12868 if (Arg->onlyReadsMemory()) {
12869 addKnownBits(IS_NOEFFECT);
12870 return ChangeStatus::UNCHANGED;
12871 }
12872
12873 // Readonly information is not provided, and cannot be inferred from
12874 // AAMemoryBehavior.
12875 return indicatePessimisticFixpoint();
12876 }
12877
12878 return ChangeStatus::UNCHANGED;
12879 }
12880
12881 ChangeStatus updateLocalInvariance(Attributor &A) {
12882 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12883 return ChangeStatus::UNCHANGED;
12884
12885 // try to infer invariance from underlying objects
12886 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12887 getIRPosition(), this, DepClassTy::REQUIRED);
12888 if (!AUO)
12889 return ChangeStatus::UNCHANGED;
12890
12891 bool UsedAssumedInformation = false;
12892 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12893 if (!V.getType()->isPointerTy())
12894 return true;
12895 const auto *IsInvariantLoadPointer =
12896 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12897 DepClassTy::REQUIRED);
12898 // Conservatively fail if invariance cannot be inferred.
12899 if (!IsInvariantLoadPointer)
12900 return false;
12901
12902 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12903 return true;
12904 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12905 return false;
12906
12907 UsedAssumedInformation = true;
12908 return true;
12909 };
12910 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12911 return indicatePessimisticFixpoint();
12912
12913 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12915 CB, /*MustPreserveNullness=*/false)) {
12916 for (const Value *Arg : CB->args()) {
12917 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12918 return indicatePessimisticFixpoint();
12919 }
12920 }
12921 }
12922
12923 if (!UsedAssumedInformation) {
12924 // Pointer is known and not just assumed to be locally invariant.
12925 addKnownBits(IS_LOCALLY_INVARIANT);
12926 return ChangeStatus::CHANGED;
12927 }
12928
12929 return ChangeStatus::UNCHANGED;
12930 }
12931};
12932
12933struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12934 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12935 : AAInvariantLoadPointerImpl(IRP, A) {}
12936};
12937
12938struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12939 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12940 : AAInvariantLoadPointerImpl(IRP, A) {}
12941
12942 void initialize(Attributor &) override {
12943 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12944 }
12945};
12946
12947struct AAInvariantLoadPointerCallSiteReturned final
12948 : AAInvariantLoadPointerImpl {
12949 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12950 : AAInvariantLoadPointerImpl(IRP, A) {}
12951
12952 void initialize(Attributor &A) override {
12953 const Function *F = getAssociatedFunction();
12954 assert(F && "no associated function for return from call");
12955
12956 if (!F->isDeclaration() && !F->isIntrinsic())
12957 return AAInvariantLoadPointerImpl::initialize(A);
12958
12959 const auto &CB = cast<CallBase>(getAnchorValue());
12961 &CB, /*MustPreserveNullness=*/false))
12962 return AAInvariantLoadPointerImpl::initialize(A);
12963
12964 if (F->onlyReadsMemory() && F->hasNoSync())
12965 return AAInvariantLoadPointerImpl::initialize(A);
12966
12967 // At this point, the function is opaque, so we conservatively assume
12968 // non-invariance.
12969 indicatePessimisticFixpoint();
12970 }
12971};
12972
12973struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12974 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12975 : AAInvariantLoadPointerImpl(IRP, A) {}
12976
12977 void initialize(Attributor &) override {
12978 const Function *F = getAssociatedFunction();
12979 assert(F && "no associated function for argument");
12980
12981 if (!isCallableCC(F->getCallingConv())) {
12982 addKnownBits(IS_LOCALLY_CONSTRAINED);
12983 return;
12984 }
12985
12986 if (!F->hasLocalLinkage())
12987 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12988 }
12989};
12990
12991struct AAInvariantLoadPointerCallSiteArgument final
12992 : AAInvariantLoadPointerImpl {
12993 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12994 : AAInvariantLoadPointerImpl(IRP, A) {}
12995};
12996} // namespace
12997
12998/// ------------------------ Address Space ------------------------------------
12999namespace {
13000
13001template <typename InstType>
13002static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
13003 Value *OriginalValue, PointerType *NewPtrTy,
13004 bool UseOriginalValue) {
13005 if (U.getOperandNo() != InstType::getPointerOperandIndex())
13006 return false;
13007
13008 if (MemInst->isVolatile()) {
13009 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
13010 *MemInst->getFunction());
13011 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
13012 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
13013 return false;
13014 }
13015
13016 if (UseOriginalValue) {
13017 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
13018 return true;
13019 }
13020
13021 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
13022 CastInst->insertBefore(MemInst->getIterator());
13023 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
13024 return true;
13025}
13026
13027struct AAAddressSpaceImpl : public AAAddressSpace {
13028 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
13029 : AAAddressSpace(IRP, A) {}
13030
13031 uint32_t getAddressSpace() const override {
13032 assert(isValidState() && "the AA is invalid");
13033 return AssumedAddressSpace;
13034 }
13035
13036 /// See AbstractAttribute::initialize(...).
13037 void initialize(Attributor &A) override {
13038 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13039 "Associated value is not a pointer");
13040
13041 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
13042 indicatePessimisticFixpoint();
13043 return;
13044 }
13045
13046 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13047 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13048 if (AS != FlatAS) {
13049 [[maybe_unused]] bool R = takeAddressSpace(AS);
13050 assert(R && "The take should happen");
13051 indicateOptimisticFixpoint();
13052 }
13053 }
13054
13055 ChangeStatus updateImpl(Attributor &A) override {
13056 uint32_t OldAddressSpace = AssumedAddressSpace;
13057 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13058
13059 auto CheckAddressSpace = [&](Value &Obj) {
13060 // Ignore undef.
13061 if (isa<UndefValue>(&Obj))
13062 return true;
13063
13064 // If the object already has a non-flat address space, we simply take it.
13065 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
13066 if (ObjAS != FlatAS)
13067 return takeAddressSpace(ObjAS);
13068
13069 // At this point, we know Obj is in the flat address space. For a final
13070 // attempt, we want to use getAssumedAddrSpace, but first we must get the
13071 // associated function, if possible.
13072 Function *F = nullptr;
13073 if (auto *Arg = dyn_cast<Argument>(&Obj))
13074 F = Arg->getParent();
13075 else if (auto *I = dyn_cast<Instruction>(&Obj))
13076 F = I->getFunction();
13077
13078 // Use getAssumedAddrSpace if the associated function exists.
13079 if (F) {
13080 auto *TTI =
13081 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
13082 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
13083 if (AssumedAS != ~0U)
13084 return takeAddressSpace(AssumedAS);
13085 }
13086
13087 // Now we can't do anything else but to take the flat AS.
13088 return takeAddressSpace(FlatAS);
13089 };
13090
13091 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
13092 DepClassTy::REQUIRED);
13093 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13094 return indicatePessimisticFixpoint();
13095
13096 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
13097 : ChangeStatus::CHANGED;
13098 }
13099
13100 /// See AbstractAttribute::manifest(...).
13101 ChangeStatus manifest(Attributor &A) override {
13102 unsigned NewAS = getAddressSpace();
13103
13104 if (NewAS == InvalidAddressSpace ||
13105 NewAS == getAssociatedType()->getPointerAddressSpace())
13106 return ChangeStatus::UNCHANGED;
13107
13108 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13109
13110 Value *AssociatedValue = &getAssociatedValue();
13111 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13112
13113 PointerType *NewPtrTy =
13114 PointerType::get(getAssociatedType()->getContext(), NewAS);
13115 bool UseOriginalValue =
13116 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13117
13118 bool Changed = false;
13119
13120 auto Pred = [&](const Use &U, bool &) {
13121 if (U.get() != AssociatedValue)
13122 return true;
13123 auto *Inst = dyn_cast<Instruction>(U.getUser());
13124 if (!Inst)
13125 return true;
13126 // This is a WA to make sure we only change uses from the corresponding
13127 // CGSCC if the AA is run on CGSCC instead of the entire module.
13128 if (!A.isRunOn(Inst->getFunction()))
13129 return true;
13130 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13131 Changed |=
13132 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13133 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13134 Changed |=
13135 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13136 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13137 Changed |=
13138 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13139 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13140 Changed |=
13141 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13142 }
13143 return true;
13144 };
13145
13146 // It doesn't matter if we can't check all uses as we can simply
13147 // conservatively ignore those that can not be visited.
13148 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13149 /* CheckBBLivenessOnly */ true);
13150
13151 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13152 }
13153
13154 /// See AbstractAttribute::getAsStr().
13155 const std::string getAsStr(Attributor *A) const override {
13156 if (!isValidState())
13157 return "addrspace(<invalid>)";
13158 return "addrspace(" +
13159 (AssumedAddressSpace == InvalidAddressSpace
13160 ? "none"
13161 : std::to_string(AssumedAddressSpace)) +
13162 ")";
13163 }
13164
13165private:
13166 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13167
13168 bool takeAddressSpace(uint32_t AS) {
13169 if (AssumedAddressSpace == InvalidAddressSpace) {
13170 AssumedAddressSpace = AS;
13171 return true;
13172 }
13173 return AssumedAddressSpace == AS;
13174 }
13175
13176 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13177 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13178 assert(I->getSrcAddressSpace() != FlatAS &&
13179 "there should not be flat AS -> non-flat AS");
13180 return I->getPointerOperand();
13181 }
13182 if (auto *C = dyn_cast<ConstantExpr>(V))
13183 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13184 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13185 FlatAS &&
13186 "there should not be flat AS -> non-flat AS X");
13187 return C->getOperand(0);
13188 }
13189 return V;
13190 }
13191};
13192
13193struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13194 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13195 : AAAddressSpaceImpl(IRP, A) {}
13196
13197 void trackStatistics() const override {
13199 }
13200};
13201
13202struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13203 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13204 : AAAddressSpaceImpl(IRP, A) {}
13205
13206 /// See AbstractAttribute::initialize(...).
13207 void initialize(Attributor &A) override {
13208 // TODO: we don't rewrite function argument for now because it will need to
13209 // rewrite the function signature and all call sites.
13210 (void)indicatePessimisticFixpoint();
13211 }
13212
13213 void trackStatistics() const override {
13214 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13215 }
13216};
13217
13218struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13219 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13220 : AAAddressSpaceImpl(IRP, A) {}
13221
13222 void trackStatistics() const override {
13223 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13224 }
13225};
13226
13227struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13228 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13229 : AAAddressSpaceImpl(IRP, A) {}
13230
13231 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13232};
13233
13234struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13235 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13236 : AAAddressSpaceImpl(IRP, A) {}
13237
13238 /// See AbstractAttribute::initialize(...).
13239 void initialize(Attributor &A) override {
13240 // TODO: we don't rewrite call site argument for now because it will need to
13241 // rewrite the function signature of the callee.
13242 (void)indicatePessimisticFixpoint();
13243 }
13244
13245 void trackStatistics() const override {
13246 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13247 }
13248};
13249} // namespace
13250
13251/// ------------------------ No Alias Address Space ---------------------------
13252// This attribute assumes flat address space can alias all other address space
13253
13254// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13255// But merging it created failing cased on gateway test that cannot be
13256// reproduced locally. So should open a separated PR to handle the merge of
13257// AANoAliasAddrSpace and AAAddressSpace attribute
13258
13259namespace {
13260struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13261 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13262 : AANoAliasAddrSpace(IRP, A) {}
13263
13264 void initialize(Attributor &A) override {
13265 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13266 "Associated value is not a pointer");
13267
13268 resetASRanges(A);
13269
13270 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13271 if (!FlatAS.has_value()) {
13272 indicatePessimisticFixpoint();
13273 return;
13274 }
13275
13276 removeAS(*FlatAS);
13277
13278 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13279 if (AS != *FlatAS) {
13280 removeAS(AS);
13281 indicateOptimisticFixpoint();
13282 }
13283 }
13284
13285 ChangeStatus updateImpl(Attributor &A) override {
13286 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13287 uint32_t OldAssumed = getAssumed();
13288
13289 auto CheckAddressSpace = [&](Value &Obj) {
13290 if (isa<PoisonValue>(&Obj))
13291 return true;
13292
13293 unsigned AS = Obj.getType()->getPointerAddressSpace();
13294 if (AS == FlatAS)
13295 return false;
13296
13297 removeAS(Obj.getType()->getPointerAddressSpace());
13298 return true;
13299 };
13300
13301 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13302 getIRPosition(), this, DepClassTy::REQUIRED);
13303 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13304 return indicatePessimisticFixpoint();
13305
13306 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13307 : ChangeStatus::CHANGED;
13308 }
13309
13310 /// See AbstractAttribute::manifest(...).
13311 ChangeStatus manifest(Attributor &A) override {
13312 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13313
13314 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13315 if (AS != FlatAS || Map.empty())
13316 return ChangeStatus::UNCHANGED;
13317
13318 LLVMContext &Ctx = getAssociatedValue().getContext();
13319 MDNode *NoAliasASNode = nullptr;
13320 MDBuilder MDB(Ctx);
13321 // Has to use iterator to get the range info.
13322 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13323 if (!I.value())
13324 continue;
13325 unsigned Upper = I.stop();
13326 unsigned Lower = I.start();
13327 if (!NoAliasASNode) {
13328 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13329 continue;
13330 }
13331 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13332 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13333 }
13334
13335 Value *AssociatedValue = &getAssociatedValue();
13336 bool Changed = false;
13337
13338 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13339 if (U.get() != AssociatedValue)
13340 return true;
13341 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13342 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13343 return true;
13344 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13346 return true;
13347 if (!A.isRunOn(Inst->getFunction()))
13348 return true;
13349 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13350 Changed = true;
13351 return true;
13352 };
13353 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13354 /*CheckBBLivenessOnly=*/true);
13355 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13356 }
13357
13358 /// See AbstractAttribute::getAsStr().
13359 const std::string getAsStr(Attributor *A) const override {
13360 if (!isValidState())
13361 return "<invalid>";
13362 std::string Str;
13363 raw_string_ostream OS(Str);
13364 OS << "CanNotBeAddrSpace(";
13365 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13366 unsigned Upper = I.stop();
13367 unsigned Lower = I.start();
13368 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13369 }
13370 OS << " )";
13371 return OS.str();
13372 }
13373
13374private:
13375 void removeAS(unsigned AS) {
13376 RangeMap::iterator I = Map.find(AS);
13377
13378 if (I != Map.end()) {
13379 unsigned Upper = I.stop();
13380 unsigned Lower = I.start();
13381 I.erase();
13382 if (Upper == Lower)
13383 return;
13384 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13385 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13386 if (AS != 0 && Lower <= AS - 1)
13387 Map.insert(Lower, AS - 1, true);
13388 }
13389 }
13390
13391 void resetASRanges(Attributor &A) {
13392 Map.clear();
13393 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13394 }
13395};
13396
13397struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13398 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13399 : AANoAliasAddrSpaceImpl(IRP, A) {}
13400
13401 void trackStatistics() const override {
13402 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13403 }
13404};
13405
13406struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13407 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13408 : AANoAliasAddrSpaceImpl(IRP, A) {}
13409
13410 void trackStatistics() const override {
13411 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13412 }
13413};
13414
13415struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13416 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13417 : AANoAliasAddrSpaceImpl(IRP, A) {}
13418
13419 void trackStatistics() const override {
13420 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13421 }
13422};
13423
13424struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13425 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13426 : AANoAliasAddrSpaceImpl(IRP, A) {}
13427
13428 void trackStatistics() const override {
13429 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13430 }
13431};
13432
13433struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13434 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13435 : AANoAliasAddrSpaceImpl(IRP, A) {}
13436
13437 void trackStatistics() const override {
13438 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13439 }
13440};
13441} // namespace
13442/// ----------- Allocation Info ----------
13443namespace {
13444struct AAAllocationInfoImpl : public AAAllocationInfo {
13445 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13446 : AAAllocationInfo(IRP, A) {}
13447
13448 std::optional<TypeSize> getAllocatedSize() const override {
13449 assert(isValidState() && "the AA is invalid");
13450 return AssumedAllocatedSize;
13451 }
13452
13453 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13454 const DataLayout &DL) {
13455
13456 // TODO: implement case for malloc like instructions
13457 switch (I->getOpcode()) {
13458 case Instruction::Alloca: {
13459 AllocaInst *AI = cast<AllocaInst>(I);
13460 return AI->getAllocationSize(DL);
13461 }
13462 default:
13463 return std::nullopt;
13464 }
13465 }
13466
13467 ChangeStatus updateImpl(Attributor &A) override {
13468
13469 const IRPosition &IRP = getIRPosition();
13470 Instruction *I = IRP.getCtxI();
13471
13472 // TODO: update check for malloc like calls
13473 if (!isa<AllocaInst>(I))
13474 return indicatePessimisticFixpoint();
13475
13476 bool IsKnownNoCapture;
13478 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13479 return indicatePessimisticFixpoint();
13480
13481 const AAPointerInfo *PI =
13482 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13483
13484 if (!PI)
13485 return indicatePessimisticFixpoint();
13486
13487 if (!PI->getState().isValidState() || PI->reachesReturn())
13488 return indicatePessimisticFixpoint();
13489
13490 const DataLayout &DL = A.getDataLayout();
13491 const auto AllocationSize = findInitialAllocationSize(I, DL);
13492
13493 // If allocation size is nullopt, we give up.
13494 if (!AllocationSize)
13495 return indicatePessimisticFixpoint();
13496
13497 // For zero sized allocations, we give up.
13498 // Since we can't reduce further
13499 if (*AllocationSize == 0)
13500 return indicatePessimisticFixpoint();
13501
13502 int64_t BinSize = PI->numOffsetBins();
13503
13504 // TODO: implement for multiple bins
13505 if (BinSize > 1)
13506 return indicatePessimisticFixpoint();
13507
13508 if (BinSize == 0) {
13509 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13510 if (!changeAllocationSize(NewAllocationSize))
13511 return ChangeStatus::UNCHANGED;
13512 return ChangeStatus::CHANGED;
13513 }
13514
13515 // TODO: refactor this to be part of multiple bin case
13516 const auto &It = PI->begin();
13517
13518 // TODO: handle if Offset is not zero
13519 if (It->first.Offset != 0)
13520 return indicatePessimisticFixpoint();
13521
13522 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13523
13524 if (SizeOfBin >= *AllocationSize)
13525 return indicatePessimisticFixpoint();
13526
13527 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13528
13529 if (!changeAllocationSize(NewAllocationSize))
13530 return ChangeStatus::UNCHANGED;
13531
13532 return ChangeStatus::CHANGED;
13533 }
13534
13535 /// See AbstractAttribute::manifest(...).
13536 ChangeStatus manifest(Attributor &A) override {
13537
13538 assert(isValidState() &&
13539 "Manifest should only be called if the state is valid.");
13540
13541 Instruction *I = getIRPosition().getCtxI();
13542
13543 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13544
13545 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13546
13547 switch (I->getOpcode()) {
13548 // TODO: add case for malloc like calls
13549 case Instruction::Alloca: {
13550
13551 AllocaInst *AI = cast<AllocaInst>(I);
13552
13553 Type *CharType = Type::getInt8Ty(I->getContext());
13554
13555 auto *NumBytesToValue =
13556 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13557
13558 BasicBlock::iterator insertPt = AI->getIterator();
13559 insertPt = std::next(insertPt);
13560 AllocaInst *NewAllocaInst =
13561 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13562 AI->getAlign(), AI->getName(), insertPt);
13563
13564 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13565 return ChangeStatus::CHANGED;
13566
13567 break;
13568 }
13569 default:
13570 break;
13571 }
13572
13573 return ChangeStatus::UNCHANGED;
13574 }
13575
13576 /// See AbstractAttribute::getAsStr().
13577 const std::string getAsStr(Attributor *A) const override {
13578 if (!isValidState())
13579 return "allocationinfo(<invalid>)";
13580 return "allocationinfo(" +
13581 (AssumedAllocatedSize == HasNoAllocationSize
13582 ? "none"
13583 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13584 ")";
13585 }
13586
13587private:
13588 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13589
13590 // Maintain the computed allocation size of the object.
13591 // Returns (bool) weather the size of the allocation was modified or not.
13592 bool changeAllocationSize(std::optional<TypeSize> Size) {
13593 if (AssumedAllocatedSize == HasNoAllocationSize ||
13594 AssumedAllocatedSize != Size) {
13595 AssumedAllocatedSize = Size;
13596 return true;
13597 }
13598 return false;
13599 }
13600};
13601
13602struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13603 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13604 : AAAllocationInfoImpl(IRP, A) {}
13605
13606 void trackStatistics() const override {
13607 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13608 }
13609};
13610
13611struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13612 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13613 : AAAllocationInfoImpl(IRP, A) {}
13614
13615 /// See AbstractAttribute::initialize(...).
13616 void initialize(Attributor &A) override {
13617 // TODO: we don't rewrite function argument for now because it will need to
13618 // rewrite the function signature and all call sites
13619 (void)indicatePessimisticFixpoint();
13620 }
13621
13622 void trackStatistics() const override {
13623 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13624 }
13625};
13626
13627struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13628 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13629 : AAAllocationInfoImpl(IRP, A) {}
13630
13631 void trackStatistics() const override {
13632 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13633 }
13634};
13635
13636struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13637 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13638 : AAAllocationInfoImpl(IRP, A) {}
13639
13640 void trackStatistics() const override {
13641 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13642 }
13643};
13644
13645struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13646 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13647 : AAAllocationInfoImpl(IRP, A) {}
13648
13649 /// See AbstractAttribute::initialize(...).
13650 void initialize(Attributor &A) override {
13651
13652 (void)indicatePessimisticFixpoint();
13653 }
13654
13655 void trackStatistics() const override {
13656 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13657 }
13658};
13659} // namespace
13660
13661const char AANoUnwind::ID = 0;
13662const char AANoSync::ID = 0;
13663const char AANoFree::ID = 0;
13664const char AANonNull::ID = 0;
13665const char AAMustProgress::ID = 0;
13666const char AANoRecurse::ID = 0;
13667const char AANonConvergent::ID = 0;
13668const char AAWillReturn::ID = 0;
13669const char AAUndefinedBehavior::ID = 0;
13670const char AANoAlias::ID = 0;
13671const char AAIntraFnReachability::ID = 0;
13672const char AANoReturn::ID = 0;
13673const char AAIsDead::ID = 0;
13674const char AADereferenceable::ID = 0;
13675const char AAAlign::ID = 0;
13676const char AAInstanceInfo::ID = 0;
13677const char AANoCapture::ID = 0;
13678const char AAValueSimplify::ID = 0;
13679const char AAHeapToStack::ID = 0;
13680const char AAPrivatizablePtr::ID = 0;
13681const char AAMemoryBehavior::ID = 0;
13682const char AAMemoryLocation::ID = 0;
13683const char AAValueConstantRange::ID = 0;
13684const char AAPotentialConstantValues::ID = 0;
13685const char AAPotentialValues::ID = 0;
13686const char AANoUndef::ID = 0;
13687const char AANoFPClass::ID = 0;
13688const char AACallEdges::ID = 0;
13689const char AAInterFnReachability::ID = 0;
13690const char AAPointerInfo::ID = 0;
13691const char AAAssumptionInfo::ID = 0;
13692const char AAUnderlyingObjects::ID = 0;
13693const char AAInvariantLoadPointer::ID = 0;
13694const char AAAddressSpace::ID = 0;
13695const char AANoAliasAddrSpace::ID = 0;
13696const char AAAllocationInfo::ID = 0;
13697const char AAIndirectCallInfo::ID = 0;
13698const char AAGlobalValueInfo::ID = 0;
13699const char AADenormalFPMath::ID = 0;
13700
13701// Macro magic to create the static generator function for attributes that
13702// follow the naming scheme.
13703
13704#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13705 case IRPosition::PK: \
13706 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13707
13708#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13709 case IRPosition::PK: \
13710 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13711 ++NumAAs; \
13712 break;
13713
13714#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13715 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13716 CLASS *AA = nullptr; \
13717 switch (IRP.getPositionKind()) { \
13718 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13719 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13720 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13721 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13722 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13723 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13724 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13725 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13726 } \
13727 return *AA; \
13728 }
13729
13730#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13731 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13732 CLASS *AA = nullptr; \
13733 switch (IRP.getPositionKind()) { \
13734 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13735 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13736 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13737 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13738 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13739 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13740 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13741 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13742 } \
13743 return *AA; \
13744 }
13745
13746#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13747 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13748 CLASS *AA = nullptr; \
13749 switch (IRP.getPositionKind()) { \
13750 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13751 default: \
13752 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13753 " position!"); \
13754 } \
13755 return *AA; \
13756 }
13757
13758#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13759 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13760 CLASS *AA = nullptr; \
13761 switch (IRP.getPositionKind()) { \
13762 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13763 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13764 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13765 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13766 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13767 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13768 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13769 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13770 } \
13771 return *AA; \
13772 }
13773
13774#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13775 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13776 CLASS *AA = nullptr; \
13777 switch (IRP.getPositionKind()) { \
13778 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13779 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13780 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13781 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13782 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13783 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13784 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13785 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13786 } \
13787 return *AA; \
13788 }
13789
13790#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13791 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13792 CLASS *AA = nullptr; \
13793 switch (IRP.getPositionKind()) { \
13794 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13795 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13796 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13797 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13798 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13799 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13800 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13801 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13802 } \
13803 return *AA; \
13804 }
13805
13815
13833
13838
13843
13850
13852
13853#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13854#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13855#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13856#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13857#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13858#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13859#undef SWITCH_PK_CREATE
13860#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
#define STATS_DECLTRACK(NAME, TYPE, MSG)
static std::optional< Constant * > askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, const IRPosition &IRP, Type &Ty)
static cl::opt< unsigned, true > MaxPotentialValues("attributor-max-potential-values", cl::Hidden, cl::desc("Maximum number of potential values to be " "tracked for each position."), cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), cl::init(7))
static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA, StateType &S, const IRPosition::CallBaseContext *CBContext=nullptr)
Clamp the information known for all returned values of a function (identified by QueryingAA) into S.
#define STATS_DECLTRACK_FN_ATTR(NAME)
#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxPotentialValuesIterations("attributor-max-potential-values-iterations", cl::Hidden, cl::desc("Maximum number of iterations we keep dismantling potential values."), cl::init(64))
#define STATS_DECLTRACK_CS_ATTR(NAME)
#define PIPE_OPERATOR(CLASS)
#define DefineKeys(ToTy)
static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, bool HeaderOnly, Cycle **CPtr=nullptr)
#define STATS_DECLTRACK_ARG_ATTR(NAME)
static const Value * stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val, const DataLayout &DL, APInt &Offset, bool GetMinOffset, bool AllowNonInbounds, bool UseAssumed=false)
#define STATS_DECLTRACK_CSRET_ATTR(NAME)
static cl::opt< bool > ManifestInternal("attributor-manifest-internal", cl::Hidden, cl::desc("Manifest Attributor internal string attributes."), cl::init(false))
static Value * constructPointer(Value *Ptr, int64_t Offset, IRBuilder< NoFolder > &IRB)
Helper function to create a pointer based on Ptr, and advanced by Offset bytes.
#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define BUILD_STAT_NAME(NAME, TYPE)
static bool isDenselyPacked(Type *Ty, const DataLayout &DL)
Checks if a type could have padding bytes.
#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static const Value * getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, const Value *Ptr, int64_t &BytesOffset, const DataLayout &DL, bool AllowNonInbounds=false)
#define STATS_DECLTRACK_FNRET_ATTR(NAME)
#define STATS_DECLTRACK_CSARG_ATTR(NAME)
#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS)
#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
static cl::opt< int > MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), cl::Hidden)
#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS)
#define STATS_DECLTRACK_FLOATING_ATTR(NAME)
#define STATS_DECL(NAME, TYPE, MSG)
basic Basic Alias true
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI, const CycleInfo *CI)
Definition CFG.cpp:145
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
dxil translate DXIL Translate Metadata
This file defines DenseMapInfo traits for DenseMap.
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
bool IsDead
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
This pass exposes codegen information to IR-level passes.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Value * RHS
Value * LHS
static unsigned getSize(unsigned Kind)
LLVM_ABI AACallGraphNode * operator*() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
CallBase * getInstruction() const
Return the underlying instruction.
bool isCallbackCall() const
Return true if this ACS represents a callback call.
bool isDirectCall() const
Return true if this ACS represents a direct call.
static LLVM_ABI void getCallbackUses(const CallBase &CB, SmallVectorImpl< const Use * > &CallbackUses)
Add operand uses of CB that represent callback uses into CallbackUses.
int getCallArgOperandNo(Argument &Arg) const
Return the operand index of the underlying instruction associated with Arg.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
unsigned getAddressSpace() const
Return the address space for the allocation.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition Function.cpp:272
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition Function.cpp:308
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition Function.cpp:171
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition Function.cpp:296
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition Function.cpp:128
const Function * getParent() const
Definition Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition Argument.h:50
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
static bool isEnumAttrKind(AttrKind Kind)
Definition Attributes.h:137
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:484
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BinaryOps getOpcode() const
Definition InstrTypes.h:374
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
Attribute getFnAttr(StringRef Kind) const
Get the attribute of a given kind for the function.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
LLVM_ABI std::optional< ConstantRange > getRange() const
If this return value has a range attribute, return the value range of the argument.
Value * getArgOperand(unsigned i) const
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
bool isConvergent() const
Determine if the invoke is convergent.
FunctionType * getFunctionType() const
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition InstrTypes.h:610
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition InstrTypes.h:617
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition InstrTypes.h:915
bool isFalseWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:948
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:676
@ ICMP_NE
not equal
Definition InstrTypes.h:698
bool isTrueWhenEqual() const
This is just a convenience.
Definition InstrTypes.h:942
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:765
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:537
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
This class represents a range of values.
const APInt & getLower() const
Return the lower value for this range.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
static LLVM_ABI ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
const APInt & getUpper() const
Return the upper value for this range.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:178
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:256
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:174
iterator end()
Definition DenseMap.h:81
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
Analysis pass which computes a DominatorTree.
Definition Dominators.h:278
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:159
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
const BasicBlock & getEntryBlock() const
Definition Function.h:809
Argument * arg_iterator
Definition Function.h:73
iterator_range< arg_iterator > args()
Definition Function.h:892
const Function & getFunction() const
Definition Function.h:166
size_t arg_size() const
Definition Function.h:901
Argument * getArg(unsigned i) const
Definition Function.h:886
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:728
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:337
bool hasLocalLinkage() const
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2084
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition IRBuilder.h:534
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2847
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
ConstantRange getConstantRange(Value *V, Instruction *CxtI, bool UndefAllowed)
Return the ConstantRange constraint that is known to hold for the specified value at the specified in...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1572
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
bool empty() const
Definition MapVector.h:77
static MemoryEffectsBase readOnly()
Definition ModRef.h:133
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:149
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition ModRef.h:265
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition ModRef.h:255
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition ModRef.h:249
static MemoryEffectsBase writeOnly()
Definition ModRef.h:138
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:166
static MemoryEffectsBase none()
Definition ModRef.h:128
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition ModRef.h:305
static MemoryEffectsBase unknown()
Definition ModRef.h:123
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static SizeOffsetValue unknown()
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
LLVM_ABI const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
ConstantRange getUnsignedRange(const SCEV *S)
Determine the unsigned range for a particular SCEV.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition DataLayout.h:736
TypeSize getElementOffset(unsigned Idx) const
Definition DataLayout.h:767
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition DataLayout.h:772
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, ArrayRef< Type * > Types) const
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:284
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition Type.h:287
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i=0) const
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
Value * get() const
Definition Use.h:55
const Use & getOperandUse(unsigned i) const
Definition User.h:220
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition User.cpp:119
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition ValueMap.h:167
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
static constexpr uint64_t MaximumAlignment
Definition Value.h:808
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:258
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
bool use_empty() const
Definition Value.h:346
static constexpr unsigned MaxAlignmentExponent
The maximum alignment for instructions.
Definition Value.h:807
iterator_range< use_iterator > uses()
Definition Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:318
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
raw_ostream & operator<<(raw_ostream &OS, const RangeTy &R)
Definition Attributor.h:323
LLVM_ABI std::optional< Value * > combineOptionalValuesInAAValueLatice(const std::optional< Value * > &A, const std::optional< Value * > &B, Type *Ty)
Return the combination of A and B such that the result is a possible value of both.
LLVM_ABI bool isValidAtPosition(const ValueAndContext &VAC, InformationCache &InfoCache)
Return true if the value of VAC is a valid at the position of VAC, that is a constant,...
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
LLVM_ABI bool isDynamicallyUnique(Attributor &A, const AbstractAttribute &QueryingAA, const Value &V, bool ForAnalysisOnly=true)
Return true if V is dynamically unique, that is, there are no two "instances" of V at runtime with di...
LLVM_ABI bool getPotentialCopiesOfStoredValue(Attributor &A, StoreInst &SI, SmallSetVector< Value *, 4 > &PotentialCopies, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values of the one stored by SI into PotentialCopies.
SmallPtrSet< Instruction *, 4 > InstExclusionSetTy
Definition Attributor.h:166
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
ValueScope
Flags to distinguish intra-procedural queries from potentially inter-procedural queries.
Definition Attributor.h:182
@ Intraprocedural
Definition Attributor.h:183
@ Interprocedural
Definition Attributor.h:184
LLVM_ABI bool isValidInScope(const Value &V, const Function *Scope)
Return true if V is a valid value in Scope, that is a constant or an instruction/argument of Scope.
LLVM_ABI bool isPotentiallyReachable(Attributor &A, const Instruction &FromI, const Instruction &ToI, const AbstractAttribute &QueryingAA, const AA::InstExclusionSetTy *ExclusionSet=nullptr, std::function< bool(const Function &F)> GoBackwardsCB=nullptr)
Return true if ToI is potentially reachable from FromI without running into any instruction in Exclus...
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
bool hasAssumedIRAttr(Attributor &A, const AbstractAttribute *QueryingAA, const IRPosition &IRP, DepClassTy DepClass, bool &IsKnown, bool IgnoreSubsumingPositions=false, const AAType **AAPtr=nullptr)
Helper to avoid creating an AA for IR Attributes that might already be set.
LLVM_ABI bool getPotentiallyLoadedValues(Attributor &A, LoadInst &LI, SmallSetVector< Value *, 4 > &PotentialValues, SmallSetVector< Instruction *, 4 > &PotentialValueOrigins, const AbstractAttribute &QueryingAA, bool &UsedAssumedInformation, bool OnlyExact=false)
Collect all potential values LI could read into PotentialValues.
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Unsupported
This operation is completely unsupported on the target.
Offsets
Offsets in bytes from the start of the input buffer.
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
ElementType
The element type of an SRV or UAV resource.
Definition DXILABI.h:68
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:709
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
Context & getContext() const
Definition BasicBlock.h:99
iterator end() const
Definition BasicBlock.h:89
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
@ Length
Definition DWP.cpp:532
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
@ Undef
Value of the register doesn't matter.
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition SPIRVUtils.h:378
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
Definition InstrProf.h:328
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition APFloat.h:1630
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI Value * simplifyInstructionWithOperands(Instruction *I, ArrayRef< Value * > NewOps, const SimplifyQuery &Q)
Like simplifyInstruction but the operands of I are replaced with NewOps.
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
bool isa_and_nonnull(const Y &Val)
Definition Casting.h:676
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:366
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
CycleInfo::CycleT Cycle
Definition CycleInfo.h:26
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
bool isPointerTy(const Type *T)
Definition SPIRVUtils.h:372
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition Local.cpp:422
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
LLVM_ABI RetainedKnowledge getKnowledgeFromUse(const Use *U, ArrayRef< Attribute::AttrKind > AttrKinds)
Return a valid Knowledge associated to the Use U if its Attribute kind is in AttrKinds.
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
Definition ModRef.h:68
PotentialValuesState< APInt > PotentialConstantIntValuesState
TargetTransformInfo TTI
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
InterleavedRange< Range > interleaved_array(const Range &R, StringRef Separator=", ")
Output range R as an array of interleaved elements.
ChangeStatus clampStateAndIndicateChange< DerefState >(DerefState &S, const DerefState &R)
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Value * getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI)
If this if a call to a free function, return the freed operand.
ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R)
Helper function to clamp a state S of type StateType with the information in R and indicate/return if...
constexpr unsigned BitWidth
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition iterator.h:368
ChangeStatus
{
Definition Attributor.h:496
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition Alignment.h:100
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
Definition Attributor.h:508
@ NONE
Do not track a dependence between source and target.
Definition Attributor.h:509
@ REQUIRED
The target cannot be valid if the source is not.
Definition Attributor.h:507
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition bit.h:347
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:872
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint().
static State getBestState(const State &SIS)
Return the best possible representable state.
bool isValidState() const override
See AbstractState::isValidState().
----------------—AAIntraFnReachability Attribute-----------------------—
ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI)
unsigned Hash
Precomputed hash for this RQI.
const Instruction * From
Start here,.
Reachable Result
and remember if it worked:
ReachabilityQueryInfo(const Instruction *From, const ToTy *To)
ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, const AA::InstExclusionSetTy *ES, bool MakeUnique)
Constructor replacement to ensure unique and stable sets are used for the cache.
const ToTy * To
reach this place,
const AA::InstExclusionSetTy * ExclusionSet
without going through any of these instructions,
An abstract interface for address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all align attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Align getKnownAlign() const
Return known alignment.
static LLVM_ABI const char ID
An abstract attribute for getting assumption information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract state for querying live call edges.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for specializing "dynamic" components of denormal_fpenv to a known denormal mod...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all dereferenceable attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for llvm::GlobalValue information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for indirect call information interference.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface to track if a value leaves it's defining function instance.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for computing reachability between functions.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
virtual bool instructionCanReach(Attributor &A, const Instruction &Inst, const Function &Fn, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Can Inst reach Fn.
An abstract interface to determine reachability of point A to B.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for identifying pointers from which loads can be marked invariant.
static LLVM_ABI const char ID
Unique ID (due to the unique address).
An abstract interface for liveness abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
static LLVM_ABI std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK)
Return the locations encoded by MLK as a readable string.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
StateType::base_t MemoryLocationsKind
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for potential address space information.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all noalias attributes.
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nocapture attributes.
@ NO_CAPTURE_MAYBE_RETURNED
If we do not capture the value in memory or through integers we can only communicate it back as a der...
@ NO_CAPTURE
If we do not capture the value in memory, through integers, or as a derived pointer we know it is not...
static LLVM_ABI const char ID
Unique ID (due to the unique address)
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI void determineFunctionCaptureCapabilities(const IRPosition &IRP, const Function &F, BitIntegerState &State)
Update State according to the capture capabilities of F for position IRP.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for nofree.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for norecurse.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An AbstractAttribute for noreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isAlignedBarrier(const CallBase &CB, bool ExecutedAligned)
Helper function to determine if CB is an aligned (GPU) barrier.
static LLVM_ABI bool isNonRelaxedAtomic(const Instruction *I)
Helper function used to determine whether an instruction is non-relaxed atomic.
static LLVM_ABI bool isNoSyncIntrinsic(const Instruction *I)
Helper function specific for intrinsics which are potentially volatile.
An abstract interface for all noundef attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See IRAttribute::isImpliedByIR.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract Attribute for determining the necessity of the convergent attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for all nonnull attributes.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
A helper containing a list of offsets computed for a Use.
A container for a list of ranges.
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
An abstract interface for struct information.
virtual bool reachesReturn() const =0
OffsetBinsTy::const_iterator const_bin_iterator
virtual const_bin_iterator begin() const =0
DenseMap< AA::RangeTy, SmallSet< unsigned, 4 > > OffsetBinsTy
static LLVM_ABI const char ID
Unique ID (due to the unique address)
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
friend struct Attributor
static LLVM_ABI const char ID
Unique ID (due to the unique address)
static LLVM_ABI Value * getSingleValue(Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, SmallVectorImpl< AA::ValueAndContext > &Values)
Extract the single value in Values if any.
An abstract interface for privatizability.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for undefined behavior.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for getting all assumption underlying objects.
virtual bool forallUnderlyingObjects(function_ref< bool(Value &)> Pred, AA::ValueScope Scope=AA::Interprocedural) const =0
Check Pred on all underlying objects in Scope collected so far.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for range value analysis.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract interface for value simplify abstract attribute.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
An abstract attribute for willreturn.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition Attributor.h:241
static constexpr int64_t Unknown
Definition Attributor.h:320
static RangeTy getUnknown()
Definition Attributor.h:247
Value * getValue() const
Definition Attributor.h:194
const Instruction * getCtxI() const
Definition Attributor.h:195
Base struct for all "concrete attribute" deductions.
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
virtual StateType & getState()=0
Return the internal abstract state for inspection.
AbstractState StateType
An interface to query the internal state of an abstract attribute.
virtual bool isAtFixpoint() const =0
Return if this abstract state is fixed, thus does not need to be updated if information changes as it...
virtual bool isValidState() const =0
Return if this abstract state is in a valid state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
DenseMapInfo< Instruction * > Base
static bool isEqual(const Access &LHS, const Access &RHS)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::function< void( const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
const Argument & getReplacedArg() const
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
The fixpoint analysis framework that orchestrates the attribute deduction.
std::function< std::optional< Value * >( const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Specialization of the integer state for a bit-wise encoding.
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Simple wrapper for a single bit (boolean) state.
static constexpr DenormalFPEnv getDefault()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
DenseMapInfo< std::pair< const Instruction *, const ToTy * > > PairDMI
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
DenseMapInfo< const AA::InstExclusionSetTy * > InstSetDMI
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
State for dereferenceable attribute.
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Helper to describe and deal with positions in the LLVM-IR.
Definition Attributor.h:593
Function * getAssociatedFunction() const
Return the associated function, if any.
Definition Attributor.h:724
static const IRPosition callsite_returned(const CallBase &CB)
Create a position describing the returned value of CB.
Definition Attributor.h:661
static const IRPosition returned(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the returned value of F.
Definition Attributor.h:643
LLVM_ABI Argument * getAssociatedArgument() const
Return the associated argument, if any.
static const IRPosition value(const Value &V, const CallBaseContext *CBContext=nullptr)
Create a position describing the value of V.
Definition Attributor.h:617
CallBase CallBaseContext
Definition Attributor.h:596
int getCalleeArgNo() const
Return the callee argument number of the associated value if it is an argument or call site argument,...
Definition Attributor.h:811
static const IRPosition inst(const Instruction &I, const CallBaseContext *CBContext=nullptr)
Create a position describing the instruction I.
Definition Attributor.h:629
static const IRPosition callsite_argument(const CallBase &CB, unsigned ArgNo)
Create a position describing the argument of CB at position ArgNo.
Definition Attributor.h:666
@ IRP_ARGUMENT
An attribute for a function argument.
Definition Attributor.h:607
@ IRP_RETURNED
An attribute for the function return value.
Definition Attributor.h:603
@ IRP_CALL_SITE
An attribute for a call site (function scope).
Definition Attributor.h:606
@ IRP_CALL_SITE_RETURNED
An attribute for a call site return value.
Definition Attributor.h:604
@ IRP_FUNCTION
An attribute for a function (scope).
Definition Attributor.h:605
@ IRP_CALL_SITE_ARGUMENT
An attribute for a call site argument.
Definition Attributor.h:608
@ IRP_INVALID
An invalid position.
Definition Attributor.h:600
Instruction * getCtxI() const
Return the context instruction, if any.
Definition Attributor.h:777
static const IRPosition argument(const Argument &Arg, const CallBaseContext *CBContext=nullptr)
Create a position describing the argument Arg.
Definition Attributor.h:650
Type * getAssociatedType() const
Return the type this abstract attribute is associated with.
Definition Attributor.h:800
static const IRPosition function(const Function &F, const CallBaseContext *CBContext=nullptr)
Create a position describing the function scope of F.
Definition Attributor.h:636
const CallBaseContext * getCallBaseContext() const
Get the call base context from the position.
Definition Attributor.h:939
Value & getAssociatedValue() const
Return the value this abstract attribute is associated with.
Definition Attributor.h:791
Value & getAnchorValue() const
Return the value this abstract attribute is anchored with.
Definition Attributor.h:710
int getCallSiteArgNo() const
Return the call site argument number of the associated value if it is an argument or call site argume...
Definition Attributor.h:820
static const IRPosition function_scope(const IRPosition &IRP, const CallBaseContext *CBContext=nullptr)
Create a position with function scope matching the "context" of IRP.
Definition Attributor.h:689
Kind getPositionKind() const
Return the associated position kind.
Definition Attributor.h:889
bool isArgumentPosition() const
Return true if the position is an argument or call site argument.
Definition Attributor.h:921
static const IRPosition callsite_function(const CallBase &CB)
Create a position describing the function scope of CB.
Definition Attributor.h:656
Function * getAnchorScope() const
Return the Function surrounding the anchor value.
Definition Attributor.h:765
Data structure to hold cached (LLVM-IR) information.
TargetLibraryInfo * getTargetLibraryInfoForFunction(const Function &F)
Return TargetLibraryInfo for function F.
bool isOnlyUsedByAssume(const Instruction &I) const
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
ConstantRange getKnown() const
Return the known state encoding.
ConstantRange getAssumed() const
Return the assumed state encoding.
base_t getAssumed() const
Return the assumed state encoding.
Helper that allows to insert a new assumption string in the known assumption set by creating a (stati...
Definition Assumptions.h:37
FPClassTest KnownFPClasses
Floating-point classes the value could be one of.
A "must be executed context" for a given program point PP is the set of instructions,...
iterator & end()
Return an universal end iterator.
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Helper to tie a abstract state implementation to an abstract attribute.
StateType & getState() override
See AbstractAttribute::getState(...).
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.
std::optional< Value * > SimplifiedAssociatedValue
An assumed simplified value.
Type * Ty
The type of the original value.