LLVM 22.0.0git
AttributorAttributes.cpp
Go to the documentation of this file.
1//===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// See the Attributor.h file comment and the class descriptions in that file for
10// more information.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/MapVector.h"
21#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
26#include "llvm/ADT/Statistic.h"
39#include "llvm/IR/Argument.h"
40#include "llvm/IR/Assumptions.h"
41#include "llvm/IR/Attributes.h"
42#include "llvm/IR/BasicBlock.h"
43#include "llvm/IR/Constant.h"
44#include "llvm/IR/Constants.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/IRBuilder.h"
49#include "llvm/IR/InlineAsm.h"
50#include "llvm/IR/InstrTypes.h"
51#include "llvm/IR/Instruction.h"
54#include "llvm/IR/IntrinsicsAMDGPU.h"
55#include "llvm/IR/IntrinsicsNVPTX.h"
56#include "llvm/IR/LLVMContext.h"
57#include "llvm/IR/MDBuilder.h"
58#include "llvm/IR/NoFolder.h"
59#include "llvm/IR/Value.h"
60#include "llvm/IR/ValueHandle.h"
75#include <cassert>
76#include <numeric>
77#include <optional>
78#include <string>
79
80using namespace llvm;
81
82#define DEBUG_TYPE "attributor"
83
85 "attributor-manifest-internal", cl::Hidden,
86 cl::desc("Manifest Attributor internal string attributes."),
87 cl::init(false));
88
89static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
91
92template <>
94
96
98 "attributor-max-potential-values", cl::Hidden,
99 cl::desc("Maximum number of potential values to be "
100 "tracked for each position."),
102 cl::init(7));
103
105 "attributor-max-potential-values-iterations", cl::Hidden,
106 cl::desc(
107 "Maximum number of iterations we keep dismantling potential values."),
108 cl::init(64));
109
110STATISTIC(NumAAs, "Number of abstract attributes created");
111STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted");
112
113// Some helper macros to deal with statistics tracking.
114//
115// Usage:
116// For simple IR attribute tracking overload trackStatistics in the abstract
117// attribute and choose the right STATS_DECLTRACK_********* macro,
118// e.g.,:
119// void trackStatistics() const override {
120// STATS_DECLTRACK_ARG_ATTR(returned)
121// }
122// If there is a single "increment" side one can use the macro
123// STATS_DECLTRACK with a custom message. If there are multiple increment
124// sides, STATS_DECL and STATS_TRACK can also be used separately.
125//
126#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
127 ("Number of " #TYPE " marked '" #NAME "'")
128#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
129#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
130#define STATS_DECL(NAME, TYPE, MSG) \
131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
132#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
133#define STATS_DECLTRACK(NAME, TYPE, MSG) \
134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)}
135#define STATS_DECLTRACK_ARG_ATTR(NAME) \
136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
137#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
138 STATS_DECLTRACK(NAME, CSArguments, \
139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
140#define STATS_DECLTRACK_FN_ATTR(NAME) \
141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
142#define STATS_DECLTRACK_CS_ATTR(NAME) \
143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
144#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
145 STATS_DECLTRACK(NAME, FunctionReturn, \
146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
147#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
148 STATS_DECLTRACK(NAME, CSReturn, \
149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
150#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
151 STATS_DECLTRACK(NAME, Floating, \
152 ("Number of floating values known to be '" #NAME "'"))
153
154// Specialization of the operator<< for abstract attributes subclasses. This
155// disambiguates situations where multiple operators are applicable.
156namespace llvm {
157#define PIPE_OPERATOR(CLASS) \
158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
159 return OS << static_cast<const AbstractAttribute &>(AA); \
160 }
161
201
202#undef PIPE_OPERATOR
203
204template <>
206 const DerefState &R) {
207 ChangeStatus CS0 =
208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
210 return CS0 | CS1;
211}
212
213} // namespace llvm
214
215static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I,
216 bool HeaderOnly, Cycle **CPtr = nullptr) {
217 if (!CI)
218 return true;
219 auto *BB = I->getParent();
220 auto *C = CI->getCycle(BB);
221 if (!C)
222 return false;
223 if (CPtr)
224 *CPtr = C;
225 return !HeaderOnly || BB == C->getHeader();
226}
227
228/// Checks if a type could have padding bytes.
229static bool isDenselyPacked(Type *Ty, const DataLayout &DL) {
230 // There is no size information, so be conservative.
231 if (!Ty->isSized())
232 return false;
233
234 // If the alloc size is not equal to the storage size, then there are padding
235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128.
236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty))
237 return false;
238
239 // FIXME: This isn't the right way to check for padding in vectors with
240 // non-byte-size elements.
241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty))
242 return isDenselyPacked(SeqTy->getElementType(), DL);
243
244 // For array types, check for padding within members.
245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty))
246 return isDenselyPacked(SeqTy->getElementType(), DL);
247
248 if (!isa<StructType>(Ty))
249 return true;
250
251 // Check for padding within and between elements of a struct.
252 StructType *StructTy = cast<StructType>(Ty);
253 const StructLayout *Layout = DL.getStructLayout(StructTy);
254 uint64_t StartPos = 0;
255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) {
256 Type *ElTy = StructTy->getElementType(I);
257 if (!isDenselyPacked(ElTy, DL))
258 return false;
259 if (StartPos != Layout->getElementOffsetInBits(I))
260 return false;
261 StartPos += DL.getTypeAllocSizeInBits(ElTy);
262 }
263
264 return true;
265}
266
267/// Get pointer operand of memory accessing instruction. If \p I is
268/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
269/// is set to false and the instruction is volatile, return nullptr.
271 bool AllowVolatile) {
272 if (!AllowVolatile && I->isVolatile())
273 return nullptr;
274
275 if (auto *LI = dyn_cast<LoadInst>(I)) {
276 return LI->getPointerOperand();
277 }
278
279 if (auto *SI = dyn_cast<StoreInst>(I)) {
280 return SI->getPointerOperand();
281 }
282
283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
284 return CXI->getPointerOperand();
285 }
286
287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
288 return RMWI->getPointerOperand();
289 }
290
291 return nullptr;
292}
293
294/// Helper function to create a pointer based on \p Ptr, and advanced by \p
295/// Offset bytes.
297 IRBuilder<NoFolder> &IRB) {
298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
299 << "-bytes\n");
300
301 if (Offset)
302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset),
303 Ptr->getName() + ".b" + Twine(Offset));
304 return Ptr;
305}
306
307static const Value *
309 const Value *Val, const DataLayout &DL, APInt &Offset,
310 bool GetMinOffset, bool AllowNonInbounds,
311 bool UseAssumed = false) {
312
313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
314 const IRPosition &Pos = IRPosition::value(V);
315 // Only track dependence if we are going to use the assumed info.
316 const AAValueConstantRange *ValueConstantRangeAA =
317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos,
318 UseAssumed ? DepClassTy::OPTIONAL
319 : DepClassTy::NONE);
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;
382 return AA::hasAssumedIRAttr<IRAttributeKind>(
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,
402 AA::ValueScope::Intraprocedural,
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;
463 return AA::hasAssumedIRAttr<IRAttributeKind>(
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;
512 return AA::hasAssumedIRAttr<IRAttributeKind>(
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)
592 *Callee, IntroduceCallBaseContext ? &CB : nullptr);
593 // If possible, use the hasAssumedIRAttr interface.
594 if (Attribute::isEnumAttrKind(IRAttributeKind)) {
595 bool IsKnown;
596 if (!AA::hasAssumedIRAttr<IRAttributeKind>(
597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown))
598 return false;
599 continue;
600 }
601
602 const AAType *AA =
603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED);
604 if (!AA)
605 return false;
606 Changed |= clampStateAndIndicateChange(S, AA->getState());
607 if (S.isAtFixpoint())
608 return S.isValidState();
609 }
610 return true;
611 };
612 if (!A.checkForAllCallees(CalleePred, *this, CB))
613 return S.indicatePessimisticFixpoint();
614 return Changed;
615 }
616};
617
618/// Helper function to accumulate uses.
619template <class AAType, typename StateType = typename AAType::StateType>
620static void followUsesInContext(AAType &AA, Attributor &A,
622 const Instruction *CtxI,
624 StateType &State) {
625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
626 for (unsigned u = 0; u < Uses.size(); ++u) {
627 const Use *U = Uses[u];
628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
630 if (Found && AA.followUseInMBEC(A, U, UserI, State))
631 Uses.insert_range(llvm::make_pointer_range(UserI->uses()));
632 }
633 }
634}
635
636/// Use the must-be-executed-context around \p I to add information into \p S.
637/// The AAType class is required to have `followUseInMBEC` method with the
638/// following signature and behaviour:
639///
640/// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I)
641/// U - Underlying use.
642/// I - The user of the \p U.
643/// Returns true if the value should be tracked transitively.
644///
645template <class AAType, typename StateType = typename AAType::StateType>
646static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S,
647 Instruction &CtxI) {
648 const Value &Val = AA.getIRPosition().getAssociatedValue();
649 if (isa<ConstantData>(Val))
650 return;
651
653 A.getInfoCache().getMustBeExecutedContextExplorer();
654 if (!Explorer)
655 return;
656
657 // Container for (transitive) uses of the associated value.
659 for (const Use &U : Val.uses())
660 Uses.insert(&U);
661
662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S);
663
664 if (S.isAtFixpoint())
665 return;
666
668 auto Pred = [&](const Instruction *I) {
669 if (const BranchInst *Br = dyn_cast<BranchInst>(I))
670 if (Br->isConditional())
671 BrInsts.push_back(Br);
672 return true;
673 };
674
675 // Here, accumulate conditional branch instructions in the context. We
676 // explore the child paths and collect the known states. The disjunction of
677 // those states can be merged to its own state. Let ParentState_i be a state
678 // to indicate the known information for an i-th branch instruction in the
679 // context. ChildStates are created for its successors respectively.
680 //
681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1}
682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2}
683 // ...
684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m}
685 //
686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m
687 //
688 // FIXME: Currently, recursive branches are not handled. For example, we
689 // can't deduce that ptr must be dereferenced in below function.
690 //
691 // void f(int a, int c, int *ptr) {
692 // if(a)
693 // if (b) {
694 // *ptr = 0;
695 // } else {
696 // *ptr = 1;
697 // }
698 // else {
699 // if (b) {
700 // *ptr = 0;
701 // } else {
702 // *ptr = 1;
703 // }
704 // }
705 // }
706
707 Explorer->checkForAllContext(&CtxI, Pred);
708 for (const BranchInst *Br : BrInsts) {
709 StateType ParentState;
710
711 // The known state of the parent state is a conjunction of children's
712 // known states so it is initialized with a best state.
713 ParentState.indicateOptimisticFixpoint();
714
715 for (const BasicBlock *BB : Br->successors()) {
716 StateType ChildState;
717
718 size_t BeforeSize = Uses.size();
719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState);
720
721 // Erase uses which only appear in the child.
722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();)
723 It = Uses.erase(It);
724
725 ParentState &= ChildState;
726 }
727
728 // Use only known state.
729 S += ParentState;
730 }
731}
732} // namespace
733
734/// ------------------------ PointerInfo ---------------------------------------
735
736namespace llvm {
737namespace AA {
738namespace PointerInfo {
739
740struct State;
741
742} // namespace PointerInfo
743} // namespace AA
744
745/// Helper for AA::PointerInfo::Access DenseMap/Set usage.
746template <>
749 static inline Access getEmptyKey();
750 static inline Access getTombstoneKey();
751 static unsigned getHashValue(const Access &A);
752 static bool isEqual(const Access &LHS, const Access &RHS);
753};
754
755/// Helper that allows RangeTy as a key in a DenseMap.
756template <> struct DenseMapInfo<AA::RangeTy> {
757 static inline AA::RangeTy getEmptyKey() {
758 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey();
759 return AA::RangeTy{EmptyKey, EmptyKey};
760 }
761
762 static inline AA::RangeTy getTombstoneKey() {
763 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey();
764 return AA::RangeTy{TombstoneKey, TombstoneKey};
765 }
766
767 static unsigned getHashValue(const AA::RangeTy &Range) {
771 }
772
773 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) {
774 return A == B;
775 }
776};
777
778/// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign
779/// but the instruction
780struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
783 static inline Access getEmptyKey();
784 static inline Access getTombstoneKey();
785 static unsigned getHashValue(const Access &A);
786 static bool isEqual(const Access &LHS, const Access &RHS);
787};
788
789} // namespace llvm
790
791/// A type to track pointer/struct usage and accesses for AAPointerInfo.
793 /// Return the best possible representable state.
794 static State getBestState(const State &SIS) { return State(); }
795
796 /// Return the worst possible representable state.
797 static State getWorstState(const State &SIS) {
798 State R;
799 R.indicatePessimisticFixpoint();
800 return R;
801 }
802
803 State() = default;
804 State(State &&SIS) = default;
805
806 const State &getAssumed() const { return *this; }
807
808 /// See AbstractState::isValidState().
809 bool isValidState() const override { return BS.isValidState(); }
810
811 /// See AbstractState::isAtFixpoint().
812 bool isAtFixpoint() const override { return BS.isAtFixpoint(); }
813
814 /// See AbstractState::indicateOptimisticFixpoint().
818 }
819
820 /// See AbstractState::indicatePessimisticFixpoint().
824 }
825
826 State &operator=(const State &R) {
827 if (this == &R)
828 return *this;
829 BS = R.BS;
830 AccessList = R.AccessList;
831 OffsetBins = R.OffsetBins;
832 RemoteIMap = R.RemoteIMap;
833 ReturnedOffsets = R.ReturnedOffsets;
834 return *this;
835 }
836
838 if (this == &R)
839 return *this;
840 std::swap(BS, R.BS);
841 std::swap(AccessList, R.AccessList);
842 std::swap(OffsetBins, R.OffsetBins);
843 std::swap(RemoteIMap, R.RemoteIMap);
844 std::swap(ReturnedOffsets, R.ReturnedOffsets);
845 return *this;
846 }
847
848 /// Add a new Access to the state at offset \p Offset and with size \p Size.
849 /// The access is associated with \p I, writes \p Content (if anything), and
850 /// is of kind \p Kind. If an Access already exists for the same \p I and same
851 /// \p RemoteI, the two are combined, potentially losing information about
852 /// offset and size. The resulting access must now be moved from its original
853 /// OffsetBin to the bin for its new offset.
854 ///
855 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise.
857 Instruction &I, std::optional<Value *> Content,
859 Instruction *RemoteI = nullptr);
860
863 int64_t numOffsetBins() const { return OffsetBins.size(); }
864
865 const AAPointerInfo::Access &getAccess(unsigned Index) const {
866 return AccessList[Index];
867 }
868
869protected:
870 // Every memory instruction results in an Access object. We maintain a list of
871 // all Access objects that we own, along with the following maps:
872 //
873 // - OffsetBins: RangeTy -> { Access }
874 // - RemoteIMap: RemoteI x LocalI -> Access
875 //
876 // A RemoteI is any instruction that accesses memory. RemoteI is different
877 // from LocalI if and only if LocalI is a call; then RemoteI is some
878 // instruction in the callgraph starting from LocalI. Multiple paths in the
879 // callgraph from LocalI to RemoteI may produce multiple accesses, but these
880 // are all combined into a single Access object. This may result in loss of
881 // information in RangeTy in the Access object.
885
886 /// Flag to determine if the underlying pointer is reaching a return statement
887 /// in the associated function or not. Returns in other functions cause
888 /// invalidation.
890
891 /// See AAPointerInfo::forallInterferingAccesses.
892 template <typename F>
895 return false;
896
897 for (const auto &It : OffsetBins) {
898 AA::RangeTy ItRange = It.getFirst();
899 if (!Range.mayOverlap(ItRange))
900 continue;
901 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown();
902 for (auto Index : It.getSecond()) {
903 auto &Access = AccessList[Index];
904 if (!CB(Access, IsExact))
905 return false;
906 }
907 }
908 return true;
909 }
910
911 /// See AAPointerInfo::forallInterferingAccesses.
912 template <typename F>
914 AA::RangeTy &Range) const {
916 return false;
917
918 auto LocalList = RemoteIMap.find(&I);
919 if (LocalList == RemoteIMap.end()) {
920 return true;
921 }
922
923 for (unsigned Index : LocalList->getSecond()) {
924 for (auto &R : AccessList[Index]) {
925 Range &= R;
926 if (Range.offsetAndSizeAreUnknown())
927 break;
928 }
929 }
931 }
932
933private:
934 /// State to track fixpoint and validity.
935 BooleanState BS;
936};
937
940 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty,
941 Instruction *RemoteI) {
942 RemoteI = RemoteI ? RemoteI : &I;
943
944 // Check if we have an access for this instruction, if not, simply add it.
945 auto &LocalList = RemoteIMap[RemoteI];
946 bool AccExists = false;
947 unsigned AccIndex = AccessList.size();
948 for (auto Index : LocalList) {
949 auto &A = AccessList[Index];
950 if (A.getLocalInst() == &I) {
951 AccExists = true;
952 AccIndex = Index;
953 break;
954 }
955 }
956
957 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) {
958 LLVM_DEBUG(if (ToAdd.size()) dbgs()
959 << "[AAPointerInfo] Inserting access in new offset bins\n";);
960
961 for (auto Key : ToAdd) {
962 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
963 OffsetBins[Key].insert(AccIndex);
964 }
965 };
966
967 if (!AccExists) {
968 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty);
969 assert((AccessList.size() == AccIndex + 1) &&
970 "New Access should have been at AccIndex");
971 LocalList.push_back(AccIndex);
972 AddToBins(AccessList[AccIndex].getRanges());
974 }
975
976 // Combine the new Access with the existing Access, and then update the
977 // mapping in the offset bins.
978 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty);
979 auto &Current = AccessList[AccIndex];
980 auto Before = Current;
981 Current &= Acc;
982 if (Current == Before)
984
985 auto &ExistingRanges = Before.getRanges();
986 auto &NewRanges = Current.getRanges();
987
988 // Ranges that are in the old access but not the new access need to be removed
989 // from the offset bins.
991 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove);
992 LLVM_DEBUG(if (ToRemove.size()) dbgs()
993 << "[AAPointerInfo] Removing access from old offset bins\n";);
994
995 for (auto Key : ToRemove) {
996 LLVM_DEBUG(dbgs() << " key " << Key << "\n");
997 assert(OffsetBins.count(Key) && "Existing Access must be in some bin.");
998 auto &Bin = OffsetBins[Key];
999 assert(Bin.count(AccIndex) &&
1000 "Expected bin to actually contain the Access.");
1001 Bin.erase(AccIndex);
1002 }
1003
1004 // Ranges that are in the new access but not the old access need to be added
1005 // to the offset bins.
1007 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd);
1008 AddToBins(ToAdd);
1009 return ChangeStatus::CHANGED;
1010}
1011
1012namespace {
1013
1014#ifndef NDEBUG
1016 const AAPointerInfo::OffsetInfo &OI) {
1018 return OS;
1019}
1020#endif // NDEBUG
1021
1022struct AAPointerInfoImpl
1023 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> {
1025 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
1026
1027 /// See AbstractAttribute::getAsStr().
1028 const std::string getAsStr(Attributor *A) const override {
1029 return std::string("PointerInfo ") +
1030 (isValidState() ? (std::string("#") +
1031 std::to_string(OffsetBins.size()) + " bins")
1032 : "<invalid>") +
1033 (reachesReturn()
1034 ? (" (returned:" +
1035 join(map_range(ReturnedOffsets,
1036 [](int64_t O) { return std::to_string(O); }),
1037 ", ") +
1038 ")")
1039 : "");
1040 }
1041
1042 /// See AbstractAttribute::manifest(...).
1043 ChangeStatus manifest(Attributor &A) override {
1044 return AAPointerInfo::manifest(A);
1045 }
1046
1047 virtual const_bin_iterator begin() const override { return State::begin(); }
1048 virtual const_bin_iterator end() const override { return State::end(); }
1049 virtual int64_t numOffsetBins() const override {
1050 return State::numOffsetBins();
1051 }
1052 virtual bool reachesReturn() const override {
1053 return !ReturnedOffsets.isUnassigned();
1054 }
1055 virtual void addReturnedOffsetsTo(OffsetInfo &OI) const override {
1056 if (ReturnedOffsets.isUnknown()) {
1057 OI.setUnknown();
1058 return;
1059 }
1060
1061 OffsetInfo MergedOI;
1062 for (auto Offset : ReturnedOffsets) {
1063 OffsetInfo TmpOI = OI;
1064 TmpOI.addToAll(Offset);
1065 MergedOI.merge(TmpOI);
1066 }
1067 OI = std::move(MergedOI);
1068 }
1069
1070 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) {
1071 if (ReturnedOffsets.isUnknown())
1072 return ChangeStatus::UNCHANGED;
1073 if (ReachedReturnedOffsets.isUnknown()) {
1074 ReturnedOffsets.setUnknown();
1075 return ChangeStatus::CHANGED;
1076 }
1077 if (ReturnedOffsets.merge(ReachedReturnedOffsets))
1078 return ChangeStatus::CHANGED;
1079 return ChangeStatus::UNCHANGED;
1080 }
1081
1082 bool forallInterferingAccesses(
1084 function_ref<bool(const AAPointerInfo::Access &, bool)> CB)
1085 const override {
1086 return State::forallInterferingAccesses(Range, CB);
1087 }
1088
1089 bool forallInterferingAccesses(
1090 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I,
1091 bool FindInterferingWrites, bool FindInterferingReads,
1092 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo,
1094 function_ref<bool(const Access &)> SkipCB) const override {
1095 HasBeenWrittenTo = false;
1096
1097 SmallPtrSet<const Access *, 8> DominatingWrites;
1098 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses;
1099
1100 Function &Scope = *I.getFunction();
1101 bool IsKnownNoSync;
1102 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>(
1103 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1104 IsKnownNoSync);
1105 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
1106 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
1107 bool AllInSameNoSyncFn = IsAssumedNoSync;
1108 bool InstIsExecutedByInitialThreadOnly =
1109 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
1110
1111 // If the function is not ending in aligned barriers, we need the stores to
1112 // be in aligned barriers. The load being in one is not sufficient since the
1113 // store might be executed by a thread that disappears after, causing the
1114 // aligned barrier guarding the load to unblock and the load to read a value
1115 // that has no CFG path to the load.
1116 bool InstIsExecutedInAlignedRegion =
1117 FindInterferingReads && ExecDomainAA &&
1118 ExecDomainAA->isExecutedInAlignedRegion(A, I);
1119
1120 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
1121 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1122
1123 InformationCache &InfoCache = A.getInfoCache();
1124 bool IsThreadLocalObj =
1125 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this);
1126
1127 // Helper to determine if we need to consider threading, which we cannot
1128 // right now. However, if the function is (assumed) nosync or the thread
1129 // executing all instructions is the main thread only we can ignore
1130 // threading. Also, thread-local objects do not require threading reasoning.
1131 // Finally, we can ignore threading if either access is executed in an
1132 // aligned region.
1133 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
1134 if (IsThreadLocalObj || AllInSameNoSyncFn)
1135 return true;
1136 const auto *FnExecDomainAA =
1137 I.getFunction() == &Scope
1138 ? ExecDomainAA
1139 : A.lookupAAFor<AAExecutionDomain>(
1140 IRPosition::function(*I.getFunction()), &QueryingAA,
1141 DepClassTy::NONE);
1142 if (!FnExecDomainAA)
1143 return false;
1144 if (InstIsExecutedInAlignedRegion ||
1145 (FindInterferingWrites &&
1146 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) {
1147 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1148 return true;
1149 }
1150 if (InstIsExecutedByInitialThreadOnly &&
1151 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
1153 return true;
1154 }
1155 return false;
1156 };
1157
1158 // Helper to determine if the access is executed by the same thread as the
1159 // given instruction, for now it is sufficient to avoid any potential
1160 // threading effects as we cannot deal with them anyway.
1161 auto CanIgnoreThreading = [&](const Access &Acc) -> bool {
1162 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) ||
1163 (Acc.getRemoteInst() != Acc.getLocalInst() &&
1164 CanIgnoreThreadingForInst(*Acc.getLocalInst()));
1165 };
1166
1167 // TODO: Use inter-procedural reachability and dominance.
1168 bool IsKnownNoRecurse;
1169 AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1170 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL,
1171 IsKnownNoRecurse);
1172
1173 // TODO: Use reaching kernels from AAKernelInfo (or move it to
1174 // AAExecutionDomain) such that we allow scopes other than kernels as long
1175 // as the reaching kernels are disjoint.
1176 bool InstInKernel = A.getInfoCache().isKernel(Scope);
1177 bool ObjHasKernelLifetime = false;
1178 const bool UseDominanceReasoning =
1179 FindInterferingWrites && IsKnownNoRecurse;
1180 const DominatorTree *DT =
1182
1183 // Helper to check if a value has "kernel lifetime", that is it will not
1184 // outlive a GPU kernel. This is true for shared, constant, and local
1185 // globals on AMD and NVIDIA GPUs.
1186 auto HasKernelLifetime = [&](Value *V, Module &M) {
1187 if (!AA::isGPU(M))
1188 return false;
1189 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) {
1190 case AA::GPUAddressSpace::Shared:
1191 case AA::GPUAddressSpace::Constant:
1192 case AA::GPUAddressSpace::Local:
1193 return true;
1194 default:
1195 return false;
1196 };
1197 };
1198
1199 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query
1200 // to determine if we should look at reachability from the callee. For
1201 // certain pointers we know the lifetime and we do not have to step into the
1202 // callee to determine reachability as the pointer would be dead in the
1203 // callee. See the conditional initialization below.
1204 std::function<bool(const Function &)> IsLiveInCalleeCB;
1205
1206 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) {
1207 // If the alloca containing function is not recursive the alloca
1208 // must be dead in the callee.
1209 const Function *AIFn = AI->getFunction();
1210 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn);
1211 bool IsKnownNoRecurse;
1212 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
1213 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL,
1214 IsKnownNoRecurse)) {
1215 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; };
1216 }
1217 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) {
1218 // If the global has kernel lifetime we can stop if we reach a kernel
1219 // as it is "dead" in the (unknown) callees.
1220 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent());
1221 if (ObjHasKernelLifetime)
1222 IsLiveInCalleeCB = [&A](const Function &Fn) {
1223 return !A.getInfoCache().isKernel(Fn);
1224 };
1225 }
1226
1227 // Set of accesses/instructions that will overwrite the result and are
1228 // therefore blockers in the reachability traversal.
1229 AA::InstExclusionSetTy ExclusionSet;
1230
1231 auto AccessCB = [&](const Access &Acc, bool Exact) {
1232 Function *AccScope = Acc.getRemoteInst()->getFunction();
1233 bool AccInSameScope = AccScope == &Scope;
1234
1235 // If the object has kernel lifetime we can ignore accesses only reachable
1236 // by other kernels. For now we only skip accesses *in* other kernels.
1237 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope &&
1238 A.getInfoCache().isKernel(*AccScope))
1239 return true;
1240
1241 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) {
1242 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption()))
1243 ExclusionSet.insert(Acc.getRemoteInst());
1244 }
1245
1246 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) &&
1247 (!FindInterferingReads || !Acc.isRead()))
1248 return true;
1249
1250 bool Dominates = FindInterferingWrites && DT && Exact &&
1251 Acc.isMustAccess() && AccInSameScope &&
1252 DT->dominates(Acc.getRemoteInst(), &I);
1253 if (Dominates)
1254 DominatingWrites.insert(&Acc);
1255
1256 // Track if all interesting accesses are in the same `nosync` function as
1257 // the given instruction.
1258 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope;
1259
1260 InterferingAccesses.push_back({&Acc, Exact});
1261 return true;
1262 };
1263 if (!State::forallInterferingAccesses(I, AccessCB, Range))
1264 return false;
1265
1266 HasBeenWrittenTo = !DominatingWrites.empty();
1267
1268 // Dominating writes form a chain, find the least/lowest member.
1269 Instruction *LeastDominatingWriteInst = nullptr;
1270 for (const Access *Acc : DominatingWrites) {
1271 if (!LeastDominatingWriteInst) {
1272 LeastDominatingWriteInst = Acc->getRemoteInst();
1273 } else if (DT->dominates(LeastDominatingWriteInst,
1274 Acc->getRemoteInst())) {
1275 LeastDominatingWriteInst = Acc->getRemoteInst();
1276 }
1277 }
1278
1279 // Helper to determine if we can skip a specific write access.
1280 auto CanSkipAccess = [&](const Access &Acc, bool Exact) {
1281 if (SkipCB && SkipCB(Acc))
1282 return true;
1283 if (!CanIgnoreThreading(Acc))
1284 return false;
1285
1286 // Check read (RAW) dependences and write (WAR) dependences as necessary.
1287 // If we successfully excluded all effects we are interested in, the
1288 // access can be skipped.
1289 bool ReadChecked = !FindInterferingReads;
1290 bool WriteChecked = !FindInterferingWrites;
1291
1292 // If the instruction cannot reach the access, the former does not
1293 // interfere with what the access reads.
1294 if (!ReadChecked) {
1295 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA,
1296 &ExclusionSet, IsLiveInCalleeCB))
1297 ReadChecked = true;
1298 }
1299 // If the instruction cannot be reach from the access, the latter does not
1300 // interfere with what the instruction reads.
1301 if (!WriteChecked) {
1302 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA,
1303 &ExclusionSet, IsLiveInCalleeCB))
1304 WriteChecked = true;
1305 }
1306
1307 // If we still might be affected by the write of the access but there are
1308 // dominating writes in the function of the instruction
1309 // (HasBeenWrittenTo), we can try to reason that the access is overwritten
1310 // by them. This would have happend above if they are all in the same
1311 // function, so we only check the inter-procedural case. Effectively, we
1312 // want to show that there is no call after the dominting write that might
1313 // reach the access, and when it returns reach the instruction with the
1314 // updated value. To this end, we iterate all call sites, check if they
1315 // might reach the instruction without going through another access
1316 // (ExclusionSet) and at the same time might reach the access. However,
1317 // that is all part of AAInterFnReachability.
1318 if (!WriteChecked && HasBeenWrittenTo &&
1319 Acc.getRemoteInst()->getFunction() != &Scope) {
1320
1321 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>(
1322 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
1323 if (FnReachabilityAA) {
1324 // Without going backwards in the call tree, can we reach the access
1325 // from the least dominating write. Do not allow to pass the
1326 // instruction itself either.
1327 bool Inserted = ExclusionSet.insert(&I).second;
1328
1329 if (!FnReachabilityAA->instructionCanReach(
1330 A, *LeastDominatingWriteInst,
1331 *Acc.getRemoteInst()->getFunction(), &ExclusionSet))
1332 WriteChecked = true;
1333
1334 if (Inserted)
1335 ExclusionSet.erase(&I);
1336 }
1337 }
1338
1339 if (ReadChecked && WriteChecked)
1340 return true;
1341
1342 if (!DT || !UseDominanceReasoning)
1343 return false;
1344 if (!DominatingWrites.count(&Acc))
1345 return false;
1346 return LeastDominatingWriteInst != Acc.getRemoteInst();
1347 };
1348
1349 // Run the user callback on all accesses we cannot skip and return if
1350 // that succeeded for all or not.
1351 for (auto &It : InterferingAccesses) {
1352 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) ||
1353 !CanSkipAccess(*It.first, It.second)) {
1354 if (!UserCB(*It.first, It.second))
1355 return false;
1356 }
1357 }
1358 return true;
1359 }
1360
1361 ChangeStatus translateAndAddStateFromCallee(Attributor &A,
1362 const AAPointerInfo &OtherAA,
1363 CallBase &CB) {
1364 using namespace AA::PointerInfo;
1365 if (!OtherAA.getState().isValidState() || !isValidState())
1366 return indicatePessimisticFixpoint();
1367
1368 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1369 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1370 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr();
1371 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets);
1372
1373 // Combine the accesses bin by bin.
1374 const auto &State = OtherAAImpl.getState();
1375 for (const auto &It : State) {
1376 for (auto Index : It.getSecond()) {
1377 const auto &RAcc = State.getAccess(Index);
1378 if (IsByval && !RAcc.isRead())
1379 continue;
1380 bool UsedAssumedInformation = false;
1381 AccessKind AK = RAcc.getKind();
1382 auto Content = A.translateArgumentToCallSiteContent(
1383 RAcc.getContent(), CB, *this, UsedAssumedInformation);
1384 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW));
1385 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST));
1386
1387 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK,
1388 RAcc.getType(), RAcc.getRemoteInst());
1389 }
1390 }
1391 return Changed;
1392 }
1393
1394 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA,
1395 const OffsetInfo &Offsets, CallBase &CB,
1396 bool IsMustAcc) {
1397 using namespace AA::PointerInfo;
1398 if (!OtherAA.getState().isValidState() || !isValidState())
1399 return indicatePessimisticFixpoint();
1400
1401 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA);
1402
1403 // Combine the accesses bin by bin.
1404 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1405 const auto &State = OtherAAImpl.getState();
1406 for (const auto &It : State) {
1407 for (auto Index : It.getSecond()) {
1408 const auto &RAcc = State.getAccess(Index);
1409 if (!IsMustAcc && RAcc.isAssumption())
1410 continue;
1411 for (auto Offset : Offsets) {
1412 auto NewRanges = Offset == AA::RangeTy::Unknown
1414 : RAcc.getRanges();
1415 if (!NewRanges.isUnknown()) {
1416 NewRanges.addToAllOffsets(Offset);
1417 }
1418 AccessKind AK = RAcc.getKind();
1419 if (!IsMustAcc)
1420 AK = AccessKind((AK & ~AK_MUST) | AK_MAY);
1421 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK,
1422 RAcc.getType(), RAcc.getRemoteInst());
1423 }
1424 }
1425 }
1426 return Changed;
1427 }
1428
1429 /// Statistic tracking for all AAPointerInfo implementations.
1430 /// See AbstractAttribute::trackStatistics().
1431 void trackPointerInfoStatistics(const IRPosition &IRP) const {}
1432
1433 /// Dump the state into \p O.
1434 void dumpState(raw_ostream &O) {
1435 for (auto &It : OffsetBins) {
1436 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size
1437 << "] : " << It.getSecond().size() << "\n";
1438 for (auto AccIndex : It.getSecond()) {
1439 auto &Acc = AccessList[AccIndex];
1440 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n";
1441 if (Acc.getLocalInst() != Acc.getRemoteInst())
1442 O << " --> " << *Acc.getRemoteInst()
1443 << "\n";
1444 if (!Acc.isWrittenValueYetUndetermined()) {
1445 if (isa_and_nonnull<Function>(Acc.getWrittenValue()))
1446 O << " - c: func " << Acc.getWrittenValue()->getName()
1447 << "\n";
1448 else if (Acc.getWrittenValue())
1449 O << " - c: " << *Acc.getWrittenValue() << "\n";
1450 else
1451 O << " - c: <unknown>\n";
1452 }
1453 }
1454 }
1455 }
1456};
1457
1458struct AAPointerInfoFloating : public AAPointerInfoImpl {
1460 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A)
1461 : AAPointerInfoImpl(IRP, A) {}
1462
1463 /// Deal with an access and signal if it was handled successfully.
1464 bool handleAccess(Attributor &A, Instruction &I,
1465 std::optional<Value *> Content, AccessKind Kind,
1466 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed,
1467 Type &Ty) {
1468 using namespace AA::PointerInfo;
1470 const DataLayout &DL = A.getDataLayout();
1471 TypeSize AccessSize = DL.getTypeStoreSize(&Ty);
1472 if (!AccessSize.isScalable())
1473 Size = AccessSize.getFixedValue();
1474
1475 // Make a strictly ascending list of offsets as required by addAccess()
1476 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end());
1477 llvm::sort(OffsetsSorted);
1478
1479 VectorType *VT = dyn_cast<VectorType>(&Ty);
1480 if (!VT || VT->getElementCount().isScalable() ||
1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) ||
1482 (*Content)->getType() != VT ||
1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) {
1484 Changed =
1485 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty);
1486 } else {
1487 // Handle vector stores with constant content element-wise.
1488 // TODO: We could look for the elements or create instructions
1489 // representing them.
1490 // TODO: We need to push the Content into the range abstraction
1491 // (AA::RangeTy) to allow different content values for different
1492 // ranges. ranges. Hence, support vectors storing different values.
1493 Type *ElementType = VT->getElementType();
1494 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue();
1495 auto *ConstContent = cast<Constant>(*Content);
1496 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext());
1497 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end());
1498
1499 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) {
1500 Value *ElementContent = ConstantExpr::getExtractElement(
1501 ConstContent, ConstantInt::get(Int32Ty, i));
1502
1503 // Add the element access.
1504 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I,
1505 ElementContent, Kind, ElementType);
1506
1507 // Advance the offsets for the next element.
1508 for (auto &ElementOffset : ElementOffsets)
1509 ElementOffset += ElementSize;
1510 }
1511 }
1512 return true;
1513 };
1514
1515 /// See AbstractAttribute::updateImpl(...).
1516 ChangeStatus updateImpl(Attributor &A) override;
1517
1518 /// If the indices to \p GEP can be traced to constants, incorporate all
1519 /// of these into \p UsrOI.
1520 ///
1521 /// \return true iff \p UsrOI is updated.
1522 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL,
1523 OffsetInfo &UsrOI, const OffsetInfo &PtrOI,
1524 const GEPOperator *GEP);
1525
1526 /// See AbstractAttribute::trackStatistics()
1527 void trackStatistics() const override {
1528 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1529 }
1530};
1531
1532bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A,
1533 const DataLayout &DL,
1534 OffsetInfo &UsrOI,
1535 const OffsetInfo &PtrOI,
1536 const GEPOperator *GEP) {
1537 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());
1538 SmallMapVector<Value *, APInt, 4> VariableOffsets;
1539 APInt ConstantOffset(BitWidth, 0);
1540
1541 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() &&
1542 "Don't look for constant values if the offset has already been "
1543 "determined to be unknown.");
1544
1545 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) {
1546 UsrOI.setUnknown();
1547 return true;
1548 }
1549
1550 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is "
1551 << (VariableOffsets.empty() ? "" : "not") << " constant "
1552 << *GEP << "\n");
1553
1554 auto Union = PtrOI;
1555 Union.addToAll(ConstantOffset.getSExtValue());
1556
1557 // Each VI in VariableOffsets has a set of potential constant values. Every
1558 // combination of elements, picked one each from these sets, is separately
1559 // added to the original set of offsets, thus resulting in more offsets.
1560 for (const auto &VI : VariableOffsets) {
1561 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
1562 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL);
1563 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) {
1564 UsrOI.setUnknown();
1565 return true;
1566 }
1567
1568 // UndefValue is treated as a zero, which leaves Union as is.
1569 if (PotentialConstantsAA->undefIsContained())
1570 continue;
1571
1572 // We need at least one constant in every set to compute an actual offset.
1573 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that
1574 // don't actually exist. In other words, the absence of constant values
1575 // implies that the operation can be assumed dead for now.
1576 auto &AssumedSet = PotentialConstantsAA->getAssumedSet();
1577 if (AssumedSet.empty())
1578 return false;
1579
1580 OffsetInfo Product;
1581 for (const auto &ConstOffset : AssumedSet) {
1582 auto CopyPerOffset = Union;
1583 CopyPerOffset.addToAll(ConstOffset.getSExtValue() *
1584 VI.second.getZExtValue());
1585 Product.merge(CopyPerOffset);
1586 }
1587 Union = Product;
1588 }
1589
1590 UsrOI = std::move(Union);
1591 return true;
1592}
1593
1594ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) {
1595 using namespace AA::PointerInfo;
1597 const DataLayout &DL = A.getDataLayout();
1598 Value &AssociatedValue = getAssociatedValue();
1599
1600 DenseMap<Value *, OffsetInfo> OffsetInfoMap;
1601 OffsetInfoMap[&AssociatedValue].insert(0);
1602
1603 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) {
1604 // One does not simply walk into a map and assign a reference to a possibly
1605 // new location. That can cause an invalidation before the assignment
1606 // happens, like so:
1607 //
1608 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */
1609 //
1610 // The RHS is a reference that may be invalidated by an insertion caused by
1611 // the LHS. So we ensure that the side-effect of the LHS happens first.
1612
1613 assert(OffsetInfoMap.contains(CurPtr) &&
1614 "CurPtr does not exist in the map!");
1615
1616 auto &UsrOI = OffsetInfoMap[Usr];
1617 auto &PtrOI = OffsetInfoMap[CurPtr];
1618 assert(!PtrOI.isUnassigned() &&
1619 "Cannot pass through if the input Ptr was not visited!");
1620 UsrOI.merge(PtrOI);
1621 Follow = true;
1622 return true;
1623 };
1624
1625 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
1626 Value *CurPtr = U.get();
1627 User *Usr = U.getUser();
1628 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr
1629 << "\n");
1630 assert(OffsetInfoMap.count(CurPtr) &&
1631 "The current pointer offset should have been seeded!");
1632 assert(!OffsetInfoMap[CurPtr].isUnassigned() &&
1633 "Current pointer should be assigned");
1634
1635 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) {
1636 if (CE->isCast())
1637 return HandlePassthroughUser(Usr, CurPtr, Follow);
1638 if (!isa<GEPOperator>(CE)) {
1639 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE
1640 << "\n");
1641 return false;
1642 }
1643 }
1644 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) {
1645 // Note the order here, the Usr access might change the map, CurPtr is
1646 // already in it though.
1647 auto &UsrOI = OffsetInfoMap[Usr];
1648 auto &PtrOI = OffsetInfoMap[CurPtr];
1649
1650 if (UsrOI.isUnknown())
1651 return true;
1652
1653 if (PtrOI.isUnknown()) {
1654 Follow = true;
1655 UsrOI.setUnknown();
1656 return true;
1657 }
1658
1659 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP);
1660 return true;
1661 }
1662 if (isa<PtrToIntInst>(Usr))
1663 return false;
1664 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr))
1665 return HandlePassthroughUser(Usr, CurPtr, Follow);
1666 // Returns are allowed if they are in the associated functions. Users can
1667 // then check the call site return. Returns from other functions can't be
1668 // tracked and are cause for invalidation.
1669 if (auto *RI = dyn_cast<ReturnInst>(Usr)) {
1670 if (RI->getFunction() == getAssociatedFunction()) {
1671 auto &PtrOI = OffsetInfoMap[CurPtr];
1672 Changed |= setReachesReturn(PtrOI);
1673 return true;
1674 }
1675 return false;
1676 }
1677
1678 // For PHIs we need to take care of the recurrence explicitly as the value
1679 // might change while we iterate through a loop. For now, we give up if
1680 // the PHI is not invariant.
1681 if (auto *PHI = dyn_cast<PHINode>(Usr)) {
1682 // Note the order here, the Usr access might change the map, CurPtr is
1683 // already in it though.
1684 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI);
1685 auto &UsrOI = PhiIt->second;
1686 auto &PtrOI = OffsetInfoMap[CurPtr];
1687
1688 // Check if the PHI operand has already an unknown offset as we can't
1689 // improve on that anymore.
1690 if (PtrOI.isUnknown()) {
1691 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown "
1692 << *CurPtr << " in " << *PHI << "\n");
1693 Follow = !UsrOI.isUnknown();
1694 UsrOI.setUnknown();
1695 return true;
1696 }
1697
1698 // Check if the PHI is invariant (so far).
1699 if (UsrOI == PtrOI) {
1700 assert(!PtrOI.isUnassigned() &&
1701 "Cannot assign if the current Ptr was not visited!");
1702 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)");
1703 return true;
1704 }
1705
1706 // Check if the PHI operand can be traced back to AssociatedValue.
1707 APInt Offset(
1708 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()),
1709 0);
1710 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets(
1711 DL, Offset, /* AllowNonInbounds */ true);
1712 auto It = OffsetInfoMap.find(CurPtrBase);
1713 if (It == OffsetInfoMap.end()) {
1714 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex "
1715 << *CurPtr << " in " << *PHI
1716 << " (base: " << *CurPtrBase << ")\n");
1717 UsrOI.setUnknown();
1718 Follow = true;
1719 return true;
1720 }
1721
1722 // Check if the PHI operand is not dependent on the PHI itself. Every
1723 // recurrence is a cyclic net of PHIs in the data flow, and has an
1724 // equivalent Cycle in the control flow. One of those PHIs must be in the
1725 // header of that control flow Cycle. This is independent of the choice of
1726 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in
1727 // every Cycle header; if such a node is marked unknown, this will
1728 // eventually propagate through the whole net of PHIs in the recurrence.
1729 const auto *CI =
1730 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
1731 *PHI->getFunction());
1732 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) {
1733 auto BaseOI = It->getSecond();
1734 BaseOI.addToAll(Offset.getZExtValue());
1735 if (IsFirstPHIUser || BaseOI == UsrOI) {
1736 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr
1737 << " in " << *Usr << "\n");
1738 return HandlePassthroughUser(Usr, CurPtr, Follow);
1739 }
1740
1741 LLVM_DEBUG(
1742 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch "
1743 << *CurPtr << " in " << *PHI << "\n");
1744 UsrOI.setUnknown();
1745 Follow = true;
1746 return true;
1747 }
1748
1749 UsrOI.merge(PtrOI);
1750 Follow = true;
1751 return true;
1752 }
1753
1754 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) {
1755 // If the access is to a pointer that may or may not be the associated
1756 // value, e.g. due to a PHI, we cannot assume it will be read.
1757 AccessKind AK = AccessKind::AK_R;
1758 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1759 AK = AccessKind(AK | AccessKind::AK_MUST);
1760 else
1761 AK = AccessKind(AK | AccessKind::AK_MAY);
1762 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK,
1763 OffsetInfoMap[CurPtr].Offsets, Changed,
1764 *LoadI->getType()))
1765 return false;
1766
1767 auto IsAssumption = [](Instruction &I) {
1768 if (auto *II = dyn_cast<IntrinsicInst>(&I))
1769 return II->isAssumeLikeIntrinsic();
1770 return false;
1771 };
1772
1773 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) {
1774 // Check if the assumption and the load are executed together without
1775 // memory modification.
1776 do {
1777 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI))
1778 return true;
1779 FromI = FromI->getNextNode();
1780 } while (FromI && FromI != ToI);
1781 return false;
1782 };
1783
1784 BasicBlock *BB = LoadI->getParent();
1785 auto IsValidAssume = [&](IntrinsicInst &IntrI) {
1786 if (IntrI.getIntrinsicID() != Intrinsic::assume)
1787 return false;
1788 BasicBlock *IntrBB = IntrI.getParent();
1789 if (IntrI.getParent() == BB) {
1790 if (IsImpactedInRange(LoadI->getNextNode(), &IntrI))
1791 return false;
1792 } else {
1793 auto PredIt = pred_begin(IntrBB);
1794 if (PredIt == pred_end(IntrBB))
1795 return false;
1796 if ((*PredIt) != BB)
1797 return false;
1798 if (++PredIt != pred_end(IntrBB))
1799 return false;
1800 for (auto *SuccBB : successors(BB)) {
1801 if (SuccBB == IntrBB)
1802 continue;
1803 if (isa<UnreachableInst>(SuccBB->getTerminator()))
1804 continue;
1805 return false;
1806 }
1807 if (IsImpactedInRange(LoadI->getNextNode(), BB->getTerminator()))
1808 return false;
1809 if (IsImpactedInRange(&IntrBB->front(), &IntrI))
1810 return false;
1811 }
1812 return true;
1813 };
1814
1815 std::pair<Value *, IntrinsicInst *> Assumption;
1816 for (const Use &LoadU : LoadI->uses()) {
1817 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) {
1818 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual())
1819 continue;
1820 for (const Use &CmpU : CmpI->uses()) {
1821 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) {
1822 if (!IsValidAssume(*IntrI))
1823 continue;
1824 int Idx = CmpI->getOperandUse(0) == LoadU;
1825 Assumption = {CmpI->getOperand(Idx), IntrI};
1826 break;
1827 }
1828 }
1829 }
1830 if (Assumption.first)
1831 break;
1832 }
1833
1834 // Check if we found an assumption associated with this load.
1835 if (!Assumption.first || !Assumption.second)
1836 return true;
1837
1838 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found "
1839 << *Assumption.second << ": " << *LoadI
1840 << " == " << *Assumption.first << "\n");
1841 bool UsedAssumedInformation = false;
1842 std::optional<Value *> Content = nullptr;
1843 if (Assumption.first)
1844 Content =
1845 A.getAssumedSimplified(*Assumption.first, *this,
1846 UsedAssumedInformation, AA::Interprocedural);
1847 return handleAccess(
1848 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION,
1849 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType());
1850 }
1851
1852 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy,
1853 ArrayRef<Value *> OtherOps, AccessKind AK) {
1854 for (auto *OtherOp : OtherOps) {
1855 if (OtherOp == CurPtr) {
1856 LLVM_DEBUG(
1857 dbgs()
1858 << "[AAPointerInfo] Escaping use in store like instruction " << I
1859 << "\n");
1860 return false;
1861 }
1862 }
1863
1864 // If the access is to a pointer that may or may not be the associated
1865 // value, e.g. due to a PHI, we cannot assume it will be written.
1866 if (getUnderlyingObject(CurPtr) == &AssociatedValue)
1867 AK = AccessKind(AK | AccessKind::AK_MUST);
1868 else
1869 AK = AccessKind(AK | AccessKind::AK_MAY);
1870 bool UsedAssumedInformation = false;
1871 std::optional<Value *> Content = nullptr;
1872 if (ValueOp)
1873 Content = A.getAssumedSimplified(
1874 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural);
1875 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets,
1876 Changed, ValueTy);
1877 };
1878
1879 if (auto *StoreI = dyn_cast<StoreInst>(Usr))
1880 return HandleStoreLike(*StoreI, StoreI->getValueOperand(),
1881 *StoreI->getValueOperand()->getType(),
1882 {StoreI->getValueOperand()}, AccessKind::AK_W);
1883 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr))
1884 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(),
1885 {RMWI->getValOperand()}, AccessKind::AK_RW);
1886 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr))
1887 return HandleStoreLike(
1888 *CXI, nullptr, *CXI->getNewValOperand()->getType(),
1889 {CXI->getCompareOperand(), CXI->getNewValOperand()},
1890 AccessKind::AK_RW);
1891
1892 if (auto *CB = dyn_cast<CallBase>(Usr)) {
1893 if (CB->isLifetimeStartOrEnd())
1894 return true;
1895 const auto *TLI =
1896 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction());
1897 if (getFreedOperand(CB, TLI) == U)
1898 return true;
1899 if (CB->isArgOperand(&U)) {
1900 unsigned ArgNo = CB->getArgOperandNo(&U);
1901 const auto *CSArgPI = A.getAAFor<AAPointerInfo>(
1902 *this, IRPosition::callsite_argument(*CB, ArgNo),
1904 if (!CSArgPI)
1905 return false;
1906 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue);
1907 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB,
1908 IsArgMustAcc) |
1909 Changed;
1910 if (!CSArgPI->reachesReturn())
1911 return isValidState();
1912
1914 if (!Callee || Callee->arg_size() <= ArgNo)
1915 return false;
1916 bool UsedAssumedInformation = false;
1917 auto ReturnedValue = A.getAssumedSimplified(
1918 IRPosition::returned(*Callee), *this, UsedAssumedInformation,
1920 auto *ReturnedArg =
1921 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr));
1922 auto *Arg = Callee->getArg(ArgNo);
1923 if (ReturnedArg && Arg != ReturnedArg)
1924 return true;
1925 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg);
1926 const auto *CSRetPI = A.getAAFor<AAPointerInfo>(
1928 if (!CSRetPI)
1929 return false;
1930 OffsetInfo OI = OffsetInfoMap[CurPtr];
1931 CSArgPI->addReturnedOffsetsTo(OI);
1932 Changed =
1933 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed;
1934 return isValidState();
1935 }
1936 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB
1937 << "\n");
1938 return false;
1939 }
1940
1941 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n");
1942 return false;
1943 };
1944 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
1945 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!");
1946 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged");
1947 if (OffsetInfoMap.count(NewU)) {
1948 LLVM_DEBUG({
1949 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) {
1950 dbgs() << "[AAPointerInfo] Equivalent use callback failed: "
1951 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU]
1952 << "\n";
1953 }
1954 });
1955 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU];
1956 }
1957 bool Unused;
1958 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused);
1959 };
1960 if (!A.checkForAllUses(UsePred, *this, AssociatedValue,
1961 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL,
1962 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
1963 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n");
1964 return indicatePessimisticFixpoint();
1965 }
1966
1967 LLVM_DEBUG({
1968 dbgs() << "Accesses by bin after update:\n";
1969 dumpState(dbgs());
1970 });
1971
1972 return Changed;
1973}
1974
1975struct AAPointerInfoReturned final : AAPointerInfoImpl {
1976 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A)
1977 : AAPointerInfoImpl(IRP, A) {}
1978
1979 /// See AbstractAttribute::updateImpl(...).
1980 ChangeStatus updateImpl(Attributor &A) override {
1981 return indicatePessimisticFixpoint();
1982 }
1983
1984 /// See AbstractAttribute::trackStatistics()
1985 void trackStatistics() const override {
1986 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1987 }
1988};
1989
1990struct AAPointerInfoArgument final : AAPointerInfoFloating {
1991 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A)
1992 : AAPointerInfoFloating(IRP, A) {}
1993
1994 /// See AbstractAttribute::trackStatistics()
1995 void trackStatistics() const override {
1996 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
1997 }
1998};
1999
2000struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating {
2001 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
2002 : AAPointerInfoFloating(IRP, A) {}
2003
2004 /// See AbstractAttribute::updateImpl(...).
2005 ChangeStatus updateImpl(Attributor &A) override {
2006 using namespace AA::PointerInfo;
2007 // We handle memory intrinsics explicitly, at least the first (=
2008 // destination) and second (=source) arguments as we know how they are
2009 // accessed.
2010 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) {
2011 int64_t LengthVal = AA::RangeTy::Unknown;
2012 if (auto Length = MI->getLengthInBytes())
2013 LengthVal = Length->getSExtValue();
2014 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
2015 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2016 if (ArgNo > 1) {
2017 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic "
2018 << *MI << "\n");
2019 return indicatePessimisticFixpoint();
2020 } else {
2021 auto Kind =
2022 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ;
2023 Changed =
2024 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr);
2025 }
2026 LLVM_DEBUG({
2027 dbgs() << "Accesses by bin after update:\n";
2028 dumpState(dbgs());
2029 });
2030
2031 return Changed;
2032 }
2033
2034 // TODO: Once we have call site specific value information we can provide
2035 // call site specific liveness information and then it makes
2036 // sense to specialize attributes for call sites arguments instead of
2037 // redirecting requests to the callee argument.
2038 Argument *Arg = getAssociatedArgument();
2039 if (Arg) {
2040 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2041 auto *ArgAA =
2042 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED);
2043 if (ArgAA && ArgAA->getState().isValidState())
2044 return translateAndAddStateFromCallee(A, *ArgAA,
2045 *cast<CallBase>(getCtxI()));
2046 if (!Arg->getParent()->isDeclaration())
2047 return indicatePessimisticFixpoint();
2048 }
2049
2050 bool IsKnownNoCapture;
2051 if (!AA::hasAssumedIRAttr<Attribute::Captures>(
2052 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture))
2053 return indicatePessimisticFixpoint();
2054
2055 bool IsKnown = false;
2056 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown))
2057 return ChangeStatus::UNCHANGED;
2058 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown);
2059 auto Kind =
2060 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE;
2061 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind,
2062 nullptr);
2063 }
2064
2065 /// See AbstractAttribute::trackStatistics()
2066 void trackStatistics() const override {
2067 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2068 }
2069};
2070
2071struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating {
2072 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
2073 : AAPointerInfoFloating(IRP, A) {}
2074
2075 /// See AbstractAttribute::trackStatistics()
2076 void trackStatistics() const override {
2077 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition());
2078 }
2079};
2080} // namespace
2081
2082/// -----------------------NoUnwind Function Attribute--------------------------
2083
2084namespace {
2085struct AANoUnwindImpl : AANoUnwind {
2086 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {}
2087
2088 /// See AbstractAttribute::initialize(...).
2089 void initialize(Attributor &A) override {
2090 bool IsKnown;
2091 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2092 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
2093 (void)IsKnown;
2094 }
2095
2096 const std::string getAsStr(Attributor *A) const override {
2097 return getAssumed() ? "nounwind" : "may-unwind";
2098 }
2099
2100 /// See AbstractAttribute::updateImpl(...).
2101 ChangeStatus updateImpl(Attributor &A) override {
2102 auto Opcodes = {
2103 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
2104 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
2105 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
2106
2107 auto CheckForNoUnwind = [&](Instruction &I) {
2108 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
2109 return true;
2110
2111 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2112 bool IsKnownNoUnwind;
2113 return AA::hasAssumedIRAttr<Attribute::NoUnwind>(
2114 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED,
2115 IsKnownNoUnwind);
2116 }
2117 return false;
2118 };
2119
2120 bool UsedAssumedInformation = false;
2121 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
2122 UsedAssumedInformation))
2123 return indicatePessimisticFixpoint();
2124
2125 return ChangeStatus::UNCHANGED;
2126 }
2127};
2128
2129struct AANoUnwindFunction final : public AANoUnwindImpl {
2130 AANoUnwindFunction(const IRPosition &IRP, Attributor &A)
2131 : AANoUnwindImpl(IRP, A) {}
2132
2133 /// See AbstractAttribute::trackStatistics()
2134 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
2135};
2136
2137/// NoUnwind attribute deduction for a call sites.
2138struct AANoUnwindCallSite final
2139 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> {
2140 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A)
2141 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {}
2142
2143 /// See AbstractAttribute::trackStatistics()
2144 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
2145};
2146} // namespace
2147
2148/// ------------------------ NoSync Function Attribute -------------------------
2149
2150bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) {
2151 switch (CB.getIntrinsicID()) {
2152 case Intrinsic::nvvm_barrier_cta_sync_aligned_all:
2153 case Intrinsic::nvvm_barrier_cta_sync_aligned_count:
2154 case Intrinsic::nvvm_barrier0_and:
2155 case Intrinsic::nvvm_barrier0_or:
2156 case Intrinsic::nvvm_barrier0_popc:
2157 return true;
2158 case Intrinsic::amdgcn_s_barrier:
2159 if (ExecutedAligned)
2160 return true;
2161 break;
2162 default:
2163 break;
2164 }
2165 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier"));
2166}
2167
2169 if (!I->isAtomic())
2170 return false;
2171
2172 if (auto *FI = dyn_cast<FenceInst>(I))
2173 // All legal orderings for fence are stronger than monotonic.
2174 return FI->getSyncScopeID() != SyncScope::SingleThread;
2175 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
2176 // Unordered is not a legal ordering for cmpxchg.
2177 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic ||
2178 AI->getFailureOrdering() != AtomicOrdering::Monotonic);
2179 }
2180
2181 AtomicOrdering Ordering;
2182 switch (I->getOpcode()) {
2183 case Instruction::AtomicRMW:
2184 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
2185 break;
2186 case Instruction::Store:
2187 Ordering = cast<StoreInst>(I)->getOrdering();
2188 break;
2189 case Instruction::Load:
2190 Ordering = cast<LoadInst>(I)->getOrdering();
2191 break;
2192 default:
2194 "New atomic operations need to be known in the attributor.");
2195 }
2196
2197 return (Ordering != AtomicOrdering::Unordered &&
2198 Ordering != AtomicOrdering::Monotonic);
2199}
2200
2201/// Return true if this intrinsic is nosync. This is only used for intrinsics
2202/// which would be nosync except that they have a volatile flag. All other
2203/// intrinsics are simply annotated with the nosync attribute in Intrinsics.td.
2205 if (auto *MI = dyn_cast<MemIntrinsic>(I))
2206 return !MI->isVolatile();
2207 return false;
2208}
2209
2210namespace {
2211struct AANoSyncImpl : AANoSync {
2212 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {}
2213
2214 /// See AbstractAttribute::initialize(...).
2215 void initialize(Attributor &A) override {
2216 bool IsKnown;
2217 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(),
2218 DepClassTy::NONE, IsKnown));
2219 (void)IsKnown;
2220 }
2221
2222 const std::string getAsStr(Attributor *A) const override {
2223 return getAssumed() ? "nosync" : "may-sync";
2224 }
2225
2226 /// See AbstractAttribute::updateImpl(...).
2227 ChangeStatus updateImpl(Attributor &A) override;
2228};
2229
2230ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
2231
2232 auto CheckRWInstForNoSync = [&](Instruction &I) {
2233 return AA::isNoSyncInst(A, I, *this);
2234 };
2235
2236 auto CheckForNoSync = [&](Instruction &I) {
2237 // At this point we handled all read/write effects and they are all
2238 // nosync, so they can be skipped.
2239 if (I.mayReadOrWriteMemory())
2240 return true;
2241
2242 bool IsKnown;
2243 CallBase &CB = cast<CallBase>(I);
2244 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
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;
2299 return AA::hasAssumedIRAttr<Attribute::NoFree>(
2300 A, this, IRPosition::callsite_function(cast<CallBase>(I)),
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;
2347 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this,
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;
2363 return AA::hasAssumedIRAttr<Attribute::NoFree>(
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;
2414 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos,
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
2526 if (isa<GetElementPtrInst>(I)) {
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)) {
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;
2557 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP,
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;
2632 return AA::hasAssumedIRAttr<Attribute::NonNull>(
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))
2657 if (AA::hasAssumedIRAttr<Attribute::NonNull>(
2658 A, this, IRPosition::value(*Select->getFalseValue()),
2659 DepClassTy::OPTIONAL, IsKnown) &&
2660 AA::hasAssumedIRAttr<Attribute::NonNull>(
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;
2742 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>(
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;
2760 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
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;
2770 return AA::hasAssumedIRAttr<Attribute::MustProgress>(
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;
2803 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>(
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;
2825 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
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;
2846 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>(
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);
2911 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
2912 if (!Callee || Callee->isIntrinsic()) {
2913 return false;
2914 }
2915 if (Callee->isDeclaration()) {
2916 return !Callee->hasFnAttribute(Attribute::Convergent);
2917 }
2918 const auto *ConvergentAA = A.getAAFor<AANonConvergent>(
2919 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED);
2920 return ConvergentAA && ConvergentAA->isAssumedNotConvergent();
2921 };
2922
2923 bool UsedAssumedInformation = false;
2924 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this,
2925 UsedAssumedInformation)) {
2926 return indicatePessimisticFixpoint();
2927 }
2928 return ChangeStatus::UNCHANGED;
2929 }
2930
2931 ChangeStatus manifest(Attributor &A) override {
2932 if (isKnownNotConvergent() &&
2933 A.hasAttr(getIRPosition(), Attribute::Convergent)) {
2934 A.removeAttrs(getIRPosition(), {Attribute::Convergent});
2935 return ChangeStatus::CHANGED;
2936 }
2937 return ChangeStatus::UNCHANGED;
2938 }
2939
2940 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) }
2941};
2942} // namespace
2943
2944/// -------------------- Undefined-Behavior Attributes ------------------------
2945
2946namespace {
2947struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2948 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A)
2949 : AAUndefinedBehavior(IRP, A) {}
2950
2951 /// See AbstractAttribute::updateImpl(...).
2952 // through a pointer (i.e. also branches etc.)
2953 ChangeStatus updateImpl(Attributor &A) override {
2954 const size_t UBPrevSize = KnownUBInsts.size();
2955 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
2956
2957 auto InspectMemAccessInstForUB = [&](Instruction &I) {
2958 // Lang ref now states volatile store is not UB, let's skip them.
2959 if (I.isVolatile() && I.mayWriteToMemory())
2960 return true;
2961
2962 // Skip instructions that are already saved.
2963 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2964 return true;
2965
2966 // If we reach here, we know we have an instruction
2967 // that accesses memory through a pointer operand,
2968 // for which getPointerOperand() should give it to us.
2969 Value *PtrOp =
2970 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true));
2971 assert(PtrOp &&
2972 "Expected pointer operand of memory accessing instruction");
2973
2974 // Either we stopped and the appropriate action was taken,
2975 // or we got back a simplified value to continue.
2976 std::optional<Value *> SimplifiedPtrOp =
2977 stopOnUndefOrAssumed(A, PtrOp, &I);
2978 if (!SimplifiedPtrOp || !*SimplifiedPtrOp)
2979 return true;
2980 const Value *PtrOpVal = *SimplifiedPtrOp;
2981
2982 // A memory access through a pointer is considered UB
2983 // only if the pointer has constant null value.
2984 // TODO: Expand it to not only check constant values.
2985 if (!isa<ConstantPointerNull>(PtrOpVal)) {
2986 AssumedNoUBInsts.insert(&I);
2987 return true;
2988 }
2989 const Type *PtrTy = PtrOpVal->getType();
2990
2991 // Because we only consider instructions inside functions,
2992 // assume that a parent function exists.
2993 const Function *F = I.getFunction();
2994
2995 // A memory access using constant null pointer is only considered UB
2996 // if null pointer is _not_ defined for the target platform.
2998 AssumedNoUBInsts.insert(&I);
2999 else
3000 KnownUBInsts.insert(&I);
3001 return true;
3002 };
3003
3004 auto InspectBrInstForUB = [&](Instruction &I) {
3005 // A conditional branch instruction is considered UB if it has `undef`
3006 // condition.
3007
3008 // Skip instructions that are already saved.
3009 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3010 return true;
3011
3012 // We know we have a branch instruction.
3013 auto *BrInst = cast<BranchInst>(&I);
3014
3015 // Unconditional branches are never considered UB.
3016 if (BrInst->isUnconditional())
3017 return true;
3018
3019 // Either we stopped and the appropriate action was taken,
3020 // or we got back a simplified value to continue.
3021 std::optional<Value *> SimplifiedCond =
3022 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
3023 if (!SimplifiedCond || !*SimplifiedCond)
3024 return true;
3025 AssumedNoUBInsts.insert(&I);
3026 return true;
3027 };
3028
3029 auto InspectCallSiteForUB = [&](Instruction &I) {
3030 // Check whether a callsite always cause UB or not
3031
3032 // Skip instructions that are already saved.
3033 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
3034 return true;
3035
3036 // Check nonnull and noundef argument attribute violation for each
3037 // callsite.
3038 CallBase &CB = cast<CallBase>(I);
3039 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand());
3040 if (!Callee)
3041 return true;
3042 for (unsigned idx = 0; idx < CB.arg_size(); idx++) {
3043 // If current argument is known to be simplified to null pointer and the
3044 // corresponding argument position is known to have nonnull attribute,
3045 // the argument is poison. Furthermore, if the argument is poison and
3046 // the position is known to have noundef attriubte, this callsite is
3047 // considered UB.
3048 if (idx >= Callee->arg_size())
3049 break;
3050 Value *ArgVal = CB.getArgOperand(idx);
3051 if (!ArgVal)
3052 continue;
3053 // Here, we handle three cases.
3054 // (1) Not having a value means it is dead. (we can replace the value
3055 // with undef)
3056 // (2) Simplified to undef. The argument violate noundef attriubte.
3057 // (3) Simplified to null pointer where known to be nonnull.
3058 // The argument is a poison value and violate noundef attribute.
3059 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx);
3060 bool IsKnownNoUndef;
3061 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3062 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef);
3063 if (!IsKnownNoUndef)
3064 continue;
3065 bool UsedAssumedInformation = false;
3066 std::optional<Value *> SimplifiedVal =
3067 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this,
3068 UsedAssumedInformation, AA::Interprocedural);
3069 if (UsedAssumedInformation)
3070 continue;
3071 if (SimplifiedVal && !*SimplifiedVal)
3072 return true;
3073 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) {
3074 KnownUBInsts.insert(&I);
3075 continue;
3076 }
3077 if (!ArgVal->getType()->isPointerTy() ||
3078 !isa<ConstantPointerNull>(**SimplifiedVal))
3079 continue;
3080 bool IsKnownNonNull;
3081 AA::hasAssumedIRAttr<Attribute::NonNull>(
3082 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull);
3083 if (IsKnownNonNull)
3084 KnownUBInsts.insert(&I);
3085 }
3086 return true;
3087 };
3088
3089 auto InspectReturnInstForUB = [&](Instruction &I) {
3090 auto &RI = cast<ReturnInst>(I);
3091 // Either we stopped and the appropriate action was taken,
3092 // or we got back a simplified return value to continue.
3093 std::optional<Value *> SimplifiedRetValue =
3094 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I);
3095 if (!SimplifiedRetValue || !*SimplifiedRetValue)
3096 return true;
3097
3098 // Check if a return instruction always cause UB or not
3099 // Note: It is guaranteed that the returned position of the anchor
3100 // scope has noundef attribute when this is called.
3101 // We also ensure the return position is not "assumed dead"
3102 // because the returned value was then potentially simplified to
3103 // `undef` in AAReturnedValues without removing the `noundef`
3104 // attribute yet.
3105
3106 // When the returned position has noundef attriubte, UB occurs in the
3107 // following cases.
3108 // (1) Returned value is known to be undef.
3109 // (2) The value is known to be a null pointer and the returned
3110 // position has nonnull attribute (because the returned value is
3111 // poison).
3112 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) {
3113 bool IsKnownNonNull;
3114 AA::hasAssumedIRAttr<Attribute::NonNull>(
3115 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE,
3116 IsKnownNonNull);
3117 if (IsKnownNonNull)
3118 KnownUBInsts.insert(&I);
3119 }
3120
3121 return true;
3122 };
3123
3124 bool UsedAssumedInformation = false;
3125 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
3126 {Instruction::Load, Instruction::Store,
3127 Instruction::AtomicCmpXchg,
3128 Instruction::AtomicRMW},
3129 UsedAssumedInformation,
3130 /* CheckBBLivenessOnly */ true);
3131 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
3132 UsedAssumedInformation,
3133 /* CheckBBLivenessOnly */ true);
3134 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
3135 UsedAssumedInformation);
3136
3137 // If the returned position of the anchor scope has noundef attriubte, check
3138 // all returned instructions.
3139 if (!getAnchorScope()->getReturnType()->isVoidTy()) {
3140 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
3141 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
3142 bool IsKnownNoUndef;
3143 AA::hasAssumedIRAttr<Attribute::NoUndef>(
3144 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef);
3145 if (IsKnownNoUndef)
3146 A.checkForAllInstructions(InspectReturnInstForUB, *this,
3147 {Instruction::Ret}, UsedAssumedInformation,
3148 /* CheckBBLivenessOnly */ true);
3149 }
3150 }
3151
3152 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
3153 UBPrevSize != KnownUBInsts.size())
3154 return ChangeStatus::CHANGED;
3155 return ChangeStatus::UNCHANGED;
3156 }
3157
3158 bool isKnownToCauseUB(Instruction *I) const override {
3159 return KnownUBInsts.count(I);
3160 }
3161
3162 bool isAssumedToCauseUB(Instruction *I) const override {
3163 // In simple words, if an instruction is not in the assumed to _not_
3164 // cause UB, then it is assumed UB (that includes those
3165 // in the KnownUBInsts set). The rest is boilerplate
3166 // is to ensure that it is one of the instructions we test
3167 // for UB.
3168
3169 switch (I->getOpcode()) {
3170 case Instruction::Load:
3171 case Instruction::Store:
3172 case Instruction::AtomicCmpXchg:
3173 case Instruction::AtomicRMW:
3174 return !AssumedNoUBInsts.count(I);
3175 case Instruction::Br: {
3176 auto *BrInst = cast<BranchInst>(I);
3177 if (BrInst->isUnconditional())
3178 return false;
3179 return !AssumedNoUBInsts.count(I);
3180 } break;
3181 default:
3182 return false;
3183 }
3184 return false;
3185 }
3186
3187 ChangeStatus manifest(Attributor &A) override {
3188 if (KnownUBInsts.empty())
3189 return ChangeStatus::UNCHANGED;
3190 for (Instruction *I : KnownUBInsts)
3191 A.changeToUnreachableAfterManifest(I);
3192 return ChangeStatus::CHANGED;
3193 }
3194
3195 /// See AbstractAttribute::getAsStr()
3196 const std::string getAsStr(Attributor *A) const override {
3197 return getAssumed() ? "undefined-behavior" : "no-ub";
3198 }
3199
3200 /// Note: The correctness of this analysis depends on the fact that the
3201 /// following 2 sets will stop changing after some point.
3202 /// "Change" here means that their size changes.
3203 /// The size of each set is monotonically increasing
3204 /// (we only add items to them) and it is upper bounded by the number of
3205 /// instructions in the processed function (we can never save more
3206 /// elements in either set than this number). Hence, at some point,
3207 /// they will stop increasing.
3208 /// Consequently, at some point, both sets will have stopped
3209 /// changing, effectively making the analysis reach a fixpoint.
3210
3211 /// Note: These 2 sets are disjoint and an instruction can be considered
3212 /// one of 3 things:
3213 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
3214 /// the KnownUBInsts set.
3215 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
3216 /// has a reason to assume it).
3217 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
3218 /// could not find a reason to assume or prove that it can cause UB,
3219 /// hence it assumes it doesn't. We have a set for these instructions
3220 /// so that we don't reprocess them in every update.
3221 /// Note however that instructions in this set may cause UB.
3222
3223protected:
3224 /// A set of all live instructions _known_ to cause UB.
3225 SmallPtrSet<Instruction *, 8> KnownUBInsts;
3226
3227private:
3228 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
3229 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
3230
3231 // Should be called on updates in which if we're processing an instruction
3232 // \p I that depends on a value \p V, one of the following has to happen:
3233 // - If the value is assumed, then stop.
3234 // - If the value is known but undef, then consider it UB.
3235 // - Otherwise, do specific processing with the simplified value.
3236 // We return std::nullopt in the first 2 cases to signify that an appropriate
3237 // action was taken and the caller should stop.
3238 // Otherwise, we return the simplified value that the caller should
3239 // use for specific processing.
3240 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V,
3241 Instruction *I) {
3242 bool UsedAssumedInformation = false;
3243 std::optional<Value *> SimplifiedV =
3244 A.getAssumedSimplified(IRPosition::value(*V), *this,
3245 UsedAssumedInformation, AA::Interprocedural);
3246 if (!UsedAssumedInformation) {
3247 // Don't depend on assumed values.
3248 if (!SimplifiedV) {
3249 // If it is known (which we tested above) but it doesn't have a value,
3250 // then we can assume `undef` and hence the instruction is UB.
3251 KnownUBInsts.insert(I);
3252 return std::nullopt;
3253 }
3254 if (!*SimplifiedV)
3255 return nullptr;
3256 V = *SimplifiedV;
3257 }
3258 if (isa<UndefValue>(V)) {
3259 KnownUBInsts.insert(I);
3260 return std::nullopt;
3261 }
3262 return V;
3263 }
3264};
3265
3266struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
3267 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A)
3268 : AAUndefinedBehaviorImpl(IRP, A) {}
3269
3270 /// See AbstractAttribute::trackStatistics()
3271 void trackStatistics() const override {
3272 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
3273 "Number of instructions known to have UB");
3274 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
3275 KnownUBInsts.size();
3276 }
3277};
3278} // namespace
3279
3280/// ------------------------ Will-Return Attributes ----------------------------
3281
3282namespace {
3283// Helper function that checks whether a function has any cycle which we don't
3284// know if it is bounded or not.
3285// Loops with maximum trip count are considered bounded, any other cycle not.
3286static bool mayContainUnboundedCycle(Function &F, Attributor &A) {
3287 ScalarEvolution *SE =
3288 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
3289 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
3290 // If either SCEV or LoopInfo is not available for the function then we assume
3291 // any cycle to be unbounded cycle.
3292 // We use scc_iterator which uses Tarjan algorithm to find all the maximal
3293 // SCCs.To detect if there's a cycle, we only need to find the maximal ones.
3294 if (!SE || !LI) {
3295 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI)
3296 if (SCCI.hasCycle())
3297 return true;
3298 return false;
3299 }
3300
3301 // If there's irreducible control, the function may contain non-loop cycles.
3303 return true;
3304
3305 // Any loop that does not have a max trip count is considered unbounded cycle.
3306 for (auto *L : LI->getLoopsInPreorder()) {
3307 if (!SE->getSmallConstantMaxTripCount(L))
3308 return true;
3309 }
3310 return false;
3311}
3312
3313struct AAWillReturnImpl : public AAWillReturn {
3314 AAWillReturnImpl(const IRPosition &IRP, Attributor &A)
3315 : AAWillReturn(IRP, A) {}
3316
3317 /// See AbstractAttribute::initialize(...).
3318 void initialize(Attributor &A) override {
3319 bool IsKnown;
3320 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>(
3321 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
3322 (void)IsKnown;
3323 }
3324
3325 /// Check for `mustprogress` and `readonly` as they imply `willreturn`.
3326 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) {
3327 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress}))
3328 return false;
3329
3330 bool IsKnown;
3331 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3332 return IsKnown || !KnownOnly;
3333 return false;
3334 }
3335
3336 /// See AbstractAttribute::updateImpl(...).
3337 ChangeStatus updateImpl(Attributor &A) override {
3338 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3339 return ChangeStatus::UNCHANGED;
3340
3341 auto CheckForWillReturn = [&](Instruction &I) {
3342 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I));
3343 bool IsKnown;
3344 if (AA::hasAssumedIRAttr<Attribute::WillReturn>(
3345 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) {
3346 if (IsKnown)
3347 return true;
3348 } else {
3349 return false;
3350 }
3351 bool IsKnownNoRecurse;
3352 return AA::hasAssumedIRAttr<Attribute::NoRecurse>(
3353 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse);
3354 };
3355
3356 bool UsedAssumedInformation = false;
3357 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
3358 UsedAssumedInformation))
3359 return indicatePessimisticFixpoint();
3360
3361 return ChangeStatus::UNCHANGED;
3362 }
3363
3364 /// See AbstractAttribute::getAsStr()
3365 const std::string getAsStr(Attributor *A) const override {
3366 return getAssumed() ? "willreturn" : "may-noreturn";
3367 }
3368};
3369
3370struct AAWillReturnFunction final : AAWillReturnImpl {
3371 AAWillReturnFunction(const IRPosition &IRP, Attributor &A)
3372 : AAWillReturnImpl(IRP, A) {}
3373
3374 /// See AbstractAttribute::initialize(...).
3375 void initialize(Attributor &A) override {
3376 AAWillReturnImpl::initialize(A);
3377
3378 Function *F = getAnchorScope();
3379 assert(F && "Did expect an anchor function");
3380 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A))
3381 indicatePessimisticFixpoint();
3382 }
3383
3384 /// See AbstractAttribute::trackStatistics()
3385 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
3386};
3387
3388/// WillReturn attribute deduction for a call sites.
3389struct AAWillReturnCallSite final
3390 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> {
3391 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A)
3392 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {}
3393
3394 /// See AbstractAttribute::updateImpl(...).
3395 ChangeStatus updateImpl(Attributor &A) override {
3396 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false))
3397 return ChangeStatus::UNCHANGED;
3398
3399 return AACalleeToCallSite::updateImpl(A);
3400 }
3401
3402 /// See AbstractAttribute::trackStatistics()
3403 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
3404};
3405} // namespace
3406
3407/// -------------------AAIntraFnReachability Attribute--------------------------
3408
3409/// All information associated with a reachability query. This boilerplate code
3410/// is used by both AAIntraFnReachability and AAInterFnReachability, with
3411/// different \p ToTy values.
3412template <typename ToTy> struct ReachabilityQueryInfo {
3413 enum class Reachable {
3414 No,
3415 Yes,
3416 };
3417
3418 /// Start here,
3419 const Instruction *From = nullptr;
3420 /// reach this place,
3421 const ToTy *To = nullptr;
3422 /// without going through any of these instructions,
3423 const AA::InstExclusionSetTy *ExclusionSet = nullptr;
3424 /// and remember if it worked:
3425 Reachable Result = Reachable::No;
3426
3427 /// Precomputed hash for this RQI.
3428 unsigned Hash = 0;
3429
3430 unsigned computeHashValue() const {
3431 assert(Hash == 0 && "Computed hash twice!");
3434 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash =
3435 detail::combineHashValue(PairDMI ::getHashValue({From, To}),
3436 InstSetDMI::getHashValue(ExclusionSet));
3437 }
3438
3440 : From(From), To(To) {}
3441
3442 /// Constructor replacement to ensure unique and stable sets are used for the
3443 /// cache.
3445 const AA::InstExclusionSetTy *ES, bool MakeUnique)
3446 : From(&From), To(&To), ExclusionSet(ES) {
3447
3448 if (!ES || ES->empty()) {
3449 ExclusionSet = nullptr;
3450 } else if (MakeUnique) {
3451 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES);
3452 }
3453 }
3454
3456 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {}
3457};
3458
3459namespace llvm {
3460template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> {
3463
3466
3467 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; }
3469 return &TombstoneKey;
3470 }
3471 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) {
3472 return RQI->Hash ? RQI->Hash : RQI->computeHashValue();
3473 }
3476 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To}))
3477 return false;
3478 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet);
3479 }
3480};
3481
3482#define DefineKeys(ToTy) \
3483 template <> \
3484 ReachabilityQueryInfo<ToTy> \
3485 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \
3486 ReachabilityQueryInfo<ToTy>( \
3487 DenseMapInfo<const Instruction *>::getEmptyKey(), \
3488 DenseMapInfo<const ToTy *>::getEmptyKey()); \
3489 template <> \
3490 ReachabilityQueryInfo<ToTy> \
3491 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \
3492 ReachabilityQueryInfo<ToTy>( \
3493 DenseMapInfo<const Instruction *>::getTombstoneKey(), \
3494 DenseMapInfo<const ToTy *>::getTombstoneKey());
3495
3497#undef DefineKeys
3498
3499} // namespace llvm
3500
3501namespace {
3502
3503template <typename BaseTy, typename ToTy>
3504struct CachedReachabilityAA : public BaseTy {
3505 using RQITy = ReachabilityQueryInfo<ToTy>;
3506
3507 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {}
3508
3509 /// See AbstractAttribute::isQueryAA.
3510 bool isQueryAA() const override { return true; }
3511
3512 /// See AbstractAttribute::updateImpl(...).
3513 ChangeStatus updateImpl(Attributor &A) override {
3514 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3515 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) {
3516 RQITy *RQI = QueryVector[u];
3517 if (RQI->Result == RQITy::Reachable::No &&
3518 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false))
3519 Changed = ChangeStatus::CHANGED;
3520 }
3521 return Changed;
3522 }
3523
3524 virtual bool isReachableImpl(Attributor &A, RQITy &RQI,
3525 bool IsTemporaryRQI) = 0;
3526
3527 bool rememberResult(Attributor &A, typename RQITy::Reachable Result,
3528 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) {
3529 RQI.Result = Result;
3530
3531 // Remove the temporary RQI from the cache.
3532 if (IsTemporaryRQI)
3533 QueryCache.erase(&RQI);
3534
3535 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options:
3536 // 1) If it is reachable, it doesn't matter if we have an exclusion set for
3537 // this query. 2) We did not use the exclusion set, potentially because
3538 // there is none.
3539 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) {
3540 RQITy PlainRQI(RQI.From, RQI.To);
3541 if (!QueryCache.count(&PlainRQI)) {
3542 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To);
3543 RQIPtr->Result = Result;
3544 QueryVector.push_back(RQIPtr);
3545 QueryCache.insert(RQIPtr);
3546 }
3547 }
3548
3549 // Check if we need to insert a new permanent RQI with the exclusion set.
3550 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) {
3551 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) &&
3552 "Did not expect empty set!");
3553 RQITy *RQIPtr = new (A.Allocator)
3554 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true);
3555 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?");
3556 RQIPtr->Result = Result;
3557 assert(!QueryCache.count(RQIPtr));
3558 QueryVector.push_back(RQIPtr);
3559 QueryCache.insert(RQIPtr);
3560 }
3561
3562 if (Result == RQITy::Reachable::No && IsTemporaryRQI)
3563 A.registerForUpdate(*this);
3564 return Result == RQITy::Reachable::Yes;
3565 }
3566
3567 const std::string getAsStr(Attributor *A) const override {
3568 // TODO: Return the number of reachable queries.
3569 return "#queries(" + std::to_string(QueryVector.size()) + ")";
3570 }
3571
3572 bool checkQueryCache(Attributor &A, RQITy &StackRQI,
3573 typename RQITy::Reachable &Result) {
3574 if (!this->getState().isValidState()) {
3575 Result = RQITy::Reachable::Yes;
3576 return true;
3577 }
3578
3579 // If we have an exclusion set we might be able to find our answer by
3580 // ignoring it first.
3581 if (StackRQI.ExclusionSet) {
3582 RQITy PlainRQI(StackRQI.From, StackRQI.To);
3583 auto It = QueryCache.find(&PlainRQI);
3584 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) {
3585 Result = RQITy::Reachable::No;
3586 return true;
3587 }
3588 }
3589
3590 auto It = QueryCache.find(&StackRQI);
3591 if (It != QueryCache.end()) {
3592 Result = (*It)->Result;
3593 return true;
3594 }
3595
3596 // Insert a temporary for recursive queries. We will replace it with a
3597 // permanent entry later.
3598 QueryCache.insert(&StackRQI);
3599 return false;
3600 }
3601
3602private:
3603 SmallVector<RQITy *> QueryVector;
3604 DenseSet<RQITy *> QueryCache;
3605};
3606
3607struct AAIntraFnReachabilityFunction final
3608 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> {
3609 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>;
3610 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
3611 : Base(IRP, A) {
3612 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>(
3613 *IRP.getAssociatedFunction());
3614 }
3615
3616 bool isAssumedReachable(
3617 Attributor &A, const Instruction &From, const Instruction &To,
3618 const AA::InstExclusionSetTy *ExclusionSet) const override {
3619 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this);
3620 if (&From == &To)
3621 return true;
3622
3623 RQITy StackRQI(A, From, To, ExclusionSet, false);
3624 typename RQITy::Reachable Result;
3625 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
3626 return NonConstThis->isReachableImpl(A, StackRQI,
3627 /*IsTemporaryRQI=*/true);
3628 return Result == RQITy::Reachable::Yes;
3629 }
3630
3631 ChangeStatus updateImpl(Attributor &A) override {
3632 // We only depend on liveness. DeadEdges is all we care about, check if any
3633 // of them changed.
3634 auto *LivenessAA =
3635 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3636 if (LivenessAA &&
3637 llvm::all_of(DeadEdges,
3638 [&](const auto &DeadEdge) {
3639 return LivenessAA->isEdgeDead(DeadEdge.first,
3640 DeadEdge.second);
3641 }) &&
3642 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) {
3643 return LivenessAA->isAssumedDead(BB);
3644 })) {
3645 return ChangeStatus::UNCHANGED;
3646 }
3647 DeadEdges.clear();
3648 DeadBlocks.clear();
3649 return Base::updateImpl(A);
3650 }
3651
3652 bool isReachableImpl(Attributor &A, RQITy &RQI,
3653 bool IsTemporaryRQI) override {
3654 const Instruction *Origin = RQI.From;
3655 bool UsedExclusionSet = false;
3656
3657 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To,
3658 const AA::InstExclusionSetTy *ExclusionSet) {
3659 const Instruction *IP = &From;
3660 while (IP && IP != &To) {
3661 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) {
3662 UsedExclusionSet = true;
3663 break;
3664 }
3665 IP = IP->getNextNode();
3666 }
3667 return IP == &To;
3668 };
3669
3670 const BasicBlock *FromBB = RQI.From->getParent();
3671 const BasicBlock *ToBB = RQI.To->getParent();
3672 assert(FromBB->getParent() == ToBB->getParent() &&
3673 "Not an intra-procedural query!");
3674
3675 // Check intra-block reachability, however, other reaching paths are still
3676 // possible.
3677 if (FromBB == ToBB &&
3678 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet))
3679 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3680 IsTemporaryRQI);
3681
3682 // Check if reaching the ToBB block is sufficient or if even that would not
3683 // ensure reaching the target. In the latter case we are done.
3684 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet))
3685 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3686 IsTemporaryRQI);
3687
3688 const Function *Fn = FromBB->getParent();
3690 if (RQI.ExclusionSet)
3691 for (auto *I : *RQI.ExclusionSet)
3692 if (I->getFunction() == Fn)
3693 ExclusionBlocks.insert(I->getParent());
3694
3695 // Check if we make it out of the FromBB block at all.
3696 if (ExclusionBlocks.count(FromBB) &&
3697 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(),
3698 RQI.ExclusionSet))
3699 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI);
3700
3701 auto *LivenessAA =
3702 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL);
3703 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) {
3704 DeadBlocks.insert(ToBB);
3705 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3706 IsTemporaryRQI);
3707 }
3708
3711 Worklist.push_back(FromBB);
3712
3714 while (!Worklist.empty()) {
3715 const BasicBlock *BB = Worklist.pop_back_val();
3716 if (!Visited.insert(BB).second)
3717 continue;
3718 for (const BasicBlock *SuccBB : successors(BB)) {
3719 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) {
3720 LocalDeadEdges.insert({BB, SuccBB});
3721 continue;
3722 }
3723 // We checked before if we just need to reach the ToBB block.
3724 if (SuccBB == ToBB)
3725 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3726 IsTemporaryRQI);
3727 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB))
3728 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
3729 IsTemporaryRQI);
3730
3731 if (ExclusionBlocks.count(SuccBB)) {
3732 UsedExclusionSet = true;
3733 continue;
3734 }
3735 Worklist.push_back(SuccBB);
3736 }
3737 }
3738
3739 DeadEdges.insert_range(LocalDeadEdges);
3740 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
3741 IsTemporaryRQI);
3742 }
3743
3744 /// See AbstractAttribute::trackStatistics()
3745 void trackStatistics() const override {}
3746
3747private:
3748 // Set of assumed dead blocks we used in the last query. If any changes we
3749 // update the state.
3751
3752 // Set of assumed dead edges we used in the last query. If any changes we
3753 // update the state.
3755
3756 /// The dominator tree of the function to short-circuit reasoning.
3757 const DominatorTree *DT = nullptr;
3758};
3759} // namespace
3760
3761/// ------------------------ NoAlias Argument Attribute ------------------------
3762
3764 Attribute::AttrKind ImpliedAttributeKind,
3765 bool IgnoreSubsumingPositions) {
3766 assert(ImpliedAttributeKind == Attribute::NoAlias &&
3767 "Unexpected attribute kind");
3768 Value *Val = &IRP.getAssociatedValue();
3769 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) {
3770 if (isa<AllocaInst>(Val))
3771 return true;
3772 } else {
3773 IgnoreSubsumingPositions = true;
3774 }
3775
3776 if (isa<UndefValue>(Val))
3777 return true;
3778
3779 if (isa<ConstantPointerNull>(Val) &&
3782 return true;
3783
3784 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias},
3785 IgnoreSubsumingPositions, Attribute::NoAlias))
3786 return true;
3787
3788 return false;
3789}
3790
3791namespace {
3792struct AANoAliasImpl : AANoAlias {
3793 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) {
3794 assert(getAssociatedType()->isPointerTy() &&
3795 "Noalias is a pointer attribute");
3796 }
3797
3798 const std::string getAsStr(Attributor *A) const override {
3799 return getAssumed() ? "noalias" : "may-alias";
3800 }
3801};
3802
3803/// NoAlias attribute for a floating value.
3804struct AANoAliasFloating final : AANoAliasImpl {
3805 AANoAliasFloating(const IRPosition &IRP, Attributor &A)
3806 : AANoAliasImpl(IRP, A) {}
3807
3808 /// See AbstractAttribute::updateImpl(...).
3809 ChangeStatus updateImpl(Attributor &A) override {
3810 // TODO: Implement this.
3811 return indicatePessimisticFixpoint();
3812 }
3813
3814 /// See AbstractAttribute::trackStatistics()
3815 void trackStatistics() const override {
3817 }
3818};
3819
3820/// NoAlias attribute for an argument.
3821struct AANoAliasArgument final
3822 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
3823 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
3824 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
3825
3826 /// See AbstractAttribute::update(...).
3827 ChangeStatus updateImpl(Attributor &A) override {
3828 // We have to make sure no-alias on the argument does not break
3829 // synchronization when this is a callback argument, see also [1] below.
3830 // If synchronization cannot be affected, we delegate to the base updateImpl
3831 // function, otherwise we give up for now.
3832
3833 // If the function is no-sync, no-alias cannot break synchronization.
3834 bool IsKnownNoSycn;
3835 if (AA::hasAssumedIRAttr<Attribute::NoSync>(
3836 A, this, IRPosition::function_scope(getIRPosition()),
3837 DepClassTy::OPTIONAL, IsKnownNoSycn))
3838 return Base::updateImpl(A);
3839
3840 // If the argument is read-only, no-alias cannot break synchronization.
3841 bool IsKnown;
3842 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
3843 return Base::updateImpl(A);
3844
3845 // If the argument is never passed through callbacks, no-alias cannot break
3846 // synchronization.
3847 bool UsedAssumedInformation = false;
3848 if (A.checkForAllCallSites(
3849 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
3850 true, UsedAssumedInformation))
3851 return Base::updateImpl(A);
3852
3853 // TODO: add no-alias but make sure it doesn't break synchronization by
3854 // introducing fake uses. See:
3855 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
3856 // International Workshop on OpenMP 2018,
3857 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
3858
3859 return indicatePessimisticFixpoint();
3860 }
3861
3862 /// See AbstractAttribute::trackStatistics()
3863 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
3864};
3865
3866struct AANoAliasCallSiteArgument final : AANoAliasImpl {
3867 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A)
3868 : AANoAliasImpl(IRP, A) {}
3869
3870 /// Determine if the underlying value may alias with the call site argument
3871 /// \p OtherArgNo of \p ICS (= the underlying call site).
3872 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
3873 const AAMemoryBehavior &MemBehaviorAA,
3874 const CallBase &CB, unsigned OtherArgNo) {
3875 // We do not need to worry about aliasing with the underlying IRP.
3876 if (this->getCalleeArgNo() == (int)OtherArgNo)
3877 return false;
3878
3879 // If it is not a pointer or pointer vector we do not alias.
3880 const Value *ArgOp = CB.getArgOperand(OtherArgNo);
3881 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
3882 return false;
3883
3884 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3885 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE);
3886
3887 // If the argument is readnone, there is no read-write aliasing.
3888 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) {
3889 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3890 return false;
3891 }
3892
3893 // If the argument is readonly and the underlying value is readonly, there
3894 // is no read-write aliasing.
3895 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
3896 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() &&
3897 IsReadOnly) {
3898 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
3899 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
3900 return false;
3901 }
3902
3903 // We have to utilize actual alias analysis queries so we need the object.
3904 if (!AAR)
3905 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>(
3906 *getAnchorScope());
3907
3908 // Try to rule it out at the call site.
3909 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
3910 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
3911 "callsite arguments: "
3912 << getAssociatedValue() << " " << *ArgOp << " => "
3913 << (IsAliasing ? "" : "no-") << "alias \n");
3914
3915 return IsAliasing;
3916 }
3917
3918 bool isKnownNoAliasDueToNoAliasPreservation(
3919 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) {
3920 // We can deduce "noalias" if the following conditions hold.
3921 // (i) Associated value is assumed to be noalias in the definition.
3922 // (ii) Associated value is assumed to be no-capture in all the uses
3923 // possibly executed before this callsite.
3924 // (iii) There is no other pointer argument which could alias with the
3925 // value.
3926
3927 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
3928 const Function *ScopeFn = VIRP.getAnchorScope();
3929 // Check whether the value is captured in the scope using AANoCapture.
3930 // Look at CFG and check only uses possibly executed before this
3931 // callsite.
3932 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
3933 Instruction *UserI = cast<Instruction>(U.getUser());
3934
3935 // If UserI is the curr instruction and there is a single potential use of
3936 // the value in UserI we allow the use.
3937 // TODO: We should inspect the operands and allow those that cannot alias
3938 // with the value.
3939 if (UserI == getCtxI() && UserI->getNumOperands() == 1)
3940 return true;
3941
3942 if (ScopeFn) {
3943 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3944 if (CB->isArgOperand(&U)) {
3945
3946 unsigned ArgNo = CB->getArgOperandNo(&U);
3947
3948 bool IsKnownNoCapture;
3949 if (AA::hasAssumedIRAttr<Attribute::Captures>(
3950 A, this, IRPosition::callsite_argument(*CB, ArgNo),
3951 DepClassTy::OPTIONAL, IsKnownNoCapture))
3952 return true;
3953 }
3954 }
3955
3957 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr,
3958 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; }))
3959 return true;
3960 }
3961
3962 // TODO: We should track the capturing uses in AANoCapture but the problem
3963 // is CGSCC runs. For those we would need to "allow" AANoCapture for
3964 // a value in the module slice.
3965 // TODO(captures): Make this more precise.
3966 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
3967 if (capturesNothing(CI))
3968 return true;
3969 if (CI.isPassthrough()) {
3970 Follow = true;
3971 return true;
3972 }
3973 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n");
3974 return false;
3975 };
3976
3977 bool IsKnownNoCapture;
3978 const AANoCapture *NoCaptureAA = nullptr;
3979 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
3980 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA);
3981 if (!IsAssumedNoCapture &&
3982 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
3983 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) {
3984 LLVM_DEBUG(
3985 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
3986 << " cannot be noalias as it is potentially captured\n");
3987 return false;
3988 }
3989 }
3990 if (NoCaptureAA)
3991 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL);
3992
3993 // Check there is no other pointer argument which could alias with the
3994 // value passed at this call site.
3995 // TODO: AbstractCallSite
3996 const auto &CB = cast<CallBase>(getAnchorValue());
3997 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++)
3998 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo))
3999 return false;
4000
4001 return true;
4002 }
4003
4004 /// See AbstractAttribute::updateImpl(...).
4005 ChangeStatus updateImpl(Attributor &A) override {
4006 // If the argument is readnone we are done as there are no accesses via the
4007 // argument.
4008 auto *MemBehaviorAA =
4009 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
4010 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
4011 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
4012 return ChangeStatus::UNCHANGED;
4013 }
4014
4015 bool IsKnownNoAlias;
4016 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
4017 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4018 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
4019 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
4020 << " is not no-alias at the definition\n");
4021 return indicatePessimisticFixpoint();
4022 }
4023
4024 AAResults *AAR = nullptr;
4025 if (MemBehaviorAA &&
4026 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) {
4027 LLVM_DEBUG(
4028 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
4029 return ChangeStatus::UNCHANGED;
4030 }
4031
4032 return indicatePessimisticFixpoint();
4033 }
4034
4035 /// See AbstractAttribute::trackStatistics()
4036 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
4037};
4038
4039/// NoAlias attribute for function return value.
4040struct AANoAliasReturned final : AANoAliasImpl {
4041 AANoAliasReturned(const IRPosition &IRP, Attributor &A)
4042 : AANoAliasImpl(IRP, A) {}
4043
4044 /// See AbstractAttribute::updateImpl(...).
4045 ChangeStatus updateImpl(Attributor &A) override {
4046
4047 auto CheckReturnValue = [&](Value &RV) -> bool {
4048 if (Constant *C = dyn_cast<Constant>(&RV))
4049 if (C->isNullValue() || isa<UndefValue>(C))
4050 return true;
4051
4052 /// For now, we can only deduce noalias if we have call sites.
4053 /// FIXME: add more support.
4054 if (!isa<CallBase>(&RV))
4055 return false;
4056
4057 const IRPosition &RVPos = IRPosition::value(RV);
4058 bool IsKnownNoAlias;
4059 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
4060 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias))
4061 return false;
4062
4063 bool IsKnownNoCapture;
4064 const AANoCapture *NoCaptureAA = nullptr;
4065 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
4066 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
4067 &NoCaptureAA);
4068 return IsAssumedNoCapture ||
4069 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned());
4070 };
4071
4072 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
4073 return indicatePessimisticFixpoint();
4074
4075 return ChangeStatus::UNCHANGED;
4076 }
4077
4078 /// See AbstractAttribute::trackStatistics()
4079 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
4080};
4081
4082/// NoAlias attribute deduction for a call site return value.
4083struct AANoAliasCallSiteReturned final
4084 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> {
4085 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A)
4086 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {}
4087
4088 /// See AbstractAttribute::trackStatistics()
4089 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
4090};
4091} // namespace
4092
4093/// -------------------AAIsDead Function Attribute-----------------------
4094
4095namespace {
4096struct AAIsDeadValueImpl : public AAIsDead {
4097 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4098
4099 /// See AAIsDead::isAssumedDead().
4100 bool isAssumedDead() const override { return isAssumed(IS_DEAD); }
4101
4102 /// See AAIsDead::isKnownDead().
4103 bool isKnownDead() const override { return isKnown(IS_DEAD); }
4104
4105 /// See AAIsDead::isAssumedDead(BasicBlock *).
4106 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
4107
4108 /// See AAIsDead::isKnownDead(BasicBlock *).
4109 bool isKnownDead(const BasicBlock *BB) const override { return false; }
4110
4111 /// See AAIsDead::isAssumedDead(Instruction *I).
4112 bool isAssumedDead(const Instruction *I) const override {
4113 return I == getCtxI() && isAssumedDead();
4114 }
4115
4116 /// See AAIsDead::isKnownDead(Instruction *I).
4117 bool isKnownDead(const Instruction *I) const override {
4118 return isAssumedDead(I) && isKnownDead();
4119 }
4120
4121 /// See AbstractAttribute::getAsStr().
4122 const std::string getAsStr(Attributor *A) const override {
4123 return isAssumedDead() ? "assumed-dead" : "assumed-live";
4124 }
4125
4126 /// Check if all uses are assumed dead.
4127 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
4128 // Callers might not check the type, void has no uses.
4129 if (V.getType()->isVoidTy() || V.use_empty())
4130 return true;
4131
4132 // If we replace a value with a constant there are no uses left afterwards.
4133 if (!isa<Constant>(V)) {
4134 if (auto *I = dyn_cast<Instruction>(&V))
4135 if (!A.isRunOn(*I->getFunction()))
4136 return false;
4137 bool UsedAssumedInformation = false;
4138 std::optional<Constant *> C =
4139 A.getAssumedConstant(V, *this, UsedAssumedInformation);
4140 if (!C || *C)
4141 return true;
4142 }
4143
4144 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
4145 // Explicitly set the dependence class to required because we want a long
4146 // chain of N dependent instructions to be considered live as soon as one is
4147 // without going through N update cycles. This is not required for
4148 // correctness.
4149 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false,
4150 DepClassTy::REQUIRED,
4151 /* IgnoreDroppableUses */ false);
4152 }
4153
4154 /// Determine if \p I is assumed to be side-effect free.
4155 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
4157 return true;
4158
4159 auto *CB = dyn_cast<CallBase>(I);
4160 if (!CB || isa<IntrinsicInst>(CB))
4161 return false;
4162
4163 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
4164
4165 bool IsKnownNoUnwind;
4166 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4167 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind))
4168 return false;
4169
4170 bool IsKnown;
4171 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown);
4172 }
4173};
4174
4175struct AAIsDeadFloating : public AAIsDeadValueImpl {
4176 AAIsDeadFloating(const IRPosition &IRP, Attributor &A)
4177 : AAIsDeadValueImpl(IRP, A) {}
4178
4179 /// See AbstractAttribute::initialize(...).
4180 void initialize(Attributor &A) override {
4181 AAIsDeadValueImpl::initialize(A);
4182
4183 if (isa<UndefValue>(getAssociatedValue())) {
4184 indicatePessimisticFixpoint();
4185 return;
4186 }
4187
4188 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4189 if (!isAssumedSideEffectFree(A, I)) {
4190 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I))
4191 indicatePessimisticFixpoint();
4192 else
4193 removeAssumedBits(HAS_NO_EFFECT);
4194 }
4195 }
4196
4197 bool isDeadFence(Attributor &A, FenceInst &FI) {
4198 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
4199 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE);
4200 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI))
4201 return false;
4202 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL);
4203 return true;
4204 }
4205
4206 bool isDeadStore(Attributor &A, StoreInst &SI,
4207 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) {
4208 // Lang ref now states volatile store is not UB/dead, let's skip them.
4209 if (SI.isVolatile())
4210 return false;
4211
4212 // If we are collecting assumes to be deleted we are in the manifest stage.
4213 // It's problematic to collect the potential copies again now so we use the
4214 // cached ones.
4215 bool UsedAssumedInformation = false;
4216 if (!AssumeOnlyInst) {
4217 PotentialCopies.clear();
4218 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this,
4219 UsedAssumedInformation)) {
4220 LLVM_DEBUG(
4221 dbgs()
4222 << "[AAIsDead] Could not determine potential copies of store!\n");
4223 return false;
4224 }
4225 }
4226 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size()
4227 << " potential copies.\n");
4228
4229 InformationCache &InfoCache = A.getInfoCache();
4230 return llvm::all_of(PotentialCopies, [&](Value *V) {
4231 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr,
4232 UsedAssumedInformation))
4233 return true;
4234 if (auto *LI = dyn_cast<LoadInst>(V)) {
4235 if (llvm::all_of(LI->uses(), [&](const Use &U) {
4236 auto &UserI = cast<Instruction>(*U.getUser());
4237 if (InfoCache.isOnlyUsedByAssume(UserI)) {
4238 if (AssumeOnlyInst)
4239 AssumeOnlyInst->insert(&UserI);
4240 return true;
4241 }
4242 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
4243 })) {
4244 return true;
4245 }
4246 }
4247 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V
4248 << " is assumed live!\n");
4249 return false;
4250 });
4251 }
4252
4253 /// See AbstractAttribute::getAsStr().
4254 const std::string getAsStr(Attributor *A) const override {
4255 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4256 if (isa_and_nonnull<StoreInst>(I))
4257 if (isValidState())
4258 return "assumed-dead-store";
4259 if (isa_and_nonnull<FenceInst>(I))
4260 if (isValidState())
4261 return "assumed-dead-fence";
4262 return AAIsDeadValueImpl::getAsStr(A);
4263 }
4264
4265 /// See AbstractAttribute::updateImpl(...).
4266 ChangeStatus updateImpl(Attributor &A) override {
4267 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
4268 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) {
4269 if (!isDeadStore(A, *SI))
4270 return indicatePessimisticFixpoint();
4271 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) {
4272 if (!isDeadFence(A, *FI))
4273 return indicatePessimisticFixpoint();
4274 } else {
4275 if (!isAssumedSideEffectFree(A, I))
4276 return indicatePessimisticFixpoint();
4277 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4278 return indicatePessimisticFixpoint();
4279 }
4281 }
4282
4283 bool isRemovableStore() const override {
4284 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue());
4285 }
4286
4287 /// See AbstractAttribute::manifest(...).
4288 ChangeStatus manifest(Attributor &A) override {
4289 Value &V = getAssociatedValue();
4290 if (auto *I = dyn_cast<Instruction>(&V)) {
4291 // If we get here we basically know the users are all dead. We check if
4292 // isAssumedSideEffectFree returns true here again because it might not be
4293 // the case and only the users are dead but the instruction (=call) is
4294 // still needed.
4295 if (auto *SI = dyn_cast<StoreInst>(I)) {
4296 SmallSetVector<Instruction *, 8> AssumeOnlyInst;
4297 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst);
4298 (void)IsDead;
4299 assert(IsDead && "Store was assumed to be dead!");
4300 A.deleteAfterManifest(*I);
4301 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) {
4302 Instruction *AOI = AssumeOnlyInst[i];
4303 for (auto *Usr : AOI->users())
4304 AssumeOnlyInst.insert(cast<Instruction>(Usr));
4305 A.deleteAfterManifest(*AOI);
4306 }
4307 return ChangeStatus::CHANGED;
4308 }
4309 if (auto *FI = dyn_cast<FenceInst>(I)) {
4310 assert(isDeadFence(A, *FI));
4311 A.deleteAfterManifest(*FI);
4312 return ChangeStatus::CHANGED;
4313 }
4314 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
4315 A.deleteAfterManifest(*I);
4316 return ChangeStatus::CHANGED;
4317 }
4318 }
4320 }
4321
4322 /// See AbstractAttribute::trackStatistics()
4323 void trackStatistics() const override {
4325 }
4326
4327private:
4328 // The potential copies of a dead store, used for deletion during manifest.
4329 SmallSetVector<Value *, 4> PotentialCopies;
4330};
4331
4332struct AAIsDeadArgument : public AAIsDeadFloating {
4333 AAIsDeadArgument(const IRPosition &IRP, Attributor &A)
4334 : AAIsDeadFloating(IRP, A) {}
4335
4336 /// See AbstractAttribute::manifest(...).
4337 ChangeStatus manifest(Attributor &A) override {
4338 Argument &Arg = *getAssociatedArgument();
4339 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
4340 if (A.registerFunctionSignatureRewrite(
4341 Arg, /* ReplacementTypes */ {},
4344 return ChangeStatus::CHANGED;
4345 }
4346 return ChangeStatus::UNCHANGED;
4347 }
4348
4349 /// See AbstractAttribute::trackStatistics()
4350 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
4351};
4352
4353struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
4354 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A)
4355 : AAIsDeadValueImpl(IRP, A) {}
4356
4357 /// See AbstractAttribute::initialize(...).
4358 void initialize(Attributor &A) override {
4359 AAIsDeadValueImpl::initialize(A);
4360 if (isa<UndefValue>(getAssociatedValue()))
4361 indicatePessimisticFixpoint();
4362 }
4363
4364 /// See AbstractAttribute::updateImpl(...).
4365 ChangeStatus updateImpl(Attributor &A) override {
4366 // TODO: Once we have call site specific value information we can provide
4367 // call site specific liveness information and then it makes
4368 // sense to specialize attributes for call sites arguments instead of
4369 // redirecting requests to the callee argument.
4370 Argument *Arg = getAssociatedArgument();
4371 if (!Arg)
4372 return indicatePessimisticFixpoint();
4373 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4374 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED);
4375 if (!ArgAA)
4376 return indicatePessimisticFixpoint();
4377 return clampStateAndIndicateChange(getState(), ArgAA->getState());
4378 }
4379
4380 /// See AbstractAttribute::manifest(...).
4381 ChangeStatus manifest(Attributor &A) override {
4382 CallBase &CB = cast<CallBase>(getAnchorValue());
4383 Use &U = CB.getArgOperandUse(getCallSiteArgNo());
4384 assert(!isa<UndefValue>(U.get()) &&
4385 "Expected undef values to be filtered out!");
4386 UndefValue &UV = *UndefValue::get(U->getType());
4387 if (A.changeUseAfterManifest(U, UV))
4388 return ChangeStatus::CHANGED;
4389 return ChangeStatus::UNCHANGED;
4390 }
4391
4392 /// See AbstractAttribute::trackStatistics()
4393 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
4394};
4395
4396struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
4397 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A)
4398 : AAIsDeadFloating(IRP, A) {}
4399
4400 /// See AAIsDead::isAssumedDead().
4401 bool isAssumedDead() const override {
4402 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
4403 }
4404
4405 /// See AbstractAttribute::initialize(...).
4406 void initialize(Attributor &A) override {
4407 AAIsDeadFloating::initialize(A);
4408 if (isa<UndefValue>(getAssociatedValue())) {
4409 indicatePessimisticFixpoint();
4410 return;
4411 }
4412
4413 // We track this separately as a secondary state.
4414 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
4415 }
4416
4417 /// See AbstractAttribute::updateImpl(...).
4418 ChangeStatus updateImpl(Attributor &A) override {
4419 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4420 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
4421 IsAssumedSideEffectFree = false;
4422 Changed = ChangeStatus::CHANGED;
4423 }
4424 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
4425 return indicatePessimisticFixpoint();
4426 return Changed;
4427 }
4428
4429 /// See AbstractAttribute::trackStatistics()
4430 void trackStatistics() const override {
4431 if (IsAssumedSideEffectFree)
4433 else
4434 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
4435 }
4436
4437 /// See AbstractAttribute::getAsStr().
4438 const std::string getAsStr(Attributor *A) const override {
4439 return isAssumedDead()
4440 ? "assumed-dead"
4441 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
4442 }
4443
4444private:
4445 bool IsAssumedSideEffectFree = true;
4446};
4447
4448struct AAIsDeadReturned : public AAIsDeadValueImpl {
4449 AAIsDeadReturned(const IRPosition &IRP, Attributor &A)
4450 : AAIsDeadValueImpl(IRP, A) {}
4451
4452 /// See AbstractAttribute::updateImpl(...).
4453 ChangeStatus updateImpl(Attributor &A) override {
4454
4455 bool UsedAssumedInformation = false;
4456 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
4457 {Instruction::Ret}, UsedAssumedInformation);
4458
4459 auto PredForCallSite = [&](AbstractCallSite ACS) {
4460 if (ACS.isCallbackCall() || !ACS.getInstruction())
4461 return false;
4462 return areAllUsesAssumedDead(A, *ACS.getInstruction());
4463 };
4464
4465 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4466 UsedAssumedInformation))
4467 return indicatePessimisticFixpoint();
4468
4469 return ChangeStatus::UNCHANGED;
4470 }
4471
4472 /// See AbstractAttribute::manifest(...).
4473 ChangeStatus manifest(Attributor &A) override {
4474 // TODO: Rewrite the signature to return void?
4475 bool AnyChange = false;
4476 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
4477 auto RetInstPred = [&](Instruction &I) {
4478 ReturnInst &RI = cast<ReturnInst>(I);
4479 if (!isa<UndefValue>(RI.getReturnValue()))
4480 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
4481 return true;
4482 };
4483 bool UsedAssumedInformation = false;
4484 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
4485 UsedAssumedInformation);
4486 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
4487 }
4488
4489 /// See AbstractAttribute::trackStatistics()
4490 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
4491};
4492
4493struct AAIsDeadFunction : public AAIsDead {
4494 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {}
4495
4496 /// See AbstractAttribute::initialize(...).
4497 void initialize(Attributor &A) override {
4498 Function *F = getAnchorScope();
4499 assert(F && "Did expect an anchor function");
4500 if (!isAssumedDeadInternalFunction(A)) {
4501 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4502 assumeLive(A, F->getEntryBlock());
4503 }
4504 }
4505
4506 bool isAssumedDeadInternalFunction(Attributor &A) {
4507 if (!getAnchorScope()->hasLocalLinkage())
4508 return false;
4509 bool UsedAssumedInformation = false;
4510 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this,
4511 true, UsedAssumedInformation);
4512 }
4513
4514 /// See AbstractAttribute::getAsStr().
4515 const std::string getAsStr(Attributor *A) const override {
4516 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
4517 std::to_string(getAnchorScope()->size()) + "][#TBEP " +
4518 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
4519 std::to_string(KnownDeadEnds.size()) + "]";
4520 }
4521
4522 /// See AbstractAttribute::manifest(...).
4523 ChangeStatus manifest(Attributor &A) override {
4524 assert(getState().isValidState() &&
4525 "Attempted to manifest an invalid state!");
4526
4527 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4528 Function &F = *getAnchorScope();
4529
4530 if (AssumedLiveBlocks.empty()) {
4531 A.deleteAfterManifest(F);
4532 return ChangeStatus::CHANGED;
4533 }
4534
4535 // Flag to determine if we can change an invoke to a call assuming the
4536 // callee is nounwind. This is not possible if the personality of the
4537 // function allows to catch asynchronous exceptions.
4538 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
4539
4540 KnownDeadEnds.set_union(ToBeExploredFrom);
4541 for (const Instruction *DeadEndI : KnownDeadEnds) {
4542 auto *CB = dyn_cast<CallBase>(DeadEndI);
4543 if (!CB)
4544 continue;
4545 bool IsKnownNoReturn;
4546 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>(
4547 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL,
4548 IsKnownNoReturn);
4549 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
4550 continue;
4551
4552 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
4553 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
4554 else
4555 A.changeToUnreachableAfterManifest(
4556 const_cast<Instruction *>(DeadEndI->getNextNode()));
4557 HasChanged = ChangeStatus::CHANGED;
4558 }
4559
4560 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
4561 for (BasicBlock &BB : F)
4562 if (!AssumedLiveBlocks.count(&BB)) {
4563 A.deleteAfterManifest(BB);
4565 HasChanged = ChangeStatus::CHANGED;
4566 }
4567
4568 return HasChanged;
4569 }
4570
4571 /// See AbstractAttribute::updateImpl(...).
4572 ChangeStatus updateImpl(Attributor &A) override;
4573
4574 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override {
4575 assert(From->getParent() == getAnchorScope() &&
4576 To->getParent() == getAnchorScope() &&
4577 "Used AAIsDead of the wrong function");
4578 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To));
4579 }
4580
4581 /// See AbstractAttribute::trackStatistics()
4582 void trackStatistics() const override {}
4583
4584 /// Returns true if the function is assumed dead.
4585 bool isAssumedDead() const override { return false; }
4586
4587 /// See AAIsDead::isKnownDead().
4588 bool isKnownDead() const override { return false; }
4589
4590 /// See AAIsDead::isAssumedDead(BasicBlock *).
4591 bool isAssumedDead(const BasicBlock *BB) const override {
4592 assert(BB->getParent() == getAnchorScope() &&
4593 "BB must be in the same anchor scope function.");
4594
4595 if (!getAssumed())
4596 return false;
4597 return !AssumedLiveBlocks.count(BB);
4598 }
4599
4600 /// See AAIsDead::isKnownDead(BasicBlock *).
4601 bool isKnownDead(const BasicBlock *BB) const override {
4602 return getKnown() && isAssumedDead(BB);
4603 }
4604
4605 /// See AAIsDead::isAssumed(Instruction *I).
4606 bool isAssumedDead(const Instruction *I) const override {
4607 assert(I->getParent()->getParent() == getAnchorScope() &&
4608 "Instruction must be in the same anchor scope function.");
4609
4610 if (!getAssumed())
4611 return false;
4612
4613 // If it is not in AssumedLiveBlocks then it for sure dead.
4614 // Otherwise, it can still be after noreturn call in a live block.
4615 if (!AssumedLiveBlocks.count(I->getParent()))
4616 return true;
4617
4618 // If it is not after a liveness barrier it is live.
4619 const Instruction *PrevI = I->getPrevNode();
4620 while (PrevI) {
4621 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
4622 return true;
4623 PrevI = PrevI->getPrevNode();
4624 }
4625 return false;
4626 }
4627
4628 /// See AAIsDead::isKnownDead(Instruction *I).
4629 bool isKnownDead(const Instruction *I) const override {
4630 return getKnown() && isAssumedDead(I);
4631 }
4632
4633 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
4634 /// that internal function called from \p BB should now be looked at.
4635 bool assumeLive(Attributor &A, const BasicBlock &BB) {
4636 if (!AssumedLiveBlocks.insert(&BB).second)
4637 return false;
4638
4639 // We assume that all of BB is (probably) live now and if there are calls to
4640 // internal functions we will assume that those are now live as well. This
4641 // is a performance optimization for blocks with calls to a lot of internal
4642 // functions. It can however cause dead functions to be treated as live.
4643 for (const Instruction &I : BB)
4644 if (const auto *CB = dyn_cast<CallBase>(&I))
4645 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand()))
4646 if (F->hasLocalLinkage())
4647 A.markLiveInternalFunction(*F);
4648 return true;
4649 }
4650
4651 /// Collection of instructions that need to be explored again, e.g., we
4652 /// did assume they do not transfer control to (one of their) successors.
4654
4655 /// Collection of instructions that are known to not transfer control.
4657
4658 /// Collection of all assumed live edges
4660
4661 /// Collection of all assumed live BasicBlocks.
4662 DenseSet<const BasicBlock *> AssumedLiveBlocks;
4663};
4664
4665static bool
4666identifyAliveSuccessors(Attributor &A, const CallBase &CB,
4668 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4669 const IRPosition &IPos = IRPosition::callsite_function(CB);
4670
4671 bool IsKnownNoReturn;
4672 if (AA::hasAssumedIRAttr<Attribute::NoReturn>(
4673 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn))
4674 return !IsKnownNoReturn;
4675 if (CB.isTerminator())
4676 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
4677 else
4678 AliveSuccessors.push_back(CB.getNextNode());
4679 return false;
4680}
4681
4682static bool
4683identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
4685 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4686 bool UsedAssumedInformation =
4687 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
4688
4689 // First, determine if we can change an invoke to a call assuming the
4690 // callee is nounwind. This is not possible if the personality of the
4691 // function allows to catch asynchronous exceptions.
4692 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
4693 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4694 } else {
4696
4697 bool IsKnownNoUnwind;
4698 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
4699 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
4700 UsedAssumedInformation |= !IsKnownNoUnwind;
4701 } else {
4702 AliveSuccessors.push_back(&II.getUnwindDest()->front());
4703 }
4704 }
4705 return UsedAssumedInformation;
4706}
4707
4708static bool
4709identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
4711 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4712 bool UsedAssumedInformation = false;
4713 if (BI.getNumSuccessors() == 1) {
4714 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4715 } else {
4716 std::optional<Constant *> C =
4717 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation);
4718 if (!C || isa_and_nonnull<UndefValue>(*C)) {
4719 // No value yet, assume both edges are dead.
4720 } else if (isa_and_nonnull<ConstantInt>(*C)) {
4721 const BasicBlock *SuccBB =
4722 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue());
4723 AliveSuccessors.push_back(&SuccBB->front());
4724 } else {
4725 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
4726 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
4727 UsedAssumedInformation = false;
4728 }
4729 }
4730 return UsedAssumedInformation;
4731}
4732
4733static bool
4734identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
4736 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
4737 bool UsedAssumedInformation = false;
4739 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA,
4740 Values, AA::AnyScope,
4741 UsedAssumedInformation)) {
4742 // Something went wrong, assume all successors are live.
4743 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4744 AliveSuccessors.push_back(&SuccBB->front());
4745 return false;
4746 }
4747
4748 if (Values.empty() ||
4749 (Values.size() == 1 &&
4750 isa_and_nonnull<UndefValue>(Values.front().getValue()))) {
4751 // No valid value yet, assume all edges are dead.
4752 return UsedAssumedInformation;
4753 }
4754
4755 Type &Ty = *SI.getCondition()->getType();
4757 auto CheckForConstantInt = [&](Value *V) {
4758 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) {
4759 Constants.insert(CI);
4760 return true;
4761 }
4762 return false;
4763 };
4764
4765 if (!all_of(Values, [&](AA::ValueAndContext &VAC) {
4766 return CheckForConstantInt(VAC.getValue());
4767 })) {
4768 for (const BasicBlock *SuccBB : successors(SI.getParent()))
4769 AliveSuccessors.push_back(&SuccBB->front());
4770 return UsedAssumedInformation;
4771 }
4772
4773 unsigned MatchedCases = 0;
4774 for (const auto &CaseIt : SI.cases()) {
4775 if (Constants.count(CaseIt.getCaseValue())) {
4776 ++MatchedCases;
4777 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
4778 }
4779 }
4780
4781 // If all potential values have been matched, we will not visit the default
4782 // case.
4783 if (MatchedCases < Constants.size())
4784 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
4785 return UsedAssumedInformation;
4786}
4787
4788ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
4790
4791 if (AssumedLiveBlocks.empty()) {
4792 if (isAssumedDeadInternalFunction(A))
4794
4795 Function *F = getAnchorScope();
4796 ToBeExploredFrom.insert(&F->getEntryBlock().front());
4797 assumeLive(A, F->getEntryBlock());
4798 Change = ChangeStatus::CHANGED;
4799 }
4800
4801 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
4802 << getAnchorScope()->size() << "] BBs and "
4803 << ToBeExploredFrom.size() << " exploration points and "
4804 << KnownDeadEnds.size() << " known dead ends\n");
4805
4806 // Copy and clear the list of instructions we need to explore from. It is
4807 // refilled with instructions the next update has to look at.
4808 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
4809 ToBeExploredFrom.end());
4810 decltype(ToBeExploredFrom) NewToBeExploredFrom;
4811
4813 while (!Worklist.empty()) {
4814 const Instruction *I = Worklist.pop_back_val();
4815 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
4816
4817 // Fast forward for uninteresting instructions. We could look for UB here
4818 // though.
4819 while (!I->isTerminator() && !isa<CallBase>(I))
4820 I = I->getNextNode();
4821
4822 AliveSuccessors.clear();
4823
4824 bool UsedAssumedInformation = false;
4825 switch (I->getOpcode()) {
4826 // TODO: look for (assumed) UB to backwards propagate "deadness".
4827 default:
4828 assert(I->isTerminator() &&
4829 "Expected non-terminators to be handled already!");
4830 for (const BasicBlock *SuccBB : successors(I->getParent()))
4831 AliveSuccessors.push_back(&SuccBB->front());
4832 break;
4833 case Instruction::Call:
4834 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
4835 *this, AliveSuccessors);
4836 break;
4837 case Instruction::Invoke:
4838 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
4839 *this, AliveSuccessors);
4840 break;
4841 case Instruction::Br:
4842 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
4843 *this, AliveSuccessors);
4844 break;
4845 case Instruction::Switch:
4846 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
4847 *this, AliveSuccessors);
4848 break;
4849 }
4850
4851 if (UsedAssumedInformation) {
4852 NewToBeExploredFrom.insert(I);
4853 } else if (AliveSuccessors.empty() ||
4854 (I->isTerminator() &&
4855 AliveSuccessors.size() < I->getNumSuccessors())) {
4856 if (KnownDeadEnds.insert(I))
4857 Change = ChangeStatus::CHANGED;
4858 }
4859
4860 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
4861 << AliveSuccessors.size() << " UsedAssumedInformation: "
4862 << UsedAssumedInformation << "\n");
4863
4864 for (const Instruction *AliveSuccessor : AliveSuccessors) {
4865 if (!I->isTerminator()) {
4866 assert(AliveSuccessors.size() == 1 &&
4867 "Non-terminator expected to have a single successor!");
4868 Worklist.push_back(AliveSuccessor);
4869 } else {
4870 // record the assumed live edge
4871 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent());
4872 if (AssumedLiveEdges.insert(Edge).second)
4873 Change = ChangeStatus::CHANGED;
4874 if (assumeLive(A, *AliveSuccessor->getParent()))
4875 Worklist.push_back(AliveSuccessor);
4876 }
4877 }
4878 }
4879
4880 // Check if the content of ToBeExploredFrom changed, ignore the order.
4881 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() ||
4882 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) {
4883 return !ToBeExploredFrom.count(I);
4884 })) {
4885 Change = ChangeStatus::CHANGED;
4886 ToBeExploredFrom = std::move(NewToBeExploredFrom);
4887 }
4888
4889 // If we know everything is live there is no need to query for liveness.
4890 // Instead, indicating a pessimistic fixpoint will cause the state to be
4891 // "invalid" and all queries to be answered conservatively without lookups.
4892 // To be in this state we have to (1) finished the exploration and (3) not
4893 // discovered any non-trivial dead end and (2) not ruled unreachable code
4894 // dead.
4895 if (ToBeExploredFrom.empty() &&
4896 getAnchorScope()->size() == AssumedLiveBlocks.size() &&
4897 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
4898 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
4899 }))
4900 return indicatePessimisticFixpoint();
4901 return Change;
4902}
4903
4904/// Liveness information for a call sites.
4905struct AAIsDeadCallSite final : AAIsDeadFunction {
4906 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A)
4907 : AAIsDeadFunction(IRP, A) {}
4908
4909 /// See AbstractAttribute::initialize(...).
4910 void initialize(Attributor &A) override {
4911 // TODO: Once we have call site specific value information we can provide
4912 // call site specific liveness information and then it makes
4913 // sense to specialize attributes for call sites instead of
4914 // redirecting requests to the callee.
4915 llvm_unreachable("Abstract attributes for liveness are not "
4916 "supported for call sites yet!");
4917 }
4918
4919 /// See AbstractAttribute::updateImpl(...).
4920 ChangeStatus updateImpl(Attributor &A) override {
4921 return indicatePessimisticFixpoint();
4922 }
4923
4924 /// See AbstractAttribute::trackStatistics()
4925 void trackStatistics() const override {}
4926};
4927} // namespace
4928
4929/// -------------------- Dereferenceable Argument Attribute --------------------
4930
4931namespace {
4932struct AADereferenceableImpl : AADereferenceable {
4933 AADereferenceableImpl(const IRPosition &IRP, Attributor &A)
4934 : AADereferenceable(IRP, A) {}
4935 using StateType = DerefState;
4936
4937 /// See AbstractAttribute::initialize(...).
4938 void initialize(Attributor &A) override {
4939 Value &V = *getAssociatedValue().stripPointerCasts();
4941 A.getAttrs(getIRPosition(),
4942 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
4943 Attrs, /* IgnoreSubsumingPositions */ false);
4944 for (const Attribute &Attr : Attrs)
4945 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
4946
4947 // Ensure we initialize the non-null AA (if necessary).
4948 bool IsKnownNonNull;
4949 AA::hasAssumedIRAttr<Attribute::NonNull>(
4950 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull);
4951
4952 bool CanBeNull, CanBeFreed;
4953 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes(
4954 A.getDataLayout(), CanBeNull, CanBeFreed));
4955
4956 if (Instruction *CtxI = getCtxI())
4957 followUsesInMBEC(*this, A, getState(), *CtxI);
4958 }
4959
4960 /// See AbstractAttribute::getState()
4961 /// {
4962 StateType &getState() override { return *this; }
4963 const StateType &getState() const override { return *this; }
4964 /// }
4965
4966 /// Helper function for collecting accessed bytes in must-be-executed-context
4967 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I,
4968 DerefState &State) {
4969 const Value *UseV = U->get();
4970 if (!UseV->getType()->isPointerTy())
4971 return;
4972
4973 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I);
4974 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile())
4975 return;
4976
4977 int64_t Offset;
4979 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true);
4980 if (Base && Base == &getAssociatedValue())
4981 State.addAccessedBytes(Offset, Loc->Size.getValue());
4982 }
4983
4984 /// See followUsesInMBEC
4985 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
4987 bool IsNonNull = false;
4988 bool TrackUse = false;
4989 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
4990 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
4991 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes
4992 << " for instruction " << *I << "\n");
4993
4994 addAccessedBytesForUse(A, U, I, State);
4995 State.takeKnownDerefBytesMaximum(DerefBytes);
4996 return TrackUse;
4997 }
4998
4999 /// See AbstractAttribute::manifest(...).
5000 ChangeStatus manifest(Attributor &A) override {
5001 ChangeStatus Change = AADereferenceable::manifest(A);
5002 bool IsKnownNonNull;
5003 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5004 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5005 if (IsAssumedNonNull &&
5006 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) {
5007 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull});
5008 return ChangeStatus::CHANGED;
5009 }
5010 return Change;
5011 }
5012
5013 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5014 SmallVectorImpl<Attribute> &Attrs) const override {
5015 // TODO: Add *_globally support
5016 bool IsKnownNonNull;
5017 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5018 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5019 if (IsAssumedNonNull)
5021 Ctx, getAssumedDereferenceableBytes()));
5022 else
5024 Ctx, getAssumedDereferenceableBytes()));
5025 }
5026
5027 /// See AbstractAttribute::getAsStr().
5028 const std::string getAsStr(Attributor *A) const override {
5029 if (!getAssumedDereferenceableBytes())
5030 return "unknown-dereferenceable";
5031 bool IsKnownNonNull;
5032 bool IsAssumedNonNull = false;
5033 if (A)
5034 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
5035 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull);
5036 return std::string("dereferenceable") +
5037 (IsAssumedNonNull ? "" : "_or_null") +
5038 (isAssumedGlobal() ? "_globally" : "") + "<" +
5039 std::to_string(getKnownDereferenceableBytes()) + "-" +
5040 std::to_string(getAssumedDereferenceableBytes()) + ">" +
5041 (!A ? " [non-null is unknown]" : "");
5042 }
5043};
5044
5045/// Dereferenceable attribute for a floating value.
5046struct AADereferenceableFloating : AADereferenceableImpl {
5047 AADereferenceableFloating(const IRPosition &IRP, Attributor &A)
5048 : AADereferenceableImpl(IRP, A) {}
5049
5050 /// See AbstractAttribute::updateImpl(...).
5051 ChangeStatus updateImpl(Attributor &A) override {
5052 bool Stripped;
5053 bool UsedAssumedInformation = false;
5055 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5056 AA::AnyScope, UsedAssumedInformation)) {
5057 Values.push_back({getAssociatedValue(), getCtxI()});
5058 Stripped = false;
5059 } else {
5060 Stripped = Values.size() != 1 ||
5061 Values.front().getValue() != &getAssociatedValue();
5062 }
5063
5064 const DataLayout &DL = A.getDataLayout();
5065 DerefState T;
5066
5067 auto VisitValueCB = [&](const Value &V) -> bool {
5068 unsigned IdxWidth =
5069 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
5070 APInt Offset(IdxWidth, 0);
5072 A, *this, &V, DL, Offset, /* GetMinOffset */ false,
5073 /* AllowNonInbounds */ true);
5074
5075 const auto *AA = A.getAAFor<AADereferenceable>(
5076 *this, IRPosition::value(*Base), DepClassTy::REQUIRED);
5077 int64_t DerefBytes = 0;
5078 if (!AA || (!Stripped && this == AA)) {
5079 // Use IR information if we did not strip anything.
5080 // TODO: track globally.
5081 bool CanBeNull, CanBeFreed;
5082 DerefBytes =
5083 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
5084 T.GlobalState.indicatePessimisticFixpoint();
5085 } else {
5086 const DerefState &DS = AA->getState();
5087 DerefBytes = DS.DerefBytesState.getAssumed();
5088 T.GlobalState &= DS.GlobalState;
5089 }
5090
5091 // For now we do not try to "increase" dereferenceability due to negative
5092 // indices as we first have to come up with code to deal with loops and
5093 // for overflows of the dereferenceable bytes.
5094 int64_t OffsetSExt = Offset.getSExtValue();
5095 if (OffsetSExt < 0)
5096 OffsetSExt = 0;
5097
5098 T.takeAssumedDerefBytesMinimum(
5099 std::max(int64_t(0), DerefBytes - OffsetSExt));
5100
5101 if (this == AA) {
5102 if (!Stripped) {
5103 // If nothing was stripped IR information is all we got.
5104 T.takeKnownDerefBytesMaximum(
5105 std::max(int64_t(0), DerefBytes - OffsetSExt));
5106 T.indicatePessimisticFixpoint();
5107 } else if (OffsetSExt > 0) {
5108 // If something was stripped but there is circular reasoning we look
5109 // for the offset. If it is positive we basically decrease the
5110 // dereferenceable bytes in a circular loop now, which will simply
5111 // drive them down to the known value in a very slow way which we
5112 // can accelerate.
5113 T.indicatePessimisticFixpoint();
5114 }
5115 }
5116
5117 return T.isValidState();
5118 };
5119
5120 for (const auto &VAC : Values)
5121 if (!VisitValueCB(*VAC.getValue()))
5122 return indicatePessimisticFixpoint();
5123
5124 return clampStateAndIndicateChange(getState(), T);
5125 }
5126
5127 /// See AbstractAttribute::trackStatistics()
5128 void trackStatistics() const override {
5129 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
5130 }
5131};
5132
5133/// Dereferenceable attribute for a return value.
5134struct AADereferenceableReturned final
5135 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
5136 using Base =
5137 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>;
5138 AADereferenceableReturned(const IRPosition &IRP, Attributor &A)
5139 : Base(IRP, A) {}
5140
5141 /// See AbstractAttribute::trackStatistics()
5142 void trackStatistics() const override {
5143 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
5144 }
5145};
5146
5147/// Dereferenceable attribute for an argument
5148struct AADereferenceableArgument final
5149 : AAArgumentFromCallSiteArguments<AADereferenceable,
5150 AADereferenceableImpl> {
5151 using Base =
5152 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>;
5153 AADereferenceableArgument(const IRPosition &IRP, Attributor &A)
5154 : Base(IRP, A) {}
5155
5156 /// See AbstractAttribute::trackStatistics()
5157 void trackStatistics() const override {
5158 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
5159 }
5160};
5161
5162/// Dereferenceable attribute for a call site argument.
5163struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
5164 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A)
5165 : AADereferenceableFloating(IRP, A) {}
5166
5167 /// See AbstractAttribute::trackStatistics()
5168 void trackStatistics() const override {
5169 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
5170 }
5171};
5172
5173/// Dereferenceable attribute deduction for a call site return value.
5174struct AADereferenceableCallSiteReturned final
5175 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> {
5176 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>;
5177 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A)
5178 : Base(IRP, A) {}
5179
5180 /// See AbstractAttribute::trackStatistics()
5181 void trackStatistics() const override {
5182 STATS_DECLTRACK_CS_ATTR(dereferenceable);
5183 }
5184};
5185} // namespace
5186
5187// ------------------------ Align Argument Attribute ------------------------
5188
5189namespace {
5190static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA,
5191 Value &AssociatedValue, const Use *U,
5192 const Instruction *I, bool &TrackUse) {
5193 // We need to follow common pointer manipulation uses to the accesses they
5194 // feed into.
5195 if (isa<CastInst>(I)) {
5196 // Follow all but ptr2int casts.
5197 TrackUse = !isa<PtrToIntInst>(I);
5198 return 0;
5199 }
5200 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
5201 if (GEP->hasAllConstantIndices())
5202 TrackUse = true;
5203 return 0;
5204 }
5205
5206 MaybeAlign MA;
5207 if (const auto *CB = dyn_cast<CallBase>(I)) {
5208 if (CB->isBundleOperand(U) || CB->isCallee(U))
5209 return 0;
5210
5211 unsigned ArgNo = CB->getArgOperandNo(U);
5212 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
5213 // As long as we only use known information there is no need to track
5214 // dependences here.
5215 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE);
5216 if (AlignAA)
5217 MA = MaybeAlign(AlignAA->getKnownAlign());
5218 }
5219
5220 const DataLayout &DL = A.getDataLayout();
5221 const Value *UseV = U->get();
5222 if (auto *SI = dyn_cast<StoreInst>(I)) {
5223 if (SI->getPointerOperand() == UseV)
5224 MA = SI->getAlign();
5225 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
5226 if (LI->getPointerOperand() == UseV)
5227 MA = LI->getAlign();
5228 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) {
5229 if (AI->getPointerOperand() == UseV)
5230 MA = AI->getAlign();
5231 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) {
5232 if (AI->getPointerOperand() == UseV)
5233 MA = AI->getAlign();
5234 }
5235
5236 if (!MA || *MA <= QueryingAA.getKnownAlign())
5237 return 0;
5238
5239 unsigned Alignment = MA->value();
5240 int64_t Offset;
5241
5242 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
5243 if (Base == &AssociatedValue) {
5244 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5245 // So we can say that the maximum power of two which is a divisor of
5246 // gcd(Offset, Alignment) is an alignment.
5247
5248 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment);
5249 Alignment = llvm::bit_floor(gcd);
5250 }
5251 }
5252
5253 return Alignment;
5254}
5255
5256struct AAAlignImpl : AAAlign {
5257 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {}
5258
5259 /// See AbstractAttribute::initialize(...).
5260 void initialize(Attributor &A) override {
5262 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs);
5263 for (const Attribute &Attr : Attrs)
5264 takeKnownMaximum(Attr.getValueAsInt());
5265
5266 Value &V = *getAssociatedValue().stripPointerCasts();
5267 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value());
5268
5269 if (Instruction *CtxI = getCtxI())
5270 followUsesInMBEC(*this, A, getState(), *CtxI);
5271 }
5272
5273 /// See AbstractAttribute::manifest(...).
5274 ChangeStatus manifest(Attributor &A) override {
5275 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED;
5276
5277 // Check for users that allow alignment annotations.
5278 Value &AssociatedValue = getAssociatedValue();
5279 if (isa<ConstantData>(AssociatedValue))
5280 return ChangeStatus::UNCHANGED;
5281
5282 for (const Use &U : AssociatedValue.uses()) {
5283 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
5284 if (SI->getPointerOperand() == &AssociatedValue)
5285 if (SI->getAlign() < getAssumedAlign()) {
5286 STATS_DECLTRACK(AAAlign, Store,
5287 "Number of times alignment added to a store");
5288 SI->setAlignment(getAssumedAlign());
5289 InstrChanged = ChangeStatus::CHANGED;
5290 }
5291 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
5292 if (LI->getPointerOperand() == &AssociatedValue)
5293 if (LI->getAlign() < getAssumedAlign()) {
5294 LI->setAlignment(getAssumedAlign());
5296 "Number of times alignment added to a load");
5297 InstrChanged = ChangeStatus::CHANGED;
5298 }
5299 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) {
5300 if (RMW->getPointerOperand() == &AssociatedValue) {
5301 if (RMW->getAlign() < getAssumedAlign()) {
5302 STATS_DECLTRACK(AAAlign, AtomicRMW,
5303 "Number of times alignment added to atomicrmw");
5304
5305 RMW->setAlignment(getAssumedAlign());
5306 InstrChanged = ChangeStatus::CHANGED;
5307 }
5308 }
5309 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) {
5310 if (CAS->getPointerOperand() == &AssociatedValue) {
5311 if (CAS->getAlign() < getAssumedAlign()) {
5312 STATS_DECLTRACK(AAAlign, AtomicCmpXchg,
5313 "Number of times alignment added to cmpxchg");
5314 CAS->setAlignment(getAssumedAlign());
5315 InstrChanged = ChangeStatus::CHANGED;
5316 }
5317 }
5318 }
5319 }
5320
5321 ChangeStatus Changed = AAAlign::manifest(A);
5322
5323 Align InheritAlign =
5324 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5325 if (InheritAlign >= getAssumedAlign())
5326 return InstrChanged;
5327 return Changed | InstrChanged;
5328 }
5329
5330 // TODO: Provide a helper to determine the implied ABI alignment and check in
5331 // the existing manifest method and a new one for AAAlignImpl that value
5332 // to avoid making the alignment explicit if it did not improve.
5333
5334 /// See AbstractAttribute::getDeducedAttributes
5335 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5336 SmallVectorImpl<Attribute> &Attrs) const override {
5337 if (getAssumedAlign() > 1)
5338 Attrs.emplace_back(
5339 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
5340 }
5341
5342 /// See followUsesInMBEC
5343 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
5344 AAAlign::StateType &State) {
5345 bool TrackUse = false;
5346
5347 unsigned int KnownAlign =
5348 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
5349 State.takeKnownMaximum(KnownAlign);
5350
5351 return TrackUse;
5352 }
5353
5354 /// See AbstractAttribute::getAsStr().
5355 const std::string getAsStr(Attributor *A) const override {
5356 return "align<" + std::to_string(getKnownAlign().value()) + "-" +
5357 std::to_string(getAssumedAlign().value()) + ">";
5358 }
5359};
5360
5361/// Align attribute for a floating value.
5362struct AAAlignFloating : AAAlignImpl {
5363 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {}
5364
5365 /// See AbstractAttribute::updateImpl(...).
5366 ChangeStatus updateImpl(Attributor &A) override {
5367 const DataLayout &DL = A.getDataLayout();
5368
5369 bool Stripped;
5370 bool UsedAssumedInformation = false;
5372 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
5373 AA::AnyScope, UsedAssumedInformation)) {
5374 Values.push_back({getAssociatedValue(), getCtxI()});
5375 Stripped = false;
5376 } else {
5377 Stripped = Values.size() != 1 ||
5378 Values.front().getValue() != &getAssociatedValue();
5379 }
5380
5381 StateType T;
5382 auto VisitValueCB = [&](Value &V) -> bool {
5383 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V))
5384 return true;
5385 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V),
5386 DepClassTy::REQUIRED);
5387 if (!AA || (!Stripped && this == AA)) {
5388 int64_t Offset;
5389 unsigned Alignment = 1;
5390 if (const Value *Base =
5392 // TODO: Use AAAlign for the base too.
5393 Align PA = Base->getPointerAlignment(DL);
5394 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
5395 // So we can say that the maximum power of two which is a divisor of
5396 // gcd(Offset, Alignment) is an alignment.
5397
5398 uint32_t gcd =
5399 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value()));
5400 Alignment = llvm::bit_floor(gcd);
5401 } else {
5402 Alignment = V.getPointerAlignment(DL).value();
5403 }
5404 // Use only IR information if we did not strip anything.
5405 T.takeKnownMaximum(Alignment);
5406 T.indicatePessimisticFixpoint();
5407 } else {
5408 // Use abstract attribute information.
5409 const AAAlign::StateType &DS = AA->getState();
5410 T ^= DS;
5411 }
5412 return T.isValidState();
5413 };
5414
5415 for (const auto &VAC : Values) {
5416 if (!VisitValueCB(*VAC.getValue()))
5417 return indicatePessimisticFixpoint();
5418 }
5419
5420 // TODO: If we know we visited all incoming values, thus no are assumed
5421 // dead, we can take the known information from the state T.
5422 return clampStateAndIndicateChange(getState(), T);
5423 }
5424
5425 /// See AbstractAttribute::trackStatistics()
5426 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
5427};
5428
5429/// Align attribute for function return value.
5430struct AAAlignReturned final
5431 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
5432 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>;
5433 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5434
5435 /// See AbstractAttribute::trackStatistics()
5436 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
5437};
5438
5439/// Align attribute for function argument.
5440struct AAAlignArgument final
5441 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
5442 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>;
5443 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {}
5444
5445 /// See AbstractAttribute::manifest(...).
5446 ChangeStatus manifest(Attributor &A) override {
5447 // If the associated argument is involved in a must-tail call we give up
5448 // because we would need to keep the argument alignments of caller and
5449 // callee in-sync. Just does not seem worth the trouble right now.
5450 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument()))
5451 return ChangeStatus::UNCHANGED;
5452 return Base::manifest(A);
5453 }
5454
5455 /// See AbstractAttribute::trackStatistics()
5456 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
5457};
5458
5459struct AAAlignCallSiteArgument final : AAAlignFloating {
5460 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A)
5461 : AAAlignFloating(IRP, A) {}
5462
5463 /// See AbstractAttribute::manifest(...).
5464 ChangeStatus manifest(Attributor &A) override {
5465 // If the associated argument is involved in a must-tail call we give up
5466 // because we would need to keep the argument alignments of caller and
5467 // callee in-sync. Just does not seem worth the trouble right now.
5468 if (Argument *Arg = getAssociatedArgument())
5469 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg))
5470 return ChangeStatus::UNCHANGED;
5471 ChangeStatus Changed = AAAlignImpl::manifest(A);
5472 Align InheritAlign =
5473 getAssociatedValue().getPointerAlignment(A.getDataLayout());
5474 if (InheritAlign >= getAssumedAlign())
5475 Changed = ChangeStatus::UNCHANGED;
5476 return Changed;
5477 }
5478
5479 /// See AbstractAttribute::updateImpl(Attributor &A).
5480 ChangeStatus updateImpl(Attributor &A) override {
5481 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
5482 if (Argument *Arg = getAssociatedArgument()) {
5483 // We only take known information from the argument
5484 // so we do not need to track a dependence.
5485 const auto *ArgAlignAA = A.getAAFor<AAAlign>(
5486 *this, IRPosition::argument(*Arg), DepClassTy::NONE);
5487 if (ArgAlignAA)
5488 takeKnownMaximum(ArgAlignAA->getKnownAlign().value());
5489 }
5490 return Changed;
5491 }
5492
5493 /// See AbstractAttribute::trackStatistics()
5494 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
5495};
5496
5497/// Align attribute deduction for a call site return value.
5498struct AAAlignCallSiteReturned final
5499 : AACalleeToCallSite<AAAlign, AAAlignImpl> {
5500 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>;
5501 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A)
5502 : Base(IRP, A) {}
5503
5504 /// See AbstractAttribute::trackStatistics()
5505 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
5506};
5507} // namespace
5508
5509/// ------------------ Function No-Return Attribute ----------------------------
5510namespace {
5511struct AANoReturnImpl : public AANoReturn {
5512 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {}
5513
5514 /// See AbstractAttribute::initialize(...).
5515 void initialize(Attributor &A) override {
5516 bool IsKnown;
5517 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>(
5518 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5519 (void)IsKnown;
5520 }
5521
5522 /// See AbstractAttribute::getAsStr().
5523 const std::string getAsStr(Attributor *A) const override {
5524 return getAssumed() ? "noreturn" : "may-return";
5525 }
5526
5527 /// See AbstractAttribute::updateImpl(Attributor &A).
5528 ChangeStatus updateImpl(Attributor &A) override {
5529 auto CheckForNoReturn = [](Instruction &) { return false; };
5530 bool UsedAssumedInformation = false;
5531 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
5532 {(unsigned)Instruction::Ret},
5533 UsedAssumedInformation))
5534 return indicatePessimisticFixpoint();
5535 return ChangeStatus::UNCHANGED;
5536 }
5537};
5538
5539struct AANoReturnFunction final : AANoReturnImpl {
5540 AANoReturnFunction(const IRPosition &IRP, Attributor &A)
5541 : AANoReturnImpl(IRP, A) {}
5542
5543 /// See AbstractAttribute::trackStatistics()
5544 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
5545};
5546
5547/// NoReturn attribute deduction for a call sites.
5548struct AANoReturnCallSite final
5549 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> {
5550 AANoReturnCallSite(const IRPosition &IRP, Attributor &A)
5551 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {}
5552
5553 /// See AbstractAttribute::trackStatistics()
5554 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
5555};
5556} // namespace
5557
5558/// ----------------------- Instance Info ---------------------------------
5559
5560namespace {
5561/// A class to hold the state of for no-capture attributes.
5562struct AAInstanceInfoImpl : public AAInstanceInfo {
5563 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A)
5564 : AAInstanceInfo(IRP, A) {}
5565
5566 /// See AbstractAttribute::initialize(...).
5567 void initialize(Attributor &A) override {
5568 Value &V = getAssociatedValue();
5569 if (auto *C = dyn_cast<Constant>(&V)) {
5570 if (C->isThreadDependent())
5571 indicatePessimisticFixpoint();
5572 else
5573 indicateOptimisticFixpoint();
5574 return;
5575 }
5576 if (auto *CB = dyn_cast<CallBase>(&V))
5577 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() &&
5578 !CB->mayReadFromMemory()) {
5579 indicateOptimisticFixpoint();
5580 return;
5581 }
5582 if (auto *I = dyn_cast<Instruction>(&V)) {
5583 const auto *CI =
5584 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
5585 *I->getFunction());
5586 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) {
5587 indicatePessimisticFixpoint();
5588 return;
5589 }
5590 }
5591 }
5592
5593 /// See AbstractAttribute::updateImpl(...).
5594 ChangeStatus updateImpl(Attributor &A) override {
5595 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5596
5597 Value &V = getAssociatedValue();
5598 const Function *Scope = nullptr;
5599 if (auto *I = dyn_cast<Instruction>(&V))
5600 Scope = I->getFunction();
5601 if (auto *A = dyn_cast<Argument>(&V)) {
5602 Scope = A->getParent();
5603 if (!Scope->hasLocalLinkage())
5604 return Changed;
5605 }
5606 if (!Scope)
5607 return indicateOptimisticFixpoint();
5608
5609 bool IsKnownNoRecurse;
5610 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>(
5611 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL,
5612 IsKnownNoRecurse))
5613 return Changed;
5614
5615 auto UsePred = [&](const Use &U, bool &Follow) {
5616 const Instruction *UserI = dyn_cast<Instruction>(U.getUser());
5617 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) ||
5618 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5619 Follow = true;
5620 return true;
5621 }
5622 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) ||
5623 (isa<StoreInst>(UserI) &&
5624 cast<StoreInst>(UserI)->getValueOperand() != U.get()))
5625 return true;
5626 if (auto *CB = dyn_cast<CallBase>(UserI)) {
5627 // This check is not guaranteeing uniqueness but for now that we cannot
5628 // end up with two versions of \p U thinking it was one.
5629 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand());
5630 if (!Callee || !Callee->hasLocalLinkage())
5631 return true;
5632 if (!CB->isArgOperand(&U))
5633 return false;
5634 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>(
5636 DepClassTy::OPTIONAL);
5637 if (!ArgInstanceInfoAA ||
5638 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis())
5639 return false;
5640 // If this call base might reach the scope again we might forward the
5641 // argument back here. This is very conservative.
5643 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr,
5644 [Scope](const Function &Fn) { return &Fn != Scope; }))
5645 return false;
5646 return true;
5647 }
5648 return false;
5649 };
5650
5651 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
5652 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) {
5653 auto *Ptr = SI->getPointerOperand()->stripPointerCasts();
5654 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) &&
5655 AA::isDynamicallyUnique(A, *this, *Ptr))
5656 return true;
5657 }
5658 return false;
5659 };
5660
5661 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true,
5662 DepClassTy::OPTIONAL,
5663 /* IgnoreDroppableUses */ true, EquivalentUseCB))
5664 return indicatePessimisticFixpoint();
5665
5666 return Changed;
5667 }
5668
5669 /// See AbstractState::getAsStr().
5670 const std::string getAsStr(Attributor *A) const override {
5671 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>";
5672 }
5673
5674 /// See AbstractAttribute::trackStatistics()
5675 void trackStatistics() const override {}
5676};
5677
5678/// InstanceInfo attribute for floating values.
5679struct AAInstanceInfoFloating : AAInstanceInfoImpl {
5680 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A)
5681 : AAInstanceInfoImpl(IRP, A) {}
5682};
5683
5684/// NoCapture attribute for function arguments.
5685struct AAInstanceInfoArgument final : AAInstanceInfoFloating {
5686 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A)
5687 : AAInstanceInfoFloating(IRP, A) {}
5688};
5689
5690/// InstanceInfo attribute for call site arguments.
5691struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl {
5692 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
5693 : AAInstanceInfoImpl(IRP, A) {}
5694
5695 /// See AbstractAttribute::updateImpl(...).
5696 ChangeStatus updateImpl(Attributor &A) override {
5697 // TODO: Once we have call site specific value information we can provide
5698 // call site specific liveness information and then it makes
5699 // sense to specialize attributes for call sites arguments instead of
5700 // redirecting requests to the callee argument.
5701 Argument *Arg = getAssociatedArgument();
5702 if (!Arg)
5703 return indicatePessimisticFixpoint();
5704 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5705 auto *ArgAA =
5706 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED);
5707 if (!ArgAA)
5708 return indicatePessimisticFixpoint();
5709 return clampStateAndIndicateChange(getState(), ArgAA->getState());
5710 }
5711};
5712
5713/// InstanceInfo attribute for function return value.
5714struct AAInstanceInfoReturned final : AAInstanceInfoImpl {
5715 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A)
5716 : AAInstanceInfoImpl(IRP, A) {
5717 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5718 }
5719
5720 /// See AbstractAttribute::initialize(...).
5721 void initialize(Attributor &A) override {
5722 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5723 }
5724
5725 /// See AbstractAttribute::updateImpl(...).
5726 ChangeStatus updateImpl(Attributor &A) override {
5727 llvm_unreachable("InstanceInfo is not applicable to function returns!");
5728 }
5729};
5730
5731/// InstanceInfo attribute deduction for a call site return value.
5732struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating {
5733 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
5734 : AAInstanceInfoFloating(IRP, A) {}
5735};
5736} // namespace
5737
5738/// ----------------------- Variable Capturing ---------------------------------
5740 Attribute::AttrKind ImpliedAttributeKind,
5741 bool IgnoreSubsumingPositions) {
5742 assert(ImpliedAttributeKind == Attribute::Captures &&
5743 "Unexpected attribute kind");
5744 Value &V = IRP.getAssociatedValue();
5745 if (!isa<Constant>(V) && !IRP.isArgumentPosition())
5746 return V.use_empty();
5747
5748 // You cannot "capture" null in the default address space.
5749 //
5750 // FIXME: This should use NullPointerIsDefined to account for the function
5751 // attribute.
5752 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) &&
5753 V.getType()->getPointerAddressSpace() == 0)) {
5754 return true;
5755 }
5756
5758 A.getAttrs(IRP, {Attribute::Captures}, Attrs,
5759 /* IgnoreSubsumingPositions */ true);
5760 for (const Attribute &Attr : Attrs)
5761 if (capturesNothing(Attr.getCaptureInfo()))
5762 return true;
5763
5764 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT)
5765 if (Argument *Arg = IRP.getAssociatedArgument()) {
5767 A.getAttrs(IRPosition::argument(*Arg),
5768 {Attribute::Captures, Attribute::ByVal}, Attrs,
5769 /* IgnoreSubsumingPositions */ true);
5770 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) {
5771 return Attr.getKindAsEnum() == Attribute::ByVal ||
5773 });
5774 if (ArgNoCapture) {
5775 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(
5776 V.getContext(), CaptureInfo::none()));
5777 return true;
5778 }
5779 }
5780
5781 if (const Function *F = IRP.getAssociatedFunction()) {
5782 // Check what state the associated function can actually capture.
5784 determineFunctionCaptureCapabilities(IRP, *F, State);
5785 if (State.isKnown(NO_CAPTURE)) {
5786 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(),
5788 return true;
5789 }
5790 }
5791
5792 return false;
5793}
5794
5795/// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
5796/// depending on the ability of the function associated with \p IRP to capture
5797/// state in memory and through "returning/throwing", respectively.
5799 const Function &F,
5800 BitIntegerState &State) {
5801 // TODO: Once we have memory behavior attributes we should use them here.
5802
5803 // If we know we cannot communicate or write to memory, we do not care about
5804 // ptr2int anymore.
5805 bool ReadOnly = F.onlyReadsMemory();
5806 bool NoThrow = F.doesNotThrow();
5807 bool IsVoidReturn = F.getReturnType()->isVoidTy();
5808 if (ReadOnly && NoThrow && IsVoidReturn) {
5809 State.addKnownBits(NO_CAPTURE);
5810 return;
5811 }
5812
5813 // A function cannot capture state in memory if it only reads memory, it can
5814 // however return/throw state and the state might be influenced by the
5815 // pointer value, e.g., loading from a returned pointer might reveal a bit.
5816 if (ReadOnly)
5817 State.addKnownBits(NOT_CAPTURED_IN_MEM);
5818
5819 // A function cannot communicate state back if it does not through
5820 // exceptions and doesn not return values.
5821 if (NoThrow && IsVoidReturn)
5822 State.addKnownBits(NOT_CAPTURED_IN_RET);
5823
5824 // Check existing "returned" attributes.
5825 int ArgNo = IRP.getCalleeArgNo();
5826 if (!NoThrow || ArgNo < 0 ||
5827 !F.getAttributes().hasAttrSomewhere(Attribute::Returned))
5828 return;
5829
5830 for (unsigned U = 0, E = F.arg_size(); U < E; ++U)
5831 if (F.hasParamAttribute(U, Attribute::Returned)) {
5832 if (U == unsigned(ArgNo))
5833 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
5834 else if (ReadOnly)
5835 State.addKnownBits(NO_CAPTURE);
5836 else
5837 State.addKnownBits(NOT_CAPTURED_IN_RET);
5838 break;
5839 }
5840}
5841
5842namespace {
5843/// A class to hold the state of for no-capture attributes.
5844struct AANoCaptureImpl : public AANoCapture {
5845 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {}
5846
5847 /// See AbstractAttribute::initialize(...).
5848 void initialize(Attributor &A) override {
5849 bool IsKnown;
5850 assert(!AA::hasAssumedIRAttr<Attribute::Captures>(
5851 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown));
5852 (void)IsKnown;
5853 }
5854
5855 /// See AbstractAttribute::updateImpl(...).
5856 ChangeStatus updateImpl(Attributor &A) override;
5857
5858 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
5859 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
5860 SmallVectorImpl<Attribute> &Attrs) const override {
5861 if (!isAssumedNoCaptureMaybeReturned())
5862 return;
5863
5864 if (isArgumentPosition()) {
5865 if (isAssumedNoCapture())
5866 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures));
5867 else if (ManifestInternal)
5868 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
5869 }
5870 }
5871
5872 /// See AbstractState::getAsStr().
5873 const std::string getAsStr(Attributor *A) const override {
5874 if (isKnownNoCapture())
5875 return "known not-captured";
5876 if (isAssumedNoCapture())
5877 return "assumed not-captured";
5878 if (isKnownNoCaptureMaybeReturned())
5879 return "known not-captured-maybe-returned";
5880 if (isAssumedNoCaptureMaybeReturned())
5881 return "assumed not-captured-maybe-returned";
5882 return "assumed-captured";
5883 }
5884
5885 /// Check the use \p U and update \p State accordingly. Return true if we
5886 /// should continue to update the state.
5887 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U,
5888 bool &Follow) {
5889 Instruction *UInst = cast<Instruction>(U.getUser());
5890 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in "
5891 << *UInst << "\n");
5892
5893 // Deal with ptr2int by following uses.
5894 if (isa<PtrToIntInst>(UInst)) {
5895 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
5896 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5897 /* Return */ true);
5898 }
5899
5900 // For stores we already checked if we can follow them, if they make it
5901 // here we give up.
5902 if (isa<StoreInst>(UInst))
5903 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5904 /* Return */ true);
5905
5906 // Explicitly catch return instructions.
5907 if (isa<ReturnInst>(UInst)) {
5908 if (UInst->getFunction() == getAnchorScope())
5909 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5910 /* Return */ true);
5911 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5912 /* Return */ true);
5913 }
5914
5915 // For now we only use special logic for call sites. However, the tracker
5916 // itself knows about a lot of other non-capturing cases already.
5917 auto *CB = dyn_cast<CallBase>(UInst);
5918 if (!CB || !CB->isArgOperand(&U))
5919 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5920 /* Return */ true);
5921
5922 unsigned ArgNo = CB->getArgOperandNo(&U);
5923 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo);
5924 // If we have a abstract no-capture attribute for the argument we can use
5925 // it to justify a non-capture attribute here. This allows recursion!
5926 bool IsKnownNoCapture;
5927 const AANoCapture *ArgNoCaptureAA = nullptr;
5928 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
5929 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
5930 &ArgNoCaptureAA);
5931 if (IsAssumedNoCapture)
5932 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5933 /* Return */ false);
5934 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) {
5935 Follow = true;
5936 return isCapturedIn(State, /* Memory */ false, /* Integer */ false,
5937 /* Return */ false);
5938 }
5939
5940 // Lastly, we could not find a reason no-capture can be assumed so we don't.
5941 return isCapturedIn(State, /* Memory */ true, /* Integer */ true,
5942 /* Return */ true);
5943 }
5944
5945 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and
5946 /// \p CapturedInRet, then return true if we should continue updating the
5947 /// state.
5948 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem,
5949 bool CapturedInInt, bool CapturedInRet) {
5950 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
5951 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
5952 if (CapturedInMem)
5953 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
5954 if (CapturedInInt)
5955 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
5956 if (CapturedInRet)
5957 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
5958 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
5959 }
5960};
5961
5962ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
5963 const IRPosition &IRP = getIRPosition();
5964 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument()
5965 : &IRP.getAssociatedValue();
5966 if (!V)
5967 return indicatePessimisticFixpoint();
5968
5969 const Function *F =
5970 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
5971
5972 // TODO: Is the checkForAllUses below useful for constants?
5973 if (!F)
5974 return indicatePessimisticFixpoint();
5975
5977 const IRPosition &FnPos = IRPosition::function(*F);
5978
5979 // Readonly means we cannot capture through memory.
5980 bool IsKnown;
5981 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) {
5982 T.addKnownBits(NOT_CAPTURED_IN_MEM);
5983 if (IsKnown)
5984 addKnownBits(NOT_CAPTURED_IN_MEM);
5985 }
5986
5987 // Make sure all returned values are different than the underlying value.
5988 // TODO: we could do this in a more sophisticated way inside
5989 // AAReturnedValues, e.g., track all values that escape through returns
5990 // directly somehow.
5991 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) {
5993 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values,
5995 UsedAssumedInformation))
5996 return false;
5997 bool SeenConstant = false;
5998 for (const AA::ValueAndContext &VAC : Values) {
5999 if (isa<Constant>(VAC.getValue())) {
6000 if (SeenConstant)
6001 return false;
6002 SeenConstant = true;
6003 } else if (!isa<Argument>(VAC.getValue()) ||
6004 VAC.getValue() == getAssociatedArgument())
6005 return false;
6006 }
6007 return true;
6008 };
6009
6010 bool IsKnownNoUnwind;
6011 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>(
6012 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) {
6013 bool IsVoidTy = F->getReturnType()->isVoidTy();
6014 bool UsedAssumedInformation = false;
6015 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) {
6016 T.addKnownBits(NOT_CAPTURED_IN_RET);
6017 if (T.isKnown(NOT_CAPTURED_IN_MEM))
6019 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) {
6020 addKnownBits(NOT_CAPTURED_IN_RET);
6021 if (isKnown(NOT_CAPTURED_IN_MEM))
6022 return indicateOptimisticFixpoint();
6023 }
6024 }
6025 }
6026
6027 auto UseCheck = [&](const Use &U, bool &Follow) -> bool {
6028 // TODO(captures): Make this more precise.
6029 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
6030 if (capturesNothing(CI))
6031 return true;
6032 if (CI.isPassthrough()) {
6033 Follow = true;
6034 return true;
6035 }
6036 return checkUse(A, T, U, Follow);
6037 };
6038
6039 if (!A.checkForAllUses(UseCheck, *this, *V))
6040 return indicatePessimisticFixpoint();
6041
6042 AANoCapture::StateType &S = getState();
6043 auto Assumed = S.getAssumed();
6044 S.intersectAssumedBits(T.getAssumed());
6045 if (!isAssumedNoCaptureMaybeReturned())
6046 return indicatePessimisticFixpoint();
6047 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
6049}
6050
6051/// NoCapture attribute for function arguments.
6052struct AANoCaptureArgument final : AANoCaptureImpl {
6053 AANoCaptureArgument(const IRPosition &IRP, Attributor &A)
6054 : AANoCaptureImpl(IRP, A) {}
6055
6056 /// See AbstractAttribute::trackStatistics()
6057 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
6058};
6059
6060/// NoCapture attribute for call site arguments.
6061struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
6062 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A)
6063 : AANoCaptureImpl(IRP, A) {}
6064
6065 /// See AbstractAttribute::updateImpl(...).
6066 ChangeStatus updateImpl(Attributor &A) override {
6067 // TODO: Once we have call site specific value information we can provide
6068 // call site specific liveness information and then it makes
6069 // sense to specialize attributes for call sites arguments instead of
6070 // redirecting requests to the callee argument.
6071 Argument *Arg = getAssociatedArgument();
6072 if (!Arg)
6073 return indicatePessimisticFixpoint();
6074 const IRPosition &ArgPos = IRPosition::argument(*Arg);
6075 bool IsKnownNoCapture;
6076 const AANoCapture *ArgAA = nullptr;
6077 if (AA::hasAssumedIRAttr<Attribute::Captures>(
6078 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false,
6079 &ArgAA))
6080 return ChangeStatus::UNCHANGED;
6081 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned())
6082 return indicatePessimisticFixpoint();
6083 return clampStateAndIndicateChange(getState(), ArgAA->getState());
6084 }
6085
6086 /// See AbstractAttribute::trackStatistics()
6087 void trackStatistics() const override {
6089 };
6090};
6091
6092/// NoCapture attribute for floating values.
6093struct AANoCaptureFloating final : AANoCaptureImpl {
6094 AANoCaptureFloating(const IRPosition &IRP, Attributor &A)
6095 : AANoCaptureImpl(IRP, A) {}
6096
6097 /// See AbstractAttribute::trackStatistics()
6098 void trackStatistics() const override {
6100 }
6101};
6102
6103/// NoCapture attribute for function return value.
6104struct AANoCaptureReturned final : AANoCaptureImpl {
6105 AANoCaptureReturned(const IRPosition &IRP, Attributor &A)
6106 : AANoCaptureImpl(IRP, A) {
6107 llvm_unreachable("NoCapture is not applicable to function returns!");
6108 }
6109
6110 /// See AbstractAttribute::initialize(...).
6111 void initialize(Attributor &A) override {
6112 llvm_unreachable("NoCapture is not applicable to function returns!");
6113 }
6114
6115 /// See AbstractAttribute::updateImpl(...).
6116 ChangeStatus updateImpl(Attributor &A) override {
6117 llvm_unreachable("NoCapture is not applicable to function returns!");
6118 }
6119
6120 /// See AbstractAttribute::trackStatistics()
6121 void trackStatistics() const override {}
6122};
6123
6124/// NoCapture attribute deduction for a call site return value.
6125struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
6126 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A)
6127 : AANoCaptureImpl(IRP, A) {}
6128
6129 /// See AbstractAttribute::initialize(...).
6130 void initialize(Attributor &A) override {
6131 const Function *F = getAnchorScope();
6132 // Check what state the associated function can actually capture.
6133 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
6134 }
6135
6136 /// See AbstractAttribute::trackStatistics()
6137 void trackStatistics() const override {
6139 }
6140};
6141} // namespace
6142
6143/// ------------------ Value Simplify Attribute ----------------------------
6144
6145bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) {
6146 // FIXME: Add a typecast support.
6147 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice(
6148 SimplifiedAssociatedValue, Other, Ty);
6149 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr))
6150 return false;
6151
6152 LLVM_DEBUG({
6153 if (SimplifiedAssociatedValue)
6154 dbgs() << "[ValueSimplify] is assumed to be "
6155 << **SimplifiedAssociatedValue << "\n";
6156 else
6157 dbgs() << "[ValueSimplify] is assumed to be <none>\n";
6158 });
6159 return true;
6160}
6161
6162namespace {
6163struct AAValueSimplifyImpl : AAValueSimplify {
6164 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A)
6165 : AAValueSimplify(IRP, A) {}
6166
6167 /// See AbstractAttribute::initialize(...).
6168 void initialize(Attributor &A) override {
6169 if (getAssociatedValue().getType()->isVoidTy())
6170 indicatePessimisticFixpoint();
6171 if (A.hasSimplificationCallback(getIRPosition()))
6172 indicatePessimisticFixpoint();
6173 }
6174
6175 /// See AbstractAttribute::getAsStr().
6176 const std::string getAsStr(Attributor *A) const override {
6177 LLVM_DEBUG({
6178 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " ";
6179 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue)
6180 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " ";
6181 });
6182 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple")
6183 : "not-simple";
6184 }
6185
6186 /// See AbstractAttribute::trackStatistics()
6187 void trackStatistics() const override {}
6188
6189 /// See AAValueSimplify::getAssumedSimplifiedValue()
6190 std::optional<Value *>
6191 getAssumedSimplifiedValue(Attributor &A) const override {
6192 return SimplifiedAssociatedValue;
6193 }
6194
6195 /// Ensure the return value is \p V with type \p Ty, if not possible return
6196 /// nullptr. If \p Check is true we will only verify such an operation would
6197 /// suceed and return a non-nullptr value if that is the case. No IR is
6198 /// generated or modified.
6199 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI,
6200 bool Check) {
6201 if (auto *TypedV = AA::getWithType(V, Ty))
6202 return TypedV;
6203 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty))
6204 return Check ? &V
6205 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6206 &V, &Ty, "", CtxI->getIterator());
6207 return nullptr;
6208 }
6209
6210 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble.
6211 /// If \p Check is true we will only verify such an operation would suceed and
6212 /// return a non-nullptr value if that is the case. No IR is generated or
6213 /// modified.
6214 static Value *reproduceInst(Attributor &A,
6215 const AbstractAttribute &QueryingAA,
6216 Instruction &I, Type &Ty, Instruction *CtxI,
6217 bool Check, ValueToValueMapTy &VMap) {
6218 assert(CtxI && "Cannot reproduce an instruction without context!");
6219 if (Check && (I.mayReadFromMemory() ||
6220 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr,
6221 /* TLI */ nullptr)))
6222 return nullptr;
6223 for (Value *Op : I.operands()) {
6224 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap);
6225 if (!NewOp) {
6226 assert(Check && "Manifest of new value unexpectedly failed!");
6227 return nullptr;
6228 }
6229 if (!Check)
6230 VMap[Op] = NewOp;
6231 }
6232 if (Check)
6233 return &I;
6234
6235 Instruction *CloneI = I.clone();
6236 // TODO: Try to salvage debug information here.
6237 CloneI->setDebugLoc(DebugLoc());
6238 VMap[&I] = CloneI;
6239 CloneI->insertBefore(CtxI->getIterator());
6240 RemapInstruction(CloneI, VMap);
6241 return CloneI;
6242 }
6243
6244 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble.
6245 /// If \p Check is true we will only verify such an operation would suceed and
6246 /// return a non-nullptr value if that is the case. No IR is generated or
6247 /// modified.
6248 static Value *reproduceValue(Attributor &A,
6249 const AbstractAttribute &QueryingAA, Value &V,
6250 Type &Ty, Instruction *CtxI, bool Check,
6251 ValueToValueMapTy &VMap) {
6252 if (const auto &NewV = VMap.lookup(&V))
6253 return NewV;
6254 bool UsedAssumedInformation = false;
6255 std::optional<Value *> SimpleV = A.getAssumedSimplified(
6256 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6257 if (!SimpleV.has_value())
6258 return PoisonValue::get(&Ty);
6259 Value *EffectiveV = &V;
6260 if (*SimpleV)
6261 EffectiveV = *SimpleV;
6262 if (auto *C = dyn_cast<Constant>(EffectiveV))
6263 return C;
6264 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
6265 A.getInfoCache()))
6266 return ensureType(A, *EffectiveV, Ty, CtxI, Check);
6267 if (auto *I = dyn_cast<Instruction>(EffectiveV))
6268 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap))
6269 return ensureType(A, *NewV, Ty, CtxI, Check);
6270 return nullptr;
6271 }
6272
6273 /// Return a value we can use as replacement for the associated one, or
6274 /// nullptr if we don't have one that makes sense.
6275 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const {
6276 Value *NewV = SimplifiedAssociatedValue
6277 ? *SimplifiedAssociatedValue
6278 : UndefValue::get(getAssociatedType());
6279 if (NewV && NewV != &getAssociatedValue()) {
6280 ValueToValueMapTy VMap;
6281 // First verify we can reprduce the value with the required type at the
6282 // context location before we actually start modifying the IR.
6283 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6284 /* CheckOnly */ true, VMap))
6285 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI,
6286 /* CheckOnly */ false, VMap);
6287 }
6288 return nullptr;
6289 }
6290
6291 /// Helper function for querying AAValueSimplify and updating candidate.
6292 /// \param IRP The value position we are trying to unify with SimplifiedValue
6293 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
6294 const IRPosition &IRP, bool Simplify = true) {
6295 bool UsedAssumedInformation = false;
6296 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue();
6297 if (Simplify)
6298 QueryingValueSimplified = A.getAssumedSimplified(
6299 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural);
6300 return unionAssumed(QueryingValueSimplified);
6301 }
6302
6303 /// Returns a candidate is found or not
6304 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) {
6305 if (!getAssociatedValue().getType()->isIntegerTy())
6306 return false;
6307
6308 // This will also pass the call base context.
6309 const auto *AA =
6310 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE);
6311 if (!AA)
6312 return false;
6313
6314 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
6315
6316 if (!COpt) {
6317 SimplifiedAssociatedValue = std::nullopt;
6318 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6319 return true;
6320 }
6321 if (auto *C = *COpt) {
6322 SimplifiedAssociatedValue = C;
6323 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL);
6324 return true;
6325 }
6326 return false;
6327 }
6328
6329 bool askSimplifiedValueForOtherAAs(Attributor &A) {
6330 if (askSimplifiedValueFor<AAValueConstantRange>(A))
6331 return true;
6332 if (askSimplifiedValueFor<AAPotentialConstantValues>(A))
6333 return true;
6334 return false;
6335 }
6336
6337 /// See AbstractAttribute::manifest(...).
6338 ChangeStatus manifest(Attributor &A) override {
6339 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6340 for (auto &U : getAssociatedValue().uses()) {
6341 // Check if we need to adjust the insertion point to make sure the IR is
6342 // valid.
6343 Instruction *IP = dyn_cast<Instruction>(U.getUser());
6344 if (auto *PHI = dyn_cast_or_null<PHINode>(IP))
6345 IP = PHI->getIncomingBlock(U)->getTerminator();
6346 if (auto *NewV = manifestReplacementValue(A, IP)) {
6347 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue()
6348 << " -> " << *NewV << " :: " << *this << "\n");
6349 if (A.changeUseAfterManifest(U, *NewV))
6350 Changed = ChangeStatus::CHANGED;
6351 }
6352 }
6353
6354 return Changed | AAValueSimplify::manifest(A);
6355 }
6356
6357 /// See AbstractState::indicatePessimisticFixpoint(...).
6358 ChangeStatus indicatePessimisticFixpoint() override {
6359 SimplifiedAssociatedValue = &getAssociatedValue();
6360 return AAValueSimplify::indicatePessimisticFixpoint();
6361 }
6362};
6363
6364struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
6365 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A)
6366 : AAValueSimplifyImpl(IRP, A) {}
6367
6368 void initialize(Attributor &A) override {
6369 AAValueSimplifyImpl::initialize(A);
6370 if (A.hasAttr(getIRPosition(),
6371 {Attribute::InAlloca, Attribute::Preallocated,
6372 Attribute::StructRet, Attribute::Nest, Attribute::ByVal},
6373 /* IgnoreSubsumingPositions */ true))
6374 indicatePessimisticFixpoint();
6375 }
6376
6377 /// See AbstractAttribute::updateImpl(...).
6378 ChangeStatus updateImpl(Attributor &A) override {
6379 // Byval is only replacable if it is readonly otherwise we would write into
6380 // the replaced value and not the copy that byval creates implicitly.
6381 Argument *Arg = getAssociatedArgument();
6382 if (Arg->hasByValAttr()) {
6383 // TODO: We probably need to verify synchronization is not an issue, e.g.,
6384 // there is no race by not copying a constant byval.
6385 bool IsKnown;
6386 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown))
6387 return indicatePessimisticFixpoint();
6388 }
6389
6390 auto Before = SimplifiedAssociatedValue;
6391
6392 auto PredForCallSite = [&](AbstractCallSite ACS) {
6393 const IRPosition &ACSArgPos =
6394 IRPosition::callsite_argument(ACS, getCallSiteArgNo());
6395 // Check if a coresponding argument was found or if it is on not
6396 // associated (which can happen for callback calls).
6397 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
6398 return false;
6399
6400 // Simplify the argument operand explicitly and check if the result is
6401 // valid in the current scope. This avoids refering to simplified values
6402 // in other functions, e.g., we don't want to say a an argument in a
6403 // static function is actually an argument in a different function.
6404 bool UsedAssumedInformation = false;
6405 std::optional<Constant *> SimpleArgOp =
6406 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation);
6407 if (!SimpleArgOp)
6408 return true;
6409 if (!*SimpleArgOp)
6410 return false;
6411 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp))
6412 return false;
6413 return unionAssumed(*SimpleArgOp);
6414 };
6415
6416 // Generate a answer specific to a call site context.
6417 bool Success;
6418 bool UsedAssumedInformation = false;
6419 if (hasCallBaseContext() &&
6420 getCallBaseContext()->getCalledOperand() == Arg->getParent())
6421 Success = PredForCallSite(
6422 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse()));
6423 else
6424 Success = A.checkForAllCallSites(PredForCallSite, *this, true,
6425 UsedAssumedInformation);
6426
6427 if (!Success)
6428 if (!askSimplifiedValueForOtherAAs(A))
6429 return indicatePessimisticFixpoint();
6430
6431 // If a candidate was found in this update, return CHANGED.
6432 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6433 : ChangeStatus ::CHANGED;
6434 }
6435
6436 /// See AbstractAttribute::trackStatistics()
6437 void trackStatistics() const override {
6438 STATS_DECLTRACK_ARG_ATTR(value_simplify)
6439 }
6440};
6441
6442struct AAValueSimplifyReturned : AAValueSimplifyImpl {
6443 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A)
6444 : AAValueSimplifyImpl(IRP, A) {}
6445
6446 /// See AAValueSimplify::getAssumedSimplifiedValue()
6447 std::optional<Value *>
6448 getAssumedSimplifiedValue(Attributor &A) const override {
6449 if (!isValidState())
6450 return nullptr;
6451 return SimplifiedAssociatedValue;
6452 }
6453
6454 /// See AbstractAttribute::updateImpl(...).
6455 ChangeStatus updateImpl(Attributor &A) override {
6456 auto Before = SimplifiedAssociatedValue;
6457
6458 auto ReturnInstCB = [&](Instruction &I) {
6459 auto &RI = cast<ReturnInst>(I);
6460 return checkAndUpdate(
6461 A, *this,
6462 IRPosition::value(*RI.getReturnValue(), getCallBaseContext()));
6463 };
6464
6465 bool UsedAssumedInformation = false;
6466 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
6467 UsedAssumedInformation))
6468 if (!askSimplifiedValueForOtherAAs(A))
6469 return indicatePessimisticFixpoint();
6470
6471 // If a candidate was found in this update, return CHANGED.
6472 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6473 : ChangeStatus ::CHANGED;
6474 }
6475
6476 ChangeStatus manifest(Attributor &A) override {
6477 // We queried AAValueSimplify for the returned values so they will be
6478 // replaced if a simplified form was found. Nothing to do here.
6479 return ChangeStatus::UNCHANGED;
6480 }
6481
6482 /// See AbstractAttribute::trackStatistics()
6483 void trackStatistics() const override {
6484 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
6485 }
6486};
6487
6488struct AAValueSimplifyFloating : AAValueSimplifyImpl {
6489 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A)
6490 : AAValueSimplifyImpl(IRP, A) {}
6491
6492 /// See AbstractAttribute::initialize(...).
6493 void initialize(Attributor &A) override {
6494 AAValueSimplifyImpl::initialize(A);
6495 Value &V = getAnchorValue();
6496
6497 // TODO: add other stuffs
6498 if (isa<Constant>(V))
6499 indicatePessimisticFixpoint();
6500 }
6501
6502 /// See AbstractAttribute::updateImpl(...).
6503 ChangeStatus updateImpl(Attributor &A) override {
6504 auto Before = SimplifiedAssociatedValue;
6505 if (!askSimplifiedValueForOtherAAs(A))
6506 return indicatePessimisticFixpoint();
6507
6508 // If a candidate was found in this update, return CHANGED.
6509 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED
6510 : ChangeStatus ::CHANGED;
6511 }
6512
6513 /// See AbstractAttribute::trackStatistics()
6514 void trackStatistics() const override {
6515 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
6516 }
6517};
6518
6519struct AAValueSimplifyFunction : AAValueSimplifyImpl {
6520 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A)
6521 : AAValueSimplifyImpl(IRP, A) {}
6522
6523 /// See AbstractAttribute::initialize(...).
6524 void initialize(Attributor &A) override {
6525 SimplifiedAssociatedValue = nullptr;
6526 indicateOptimisticFixpoint();
6527 }
6528 /// See AbstractAttribute::initialize(...).
6529 ChangeStatus updateImpl(Attributor &A) override {
6531 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
6532 }
6533 /// See AbstractAttribute::trackStatistics()
6534 void trackStatistics() const override {
6535 STATS_DECLTRACK_FN_ATTR(value_simplify)
6536 }
6537};
6538
6539struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
6540 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A)
6541 : AAValueSimplifyFunction(IRP, A) {}
6542 /// See AbstractAttribute::trackStatistics()
6543 void trackStatistics() const override {
6544 STATS_DECLTRACK_CS_ATTR(value_simplify)
6545 }
6546};
6547
6548struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl {
6549 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A)
6550 : AAValueSimplifyImpl(IRP, A) {}
6551
6552 void initialize(Attributor &A) override {
6553 AAValueSimplifyImpl::initialize(A);
6554 Function *Fn = getAssociatedFunction();
6555 assert(Fn && "Did expect an associted function");
6556 for (Argument &Arg : Fn->args()) {
6557 if (Arg.hasReturnedAttr()) {
6558 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()),
6559 Arg.getArgNo());
6561 checkAndUpdate(A, *this, IRP))
6562 indicateOptimisticFixpoint();
6563 else
6564 indicatePessimisticFixpoint();
6565 return;
6566 }
6567 }
6568 }
6569
6570 /// See AbstractAttribute::updateImpl(...).
6571 ChangeStatus updateImpl(Attributor &A) override {
6572 return indicatePessimisticFixpoint();
6573 }
6574
6575 void trackStatistics() const override {
6576 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
6577 }
6578};
6579
6580struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
6581 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A)
6582 : AAValueSimplifyFloating(IRP, A) {}
6583
6584 /// See AbstractAttribute::manifest(...).
6585 ChangeStatus manifest(Attributor &A) override {
6586 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6587 // TODO: We should avoid simplification duplication to begin with.
6588 auto *FloatAA = A.lookupAAFor<AAValueSimplify>(
6589 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE);
6590 if (FloatAA && FloatAA->getState().isValidState())
6591 return Changed;
6592
6593 if (auto *NewV = manifestReplacementValue(A, getCtxI())) {
6594 Use &U = cast<CallBase>(&getAnchorValue())
6595 ->getArgOperandUse(getCallSiteArgNo());
6596 if (A.changeUseAfterManifest(U, *NewV))
6597 Changed = ChangeStatus::CHANGED;
6598 }
6599
6600 return Changed | AAValueSimplify::manifest(A);
6601 }
6602
6603 void trackStatistics() const override {
6604 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
6605 }
6606};
6607} // namespace
6608
6609/// ----------------------- Heap-To-Stack Conversion ---------------------------
6610namespace {
6611struct AAHeapToStackFunction final : public AAHeapToStack {
6612
6613 struct AllocationInfo {
6614 /// The call that allocates the memory.
6615 CallBase *const CB;
6616
6617 /// The library function id for the allocation.
6618 LibFunc LibraryFunctionId = NotLibFunc;
6619
6620 /// The status wrt. a rewrite.
6621 enum {
6622 STACK_DUE_TO_USE,
6623 STACK_DUE_TO_FREE,
6624 INVALID,
6625 } Status = STACK_DUE_TO_USE;
6626
6627 /// Flag to indicate if we encountered a use that might free this allocation
6628 /// but which is not in the deallocation infos.
6629 bool HasPotentiallyFreeingUnknownUses = false;
6630
6631 /// Flag to indicate that we should place the new alloca in the function
6632 /// entry block rather than where the call site (CB) is.
6633 bool MoveAllocaIntoEntry = true;
6634
6635 /// The set of free calls that use this allocation.
6636 SmallSetVector<CallBase *, 1> PotentialFreeCalls{};
6637 };
6638
6639 struct DeallocationInfo {
6640 /// The call that deallocates the memory.
6641 CallBase *const CB;
6642 /// The value freed by the call.
6643 Value *FreedOp;
6644
6645 /// Flag to indicate if we don't know all objects this deallocation might
6646 /// free.
6647 bool MightFreeUnknownObjects = false;
6648
6649 /// The set of allocation calls that are potentially freed.
6650 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{};
6651 };
6652
6653 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A)
6654 : AAHeapToStack(IRP, A) {}
6655
6656 ~AAHeapToStackFunction() {
6657 // Ensure we call the destructor so we release any memory allocated in the
6658 // sets.
6659 for (auto &It : AllocationInfos)
6660 It.second->~AllocationInfo();
6661 for (auto &It : DeallocationInfos)
6662 It.second->~DeallocationInfo();
6663 }
6664
6665 void initialize(Attributor &A) override {
6666 AAHeapToStack::initialize(A);
6667
6668 const Function *F = getAnchorScope();
6669 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6670
6671 auto AllocationIdentifierCB = [&](Instruction &I) {
6672 CallBase *CB = dyn_cast<CallBase>(&I);
6673 if (!CB)
6674 return true;
6675 if (Value *FreedOp = getFreedOperand(CB, TLI)) {
6676 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp};
6677 return true;
6678 }
6679 // To do heap to stack, we need to know that the allocation itself is
6680 // removable once uses are rewritten, and that we can initialize the
6681 // alloca to the same pattern as the original allocation result.
6682 if (isRemovableAlloc(CB, TLI)) {
6683 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext());
6684 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) {
6685 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB};
6686 AllocationInfos[CB] = AI;
6687 if (TLI)
6688 TLI->getLibFunc(*CB, AI->LibraryFunctionId);
6689 }
6690 }
6691 return true;
6692 };
6693
6694 bool UsedAssumedInformation = false;
6695 bool Success = A.checkForAllCallLikeInstructions(
6696 AllocationIdentifierCB, *this, UsedAssumedInformation,
6697 /* CheckBBLivenessOnly */ false,
6698 /* CheckPotentiallyDead */ true);
6699 (void)Success;
6700 assert(Success && "Did not expect the call base visit callback to fail!");
6701
6703 [](const IRPosition &, const AbstractAttribute *,
6704 bool &) -> std::optional<Value *> { return nullptr; };
6705 for (const auto &It : AllocationInfos)
6706 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6707 SCB);
6708 for (const auto &It : DeallocationInfos)
6709 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first),
6710 SCB);
6711 }
6712
6713 const std::string getAsStr(Attributor *A) const override {
6714 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0;
6715 for (const auto &It : AllocationInfos) {
6716 if (It.second->Status == AllocationInfo::INVALID)
6717 ++NumInvalidMallocs;
6718 else
6719 ++NumH2SMallocs;
6720 }
6721 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" +
6722 std::to_string(NumInvalidMallocs);
6723 }
6724
6725 /// See AbstractAttribute::trackStatistics().
6726 void trackStatistics() const override {
6727 STATS_DECL(
6728 MallocCalls, Function,
6729 "Number of malloc/calloc/aligned_alloc calls converted to allocas");
6730 for (const auto &It : AllocationInfos)
6731 if (It.second->Status != AllocationInfo::INVALID)
6732 ++BUILD_STAT_NAME(MallocCalls, Function);
6733 }
6734
6735 bool isAssumedHeapToStack(const CallBase &CB) const override {
6736 if (isValidState())
6737 if (AllocationInfo *AI =
6738 AllocationInfos.lookup(const_cast<CallBase *>(&CB)))
6739 return AI->Status != AllocationInfo::INVALID;
6740 return false;
6741 }
6742
6743 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override {
6744 if (!isValidState())
6745 return false;
6746
6747 for (const auto &It : AllocationInfos) {
6748 AllocationInfo &AI = *It.second;
6749 if (AI.Status == AllocationInfo::INVALID)
6750 continue;
6751
6752 if (AI.PotentialFreeCalls.count(&CB))
6753 return true;
6754 }
6755
6756 return false;
6757 }
6758
6759 ChangeStatus manifest(Attributor &A) override {
6760 assert(getState().isValidState() &&
6761 "Attempted to manifest an invalid state!");
6762
6763 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
6764 Function *F = getAnchorScope();
6765 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6766
6767 for (auto &It : AllocationInfos) {
6768 AllocationInfo &AI = *It.second;
6769 if (AI.Status == AllocationInfo::INVALID)
6770 continue;
6771
6772 for (CallBase *FreeCall : AI.PotentialFreeCalls) {
6773 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
6774 A.deleteAfterManifest(*FreeCall);
6775 HasChanged = ChangeStatus::CHANGED;
6776 }
6777
6778 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB
6779 << "\n");
6780
6781 auto Remark = [&](OptimizationRemark OR) {
6782 LibFunc IsAllocShared;
6783 if (TLI->getLibFunc(*AI.CB, IsAllocShared))
6784 if (IsAllocShared == LibFunc___kmpc_alloc_shared)
6785 return OR << "Moving globalized variable to the stack.";
6786 return OR << "Moving memory allocation from the heap to the stack.";
6787 };
6788 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
6789 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark);
6790 else
6791 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark);
6792
6793 const DataLayout &DL = A.getInfoCache().getDL();
6794 Value *Size;
6795 std::optional<APInt> SizeAPI = getSize(A, *this, AI);
6796 if (SizeAPI) {
6797 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI);
6798 } else {
6799 LLVMContext &Ctx = AI.CB->getContext();
6800 ObjectSizeOpts Opts;
6801 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts);
6802 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB);
6803 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() &&
6804 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero());
6805 Size = SizeOffsetPair.Size;
6806 }
6807
6808 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry
6809 ? F->getEntryBlock().begin()
6810 : AI.CB->getIterator();
6811
6812 Align Alignment(1);
6813 if (MaybeAlign RetAlign = AI.CB->getRetAlign())
6814 Alignment = std::max(Alignment, *RetAlign);
6815 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
6816 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align);
6817 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 &&
6818 "Expected an alignment during manifest!");
6819 Alignment =
6820 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue()));
6821 }
6822
6823 // TODO: Hoist the alloca towards the function entry.
6824 unsigned AS = DL.getAllocaAddrSpace();
6825 Instruction *Alloca =
6826 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment,
6827 AI.CB->getName() + ".h2s", IP);
6828
6829 if (Alloca->getType() != AI.CB->getType())
6830 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
6831 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator());
6832
6833 auto *I8Ty = Type::getInt8Ty(F->getContext());
6834 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty);
6835 assert(InitVal &&
6836 "Must be able to materialize initial memory state of allocation");
6837
6838 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca);
6839
6840 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) {
6841 auto *NBB = II->getNormalDest();
6842 BranchInst::Create(NBB, AI.CB->getParent());
6843 A.deleteAfterManifest(*AI.CB);
6844 } else {
6845 A.deleteAfterManifest(*AI.CB);
6846 }
6847
6848 // Initialize the alloca with the same value as used by the allocation
6849 // function. We can skip undef as the initial value of an alloc is
6850 // undef, and the memset would simply end up being DSEd.
6851 if (!isa<UndefValue>(InitVal)) {
6852 IRBuilder<> Builder(Alloca->getNextNode());
6853 // TODO: Use alignment above if align!=1
6854 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt);
6855 }
6856 HasChanged = ChangeStatus::CHANGED;
6857 }
6858
6859 return HasChanged;
6860 }
6861
6862 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA,
6863 Value &V) {
6864 bool UsedAssumedInformation = false;
6865 std::optional<Constant *> SimpleV =
6866 A.getAssumedConstant(V, AA, UsedAssumedInformation);
6867 if (!SimpleV)
6868 return APInt(64, 0);
6869 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV))
6870 return CI->getValue();
6871 return std::nullopt;
6872 }
6873
6874 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA,
6875 AllocationInfo &AI) {
6876 auto Mapper = [&](const Value *V) -> const Value * {
6877 bool UsedAssumedInformation = false;
6878 if (std::optional<Constant *> SimpleV =
6879 A.getAssumedConstant(*V, AA, UsedAssumedInformation))
6880 if (*SimpleV)
6881 return *SimpleV;
6882 return V;
6883 };
6884
6885 const Function *F = getAnchorScope();
6886 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6887 return getAllocSize(AI.CB, TLI, Mapper);
6888 }
6889
6890 /// Collection of all malloc-like calls in a function with associated
6891 /// information.
6893
6894 /// Collection of all free-like calls in a function with associated
6895 /// information.
6897
6898 ChangeStatus updateImpl(Attributor &A) override;
6899};
6900
6901ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) {
6903 const Function *F = getAnchorScope();
6904 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
6905
6906 const auto *LivenessAA =
6907 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE);
6908
6910 A.getInfoCache().getMustBeExecutedContextExplorer();
6911
6912 bool StackIsAccessibleByOtherThreads =
6913 A.getInfoCache().stackIsAccessibleByOtherThreads();
6914
6915 LoopInfo *LI =
6916 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F);
6917 std::optional<bool> MayContainIrreducibleControl;
6918 auto IsInLoop = [&](BasicBlock &BB) {
6919 if (&F->getEntryBlock() == &BB)
6920 return false;
6921 if (!MayContainIrreducibleControl.has_value())
6922 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI);
6923 if (*MayContainIrreducibleControl)
6924 return true;
6925 if (!LI)
6926 return true;
6927 return LI->getLoopFor(&BB) != nullptr;
6928 };
6929
6930 // Flag to ensure we update our deallocation information at most once per
6931 // updateImpl call and only if we use the free check reasoning.
6932 bool HasUpdatedFrees = false;
6933
6934 auto UpdateFrees = [&]() {
6935 HasUpdatedFrees = true;
6936
6937 for (auto &It : DeallocationInfos) {
6938 DeallocationInfo &DI = *It.second;
6939 // For now we cannot use deallocations that have unknown inputs, skip
6940 // them.
6941 if (DI.MightFreeUnknownObjects)
6942 continue;
6943
6944 // No need to analyze dead calls, ignore them instead.
6945 bool UsedAssumedInformation = false;
6946 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation,
6947 /* CheckBBLivenessOnly */ true))
6948 continue;
6949
6950 // Use the non-optimistic version to get the freed object.
6951 Value *Obj = getUnderlyingObject(DI.FreedOp);
6952 if (!Obj) {
6953 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n");
6954 DI.MightFreeUnknownObjects = true;
6955 continue;
6956 }
6957
6958 // Free of null and undef can be ignored as no-ops (or UB in the latter
6959 // case).
6960 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj))
6961 continue;
6962
6963 CallBase *ObjCB = dyn_cast<CallBase>(Obj);
6964 if (!ObjCB) {
6965 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj
6966 << "\n");
6967 DI.MightFreeUnknownObjects = true;
6968 continue;
6969 }
6970
6971 AllocationInfo *AI = AllocationInfos.lookup(ObjCB);
6972 if (!AI) {
6973 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj
6974 << "\n");
6975 DI.MightFreeUnknownObjects = true;
6976 continue;
6977 }
6978
6979 DI.PotentialAllocationCalls.insert(ObjCB);
6980 }
6981 };
6982
6983 auto FreeCheck = [&](AllocationInfo &AI) {
6984 // If the stack is not accessible by other threads, the "must-free" logic
6985 // doesn't apply as the pointer could be shared and needs to be places in
6986 // "shareable" memory.
6987 if (!StackIsAccessibleByOtherThreads) {
6988 bool IsKnownNoSycn;
6989 if (!AA::hasAssumedIRAttr<Attribute::NoSync>(
6990 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) {
6991 LLVM_DEBUG(
6992 dbgs() << "[H2S] found an escaping use, stack is not accessible by "
6993 "other threads and function is not nosync:\n");
6994 return false;
6995 }
6996 }
6997 if (!HasUpdatedFrees)
6998 UpdateFrees();
6999
7000 // TODO: Allow multi exit functions that have different free calls.
7001 if (AI.PotentialFreeCalls.size() != 1) {
7002 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but "
7003 << AI.PotentialFreeCalls.size() << "\n");
7004 return false;
7005 }
7006 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin();
7007 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree);
7008 if (!DI) {
7009 LLVM_DEBUG(
7010 dbgs() << "[H2S] unique free call was not known as deallocation call "
7011 << *UniqueFree << "\n");
7012 return false;
7013 }
7014 if (DI->MightFreeUnknownObjects) {
7015 LLVM_DEBUG(
7016 dbgs() << "[H2S] unique free call might free unknown allocations\n");
7017 return false;
7018 }
7019 if (DI->PotentialAllocationCalls.empty())
7020 return true;
7021 if (DI->PotentialAllocationCalls.size() > 1) {
7022 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free "
7023 << DI->PotentialAllocationCalls.size()
7024 << " different allocations\n");
7025 return false;
7026 }
7027 if (*DI->PotentialAllocationCalls.begin() != AI.CB) {
7028 LLVM_DEBUG(
7029 dbgs()
7030 << "[H2S] unique free call not known to free this allocation but "
7031 << **DI->PotentialAllocationCalls.begin() << "\n");
7032 return false;
7033 }
7034
7035 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched.
7036 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) {
7037 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode();
7038 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) {
7039 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed "
7040 "with the allocation "
7041 << *UniqueFree << "\n");
7042 return false;
7043 }
7044 }
7045 return true;
7046 };
7047
7048 auto UsesCheck = [&](AllocationInfo &AI) {
7049 bool ValidUsesOnly = true;
7050
7051 auto Pred = [&](const Use &U, bool &Follow) -> bool {
7052 Instruction *UserI = cast<Instruction>(U.getUser());
7053 if (isa<LoadInst>(UserI))
7054 return true;
7055 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
7056 if (SI->getValueOperand() == U.get()) {
7058 << "[H2S] escaping store to memory: " << *UserI << "\n");
7059 ValidUsesOnly = false;
7060 } else {
7061 // A store into the malloc'ed memory is fine.
7062 }
7063 return true;
7064 }
7065 if (auto *CB = dyn_cast<CallBase>(UserI)) {
7066 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
7067 return true;
7068 if (DeallocationInfos.count(CB)) {
7069 AI.PotentialFreeCalls.insert(CB);
7070 return true;
7071 }
7072
7073 unsigned ArgNo = CB->getArgOperandNo(&U);
7074 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo);
7075
7076 bool IsKnownNoCapture;
7077 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7078 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture);
7079
7080 // If a call site argument use is nofree, we are fine.
7081 bool IsKnownNoFree;
7082 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>(
7083 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree);
7084
7085 if (!IsAssumedNoCapture ||
7086 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7087 !IsAssumedNoFree)) {
7088 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree;
7089
7090 // Emit a missed remark if this is missed OpenMP globalization.
7091 auto Remark = [&](OptimizationRemarkMissed ORM) {
7092 return ORM
7093 << "Could not move globalized variable to the stack. "
7094 "Variable is potentially captured in call. Mark "
7095 "parameter as `__attribute__((noescape))` to override.";
7096 };
7097
7098 if (ValidUsesOnly &&
7099 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared)
7100 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark);
7101
7102 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
7103 ValidUsesOnly = false;
7104 }
7105 return true;
7106 }
7107
7108 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
7109 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
7110 Follow = true;
7111 return true;
7112 }
7113 // Unknown user for which we can not track uses further (in a way that
7114 // makes sense).
7115 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
7116 ValidUsesOnly = false;
7117 return true;
7118 };
7119 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false,
7120 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true,
7121 [&](const Use &OldU, const Use &NewU) {
7122 auto *SI = dyn_cast<StoreInst>(OldU.getUser());
7123 return !SI || StackIsAccessibleByOtherThreads ||
7124 AA::isAssumedThreadLocalObject(
7125 A, *SI->getPointerOperand(), *this);
7126 }))
7127 return false;
7128 return ValidUsesOnly;
7129 };
7130
7131 // The actual update starts here. We look at all allocations and depending on
7132 // their status perform the appropriate check(s).
7133 for (auto &It : AllocationInfos) {
7134 AllocationInfo &AI = *It.second;
7135 if (AI.Status == AllocationInfo::INVALID)
7136 continue;
7137
7138 if (Value *Align = getAllocAlignment(AI.CB, TLI)) {
7139 std::optional<APInt> APAlign = getAPInt(A, *this, *Align);
7140 if (!APAlign) {
7141 // Can't generate an alloca which respects the required alignment
7142 // on the allocation.
7143 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB
7144 << "\n");
7145 AI.Status = AllocationInfo::INVALID;
7146 Changed = ChangeStatus::CHANGED;
7147 continue;
7148 }
7149 if (APAlign->ugt(llvm::Value::MaximumAlignment) ||
7150 !APAlign->isPowerOf2()) {
7151 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign
7152 << "\n");
7153 AI.Status = AllocationInfo::INVALID;
7154 Changed = ChangeStatus::CHANGED;
7155 continue;
7156 }
7157 }
7158
7159 std::optional<APInt> Size = getSize(A, *this, AI);
7160 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared &&
7161 MaxHeapToStackSize != -1) {
7162 if (!Size || Size->ugt(MaxHeapToStackSize)) {
7163 LLVM_DEBUG({
7164 if (!Size)
7165 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n";
7166 else
7167 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. "
7168 << MaxHeapToStackSize << "\n";
7169 });
7170
7171 AI.Status = AllocationInfo::INVALID;
7172 Changed = ChangeStatus::CHANGED;
7173 continue;
7174 }
7175 }
7176
7177 switch (AI.Status) {
7178 case AllocationInfo::STACK_DUE_TO_USE:
7179 if (UsesCheck(AI))
7180 break;
7181 AI.Status = AllocationInfo::STACK_DUE_TO_FREE;
7182 [[fallthrough]];
7183 case AllocationInfo::STACK_DUE_TO_FREE:
7184 if (FreeCheck(AI))
7185 break;
7186 AI.Status = AllocationInfo::INVALID;
7187 Changed = ChangeStatus::CHANGED;
7188 break;
7189 case AllocationInfo::INVALID:
7190 llvm_unreachable("Invalid allocations should never reach this point!");
7191 };
7192
7193 // Check if we still think we can move it into the entry block. If the
7194 // alloca comes from a converted __kmpc_alloc_shared then we can usually
7195 // ignore the potential compilations associated with loops.
7196 bool IsGlobalizedLocal =
7197 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared;
7198 if (AI.MoveAllocaIntoEntry &&
7199 (!Size.has_value() ||
7200 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent()))))
7201 AI.MoveAllocaIntoEntry = false;
7202 }
7203
7204 return Changed;
7205}
7206} // namespace
7207
7208/// ----------------------- Privatizable Pointers ------------------------------
7209namespace {
7210struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
7211 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A)
7212 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {}
7213
7214 ChangeStatus indicatePessimisticFixpoint() override {
7215 AAPrivatizablePtr::indicatePessimisticFixpoint();
7216 PrivatizableType = nullptr;
7217 return ChangeStatus::CHANGED;
7218 }
7219
7220 /// Identify the type we can chose for a private copy of the underlying
7221 /// argument. std::nullopt means it is not clear yet, nullptr means there is
7222 /// none.
7223 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
7224
7225 /// Return a privatizable type that encloses both T0 and T1.
7226 /// TODO: This is merely a stub for now as we should manage a mapping as well.
7227 std::optional<Type *> combineTypes(std::optional<Type *> T0,
7228 std::optional<Type *> T1) {
7229 if (!T0)
7230 return T1;
7231 if (!T1)
7232 return T0;
7233 if (T0 == T1)
7234 return T0;
7235 return nullptr;
7236 }
7237
7238 std::optional<Type *> getPrivatizableType() const override {
7239 return PrivatizableType;
7240 }
7241
7242 const std::string getAsStr(Attributor *A) const override {
7243 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
7244 }
7245
7246protected:
7247 std::optional<Type *> PrivatizableType;
7248};
7249
7250// TODO: Do this for call site arguments (probably also other values) as well.
7251
7252struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
7253 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A)
7254 : AAPrivatizablePtrImpl(IRP, A) {}
7255
7256 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7257 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7258 // If this is a byval argument and we know all the call sites (so we can
7259 // rewrite them), there is no need to check them explicitly.
7260 bool UsedAssumedInformation = false;
7262 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs,
7263 /* IgnoreSubsumingPositions */ true);
7264 if (!Attrs.empty() &&
7265 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
7266 true, UsedAssumedInformation))
7267 return Attrs[0].getValueAsType();
7268
7269 std::optional<Type *> Ty;
7270 unsigned ArgNo = getIRPosition().getCallSiteArgNo();
7271
7272 // Make sure the associated call site argument has the same type at all call
7273 // sites and it is an allocation we know is safe to privatize, for now that
7274 // means we only allow alloca instructions.
7275 // TODO: We can additionally analyze the accesses in the callee to create
7276 // the type from that information instead. That is a little more
7277 // involved and will be done in a follow up patch.
7278 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7279 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
7280 // Check if a coresponding argument was found or if it is one not
7281 // associated (which can happen for callback calls).
7282 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
7283 return false;
7284
7285 // Check that all call sites agree on a type.
7286 auto *PrivCSArgAA =
7287 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED);
7288 if (!PrivCSArgAA)
7289 return false;
7290 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType();
7291
7292 LLVM_DEBUG({
7293 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
7294 if (CSTy && *CSTy)
7295 (*CSTy)->print(dbgs());
7296 else if (CSTy)
7297 dbgs() << "<nullptr>";
7298 else
7299 dbgs() << "<none>";
7300 });
7301
7302 Ty = combineTypes(Ty, CSTy);
7303
7304 LLVM_DEBUG({
7305 dbgs() << " : New Type: ";
7306 if (Ty && *Ty)
7307 (*Ty)->print(dbgs());
7308 else if (Ty)
7309 dbgs() << "<nullptr>";
7310 else
7311 dbgs() << "<none>";
7312 dbgs() << "\n";
7313 });
7314
7315 return !Ty || *Ty;
7316 };
7317
7318 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7319 UsedAssumedInformation))
7320 return nullptr;
7321 return Ty;
7322 }
7323
7324 /// See AbstractAttribute::updateImpl(...).
7325 ChangeStatus updateImpl(Attributor &A) override {
7326 PrivatizableType = identifyPrivatizableType(A);
7327 if (!PrivatizableType)
7328 return ChangeStatus::UNCHANGED;
7329 if (!*PrivatizableType)
7330 return indicatePessimisticFixpoint();
7331
7332 // The dependence is optional so we don't give up once we give up on the
7333 // alignment.
7334 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()),
7335 DepClassTy::OPTIONAL);
7336
7337 // Avoid arguments with padding for now.
7338 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) &&
7339 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) {
7340 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
7341 return indicatePessimisticFixpoint();
7342 }
7343
7344 // Collect the types that will replace the privatizable type in the function
7345 // signature.
7346 SmallVector<Type *, 16> ReplacementTypes;
7347 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7348
7349 // Verify callee and caller agree on how the promoted argument would be
7350 // passed.
7351 Function &Fn = *getIRPosition().getAnchorScope();
7352 const auto *TTI =
7353 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
7354 if (!TTI) {
7355 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function "
7356 << Fn.getName() << "\n");
7357 return indicatePessimisticFixpoint();
7358 }
7359
7360 auto CallSiteCheck = [&](AbstractCallSite ACS) {
7361 CallBase *CB = ACS.getInstruction();
7362 return TTI->areTypesABICompatible(
7363 CB->getCaller(),
7364 dyn_cast_if_present<Function>(CB->getCalledOperand()),
7365 ReplacementTypes);
7366 };
7367 bool UsedAssumedInformation = false;
7368 if (!A.checkForAllCallSites(CallSiteCheck, *this, true,
7369 UsedAssumedInformation)) {
7370 LLVM_DEBUG(
7371 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
7372 << Fn.getName() << "\n");
7373 return indicatePessimisticFixpoint();
7374 }
7375
7376 // Register a rewrite of the argument.
7377 Argument *Arg = getAssociatedArgument();
7378 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
7379 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
7380 return indicatePessimisticFixpoint();
7381 }
7382
7383 unsigned ArgNo = Arg->getArgNo();
7384
7385 // Helper to check if for the given call site the associated argument is
7386 // passed to a callback where the privatization would be different.
7387 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) {
7388 SmallVector<const Use *, 4> CallbackUses;
7389 AbstractCallSite::getCallbackUses(CB, CallbackUses);
7390 for (const Use *U : CallbackUses) {
7391 AbstractCallSite CBACS(U);
7392 assert(CBACS && CBACS.isCallbackCall());
7393 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
7394 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
7395
7396 LLVM_DEBUG({
7397 dbgs()
7398 << "[AAPrivatizablePtr] Argument " << *Arg
7399 << "check if can be privatized in the context of its parent ("
7400 << Arg->getParent()->getName()
7401 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7402 "callback ("
7403 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7404 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
7405 << CBACS.getCallArgOperand(CBArg) << " vs "
7406 << CB.getArgOperand(ArgNo) << "\n"
7407 << "[AAPrivatizablePtr] " << CBArg << " : "
7408 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
7409 });
7410
7411 if (CBArgNo != int(ArgNo))
7412 continue;
7413 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7414 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED);
7415 if (CBArgPrivAA && CBArgPrivAA->isValidState()) {
7416 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType();
7417 if (!CBArgPrivTy)
7418 continue;
7419 if (*CBArgPrivTy == PrivatizableType)
7420 continue;
7421 }
7422
7423 LLVM_DEBUG({
7424 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7425 << " cannot be privatized in the context of its parent ("
7426 << Arg->getParent()->getName()
7427 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7428 "callback ("
7429 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
7430 << ").\n[AAPrivatizablePtr] for which the argument "
7431 "privatization is not compatible.\n";
7432 });
7433 return false;
7434 }
7435 }
7436 return true;
7437 };
7438
7439 // Helper to check if for the given call site the associated argument is
7440 // passed to a direct call where the privatization would be different.
7441 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
7442 CallBase *DC = cast<CallBase>(ACS.getInstruction());
7443 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
7444 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() &&
7445 "Expected a direct call operand for callback call operand");
7446
7447 Function *DCCallee =
7448 dyn_cast_if_present<Function>(DC->getCalledOperand());
7449 LLVM_DEBUG({
7450 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7451 << " check if be privatized in the context of its parent ("
7452 << Arg->getParent()->getName()
7453 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7454 "direct call of ("
7455 << DCArgNo << "@" << DCCallee->getName() << ").\n";
7456 });
7457
7458 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
7459 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
7460 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)),
7461 DepClassTy::REQUIRED);
7462 if (DCArgPrivAA && DCArgPrivAA->isValidState()) {
7463 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType();
7464 if (!DCArgPrivTy)
7465 return true;
7466 if (*DCArgPrivTy == PrivatizableType)
7467 return true;
7468 }
7469 }
7470
7471 LLVM_DEBUG({
7472 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
7473 << " cannot be privatized in the context of its parent ("
7474 << Arg->getParent()->getName()
7475 << ")\n[AAPrivatizablePtr] because it is an argument in a "
7476 "direct call of ("
7478 << ").\n[AAPrivatizablePtr] for which the argument "
7479 "privatization is not compatible.\n";
7480 });
7481 return false;
7482 };
7483
7484 // Helper to check if the associated argument is used at the given abstract
7485 // call site in a way that is incompatible with the privatization assumed
7486 // here.
7487 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
7488 if (ACS.isDirectCall())
7489 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction());
7490 if (ACS.isCallbackCall())
7491 return IsCompatiblePrivArgOfDirectCS(ACS);
7492 return false;
7493 };
7494
7495 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
7496 UsedAssumedInformation))
7497 return indicatePessimisticFixpoint();
7498
7499 return ChangeStatus::UNCHANGED;
7500 }
7501
7502 /// Given a type to private \p PrivType, collect the constituates (which are
7503 /// used) in \p ReplacementTypes.
7504 static void
7505 identifyReplacementTypes(Type *PrivType,
7506 SmallVectorImpl<Type *> &ReplacementTypes) {
7507 // TODO: For now we expand the privatization type to the fullest which can
7508 // lead to dead arguments that need to be removed later.
7509 assert(PrivType && "Expected privatizable type!");
7510
7511 // Traverse the type, extract constituate types on the outermost level.
7512 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7513 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
7514 ReplacementTypes.push_back(PrivStructType->getElementType(u));
7515 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7516 ReplacementTypes.append(PrivArrayType->getNumElements(),
7517 PrivArrayType->getElementType());
7518 } else {
7519 ReplacementTypes.push_back(PrivType);
7520 }
7521 }
7522
7523 /// Initialize \p Base according to the type \p PrivType at position \p IP.
7524 /// The values needed are taken from the arguments of \p F starting at
7525 /// position \p ArgNo.
7526 static void createInitialization(Type *PrivType, Value &Base, Function &F,
7527 unsigned ArgNo, BasicBlock::iterator IP) {
7528 assert(PrivType && "Expected privatizable type!");
7529
7530 IRBuilder<NoFolder> IRB(IP->getParent(), IP);
7531 const DataLayout &DL = F.getDataLayout();
7532
7533 // Traverse the type, build GEPs and stores.
7534 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7535 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7536 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7537 Value *Ptr =
7538 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB);
7539 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7540 }
7541 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7542 Type *PointeeTy = PrivArrayType->getElementType();
7543 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7544 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7545 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB);
7546 new StoreInst(F.getArg(ArgNo + u), Ptr, IP);
7547 }
7548 } else {
7549 new StoreInst(F.getArg(ArgNo), &Base, IP);
7550 }
7551 }
7552
7553 /// Extract values from \p Base according to the type \p PrivType at the
7554 /// call position \p ACS. The values are appended to \p ReplacementValues.
7555 void createReplacementValues(Align Alignment, Type *PrivType,
7557 SmallVectorImpl<Value *> &ReplacementValues) {
7558 assert(Base && "Expected base value!");
7559 assert(PrivType && "Expected privatizable type!");
7560 Instruction *IP = ACS.getInstruction();
7561
7562 IRBuilder<NoFolder> IRB(IP);
7563 const DataLayout &DL = IP->getDataLayout();
7564
7565 // Traverse the type, build GEPs and loads.
7566 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
7567 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
7568 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
7569 Type *PointeeTy = PrivStructType->getElementType(u);
7570 Value *Ptr =
7571 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB);
7572 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7573 L->setAlignment(Alignment);
7574 ReplacementValues.push_back(L);
7575 }
7576 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
7577 Type *PointeeTy = PrivArrayType->getElementType();
7578 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
7579 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
7580 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB);
7581 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator());
7582 L->setAlignment(Alignment);
7583 ReplacementValues.push_back(L);
7584 }
7585 } else {
7586 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator());
7587 L->setAlignment(Alignment);
7588 ReplacementValues.push_back(L);
7589 }
7590 }
7591
7592 /// See AbstractAttribute::manifest(...)
7593 ChangeStatus manifest(Attributor &A) override {
7594 if (!PrivatizableType)
7595 return ChangeStatus::UNCHANGED;
7596 assert(*PrivatizableType && "Expected privatizable type!");
7597
7598 // Collect all tail calls in the function as we cannot allow new allocas to
7599 // escape into tail recursion.
7600 // TODO: Be smarter about new allocas escaping into tail calls.
7602 bool UsedAssumedInformation = false;
7603 if (!A.checkForAllInstructions(
7604 [&](Instruction &I) {
7605 CallInst &CI = cast<CallInst>(I);
7606 if (CI.isTailCall())
7607 TailCalls.push_back(&CI);
7608 return true;
7609 },
7610 *this, {Instruction::Call}, UsedAssumedInformation))
7611 return ChangeStatus::UNCHANGED;
7612
7613 Argument *Arg = getAssociatedArgument();
7614 // Query AAAlign attribute for alignment of associated argument to
7615 // determine the best alignment of loads.
7616 const auto *AlignAA =
7617 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE);
7618
7619 // Callback to repair the associated function. A new alloca is placed at the
7620 // beginning and initialized with the values passed through arguments. The
7621 // new alloca replaces the use of the old pointer argument.
7624 Function &ReplacementFn, Function::arg_iterator ArgIt) {
7625 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
7627 const DataLayout &DL = IP->getDataLayout();
7628 unsigned AS = DL.getAllocaAddrSpace();
7629 Instruction *AI = new AllocaInst(*PrivatizableType, AS,
7630 Arg->getName() + ".priv", IP);
7631 createInitialization(*PrivatizableType, *AI, ReplacementFn,
7632 ArgIt->getArgNo(), IP);
7633
7634 if (AI->getType() != Arg->getType())
7635 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast(
7636 AI, Arg->getType(), "", IP);
7637 Arg->replaceAllUsesWith(AI);
7638
7639 for (CallInst *CI : TailCalls)
7640 CI->setTailCall(false);
7641 };
7642
7643 // Callback to repair a call site of the associated function. The elements
7644 // of the privatizable type are loaded prior to the call and passed to the
7645 // new function version.
7648 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
7649 // When no alignment is specified for the load instruction,
7650 // natural alignment is assumed.
7651 createReplacementValues(
7652 AlignAA ? AlignAA->getAssumedAlign() : Align(0),
7653 *PrivatizableType, ACS,
7654 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
7655 NewArgOperands);
7656 };
7657
7658 // Collect the types that will replace the privatizable type in the function
7659 // signature.
7660 SmallVector<Type *, 16> ReplacementTypes;
7661 identifyReplacementTypes(*PrivatizableType, ReplacementTypes);
7662
7663 // Register a rewrite of the argument.
7664 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
7665 std::move(FnRepairCB),
7666 std::move(ACSRepairCB)))
7667 return ChangeStatus::CHANGED;
7668 return ChangeStatus::UNCHANGED;
7669 }
7670
7671 /// See AbstractAttribute::trackStatistics()
7672 void trackStatistics() const override {
7673 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
7674 }
7675};
7676
7677struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
7678 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A)
7679 : AAPrivatizablePtrImpl(IRP, A) {}
7680
7681 /// See AbstractAttribute::initialize(...).
7682 void initialize(Attributor &A) override {
7683 // TODO: We can privatize more than arguments.
7684 indicatePessimisticFixpoint();
7685 }
7686
7687 ChangeStatus updateImpl(Attributor &A) override {
7688 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
7689 "updateImpl will not be called");
7690 }
7691
7692 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
7693 std::optional<Type *> identifyPrivatizableType(Attributor &A) override {
7694 Value *Obj = getUnderlyingObject(&getAssociatedValue());
7695 if (!Obj) {
7696 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
7697 return nullptr;
7698 }
7699
7700 if (auto *AI = dyn_cast<AllocaInst>(Obj))
7701 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
7702 if (CI->isOne())
7703 return AI->getAllocatedType();
7704 if (auto *Arg = dyn_cast<Argument>(Obj)) {
7705 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>(
7706 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED);
7707 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr())
7708 return PrivArgAA->getPrivatizableType();
7709 }
7710
7711 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
7712 "alloca nor privatizable argument: "
7713 << *Obj << "!\n");
7714 return nullptr;
7715 }
7716
7717 /// See AbstractAttribute::trackStatistics()
7718 void trackStatistics() const override {
7719 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
7720 }
7721};
7722
7723struct AAPrivatizablePtrCallSiteArgument final
7724 : public AAPrivatizablePtrFloating {
7725 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A)
7726 : AAPrivatizablePtrFloating(IRP, A) {}
7727
7728 /// See AbstractAttribute::initialize(...).
7729 void initialize(Attributor &A) override {
7730 if (A.hasAttr(getIRPosition(), Attribute::ByVal))
7731 indicateOptimisticFixpoint();
7732 }
7733
7734 /// See AbstractAttribute::updateImpl(...).
7735 ChangeStatus updateImpl(Attributor &A) override {
7736 PrivatizableType = identifyPrivatizableType(A);
7737 if (!PrivatizableType)
7738 return ChangeStatus::UNCHANGED;
7739 if (!*PrivatizableType)
7740 return indicatePessimisticFixpoint();
7741
7742 const IRPosition &IRP = getIRPosition();
7743 bool IsKnownNoCapture;
7744 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
7745 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture);
7746 if (!IsAssumedNoCapture) {
7747 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
7748 return indicatePessimisticFixpoint();
7749 }
7750
7751 bool IsKnownNoAlias;
7752 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>(
7753 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) {
7754 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
7755 return indicatePessimisticFixpoint();
7756 }
7757
7758 bool IsKnown;
7759 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) {
7760 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
7761 return indicatePessimisticFixpoint();
7762 }
7763
7764 return ChangeStatus::UNCHANGED;
7765 }
7766
7767 /// See AbstractAttribute::trackStatistics()
7768 void trackStatistics() const override {
7769 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
7770 }
7771};
7772
7773struct AAPrivatizablePtrCallSiteReturned final
7774 : public AAPrivatizablePtrFloating {
7775 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A)
7776 : AAPrivatizablePtrFloating(IRP, A) {}
7777
7778 /// See AbstractAttribute::initialize(...).
7779 void initialize(Attributor &A) override {
7780 // TODO: We can privatize more than arguments.
7781 indicatePessimisticFixpoint();
7782 }
7783
7784 /// See AbstractAttribute::trackStatistics()
7785 void trackStatistics() const override {
7786 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
7787 }
7788};
7789
7790struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
7791 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A)
7792 : AAPrivatizablePtrFloating(IRP, A) {}
7793
7794 /// See AbstractAttribute::initialize(...).
7795 void initialize(Attributor &A) override {
7796 // TODO: We can privatize more than arguments.
7797 indicatePessimisticFixpoint();
7798 }
7799
7800 /// See AbstractAttribute::trackStatistics()
7801 void trackStatistics() const override {
7802 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
7803 }
7804};
7805} // namespace
7806
7807/// -------------------- Memory Behavior Attributes ----------------------------
7808/// Includes read-none, read-only, and write-only.
7809/// ----------------------------------------------------------------------------
7810namespace {
7811struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
7812 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A)
7813 : AAMemoryBehavior(IRP, A) {}
7814
7815 /// See AbstractAttribute::initialize(...).
7816 void initialize(Attributor &A) override {
7817 intersectAssumedBits(BEST_STATE);
7818 getKnownStateFromValue(A, getIRPosition(), getState());
7819 AAMemoryBehavior::initialize(A);
7820 }
7821
7822 /// Return the memory behavior information encoded in the IR for \p IRP.
7823 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
7824 BitIntegerState &State,
7825 bool IgnoreSubsumingPositions = false) {
7827 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions);
7828 for (const Attribute &Attr : Attrs) {
7829 switch (Attr.getKindAsEnum()) {
7830 case Attribute::ReadNone:
7831 State.addKnownBits(NO_ACCESSES);
7832 break;
7833 case Attribute::ReadOnly:
7834 State.addKnownBits(NO_WRITES);
7835 break;
7836 case Attribute::WriteOnly:
7837 State.addKnownBits(NO_READS);
7838 break;
7839 default:
7840 llvm_unreachable("Unexpected attribute!");
7841 }
7842 }
7843
7844 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
7845 if (!I->mayReadFromMemory())
7846 State.addKnownBits(NO_READS);
7847 if (!I->mayWriteToMemory())
7848 State.addKnownBits(NO_WRITES);
7849 }
7850 }
7851
7852 /// See AbstractAttribute::getDeducedAttributes(...).
7853 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
7854 SmallVectorImpl<Attribute> &Attrs) const override {
7855 assert(Attrs.size() == 0);
7856 if (isAssumedReadNone())
7857 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
7858 else if (isAssumedReadOnly())
7859 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
7860 else if (isAssumedWriteOnly())
7861 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
7862 assert(Attrs.size() <= 1);
7863 }
7864
7865 /// See AbstractAttribute::manifest(...).
7866 ChangeStatus manifest(Attributor &A) override {
7867 const IRPosition &IRP = getIRPosition();
7868
7869 if (A.hasAttr(IRP, Attribute::ReadNone,
7870 /* IgnoreSubsumingPositions */ true))
7871 return ChangeStatus::UNCHANGED;
7872
7873 // Check if we would improve the existing attributes first.
7874 SmallVector<Attribute, 4> DeducedAttrs;
7875 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
7876 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
7877 return A.hasAttr(IRP, Attr.getKindAsEnum(),
7878 /* IgnoreSubsumingPositions */ true);
7879 }))
7880 return ChangeStatus::UNCHANGED;
7881
7882 // Clear existing attributes.
7883 A.removeAttrs(IRP, AttrKinds);
7884 // Clear conflicting writable attribute.
7885 if (isAssumedReadOnly())
7886 A.removeAttrs(IRP, Attribute::Writable);
7887
7888 // Use the generic manifest method.
7889 return IRAttribute::manifest(A);
7890 }
7891
7892 /// See AbstractState::getAsStr().
7893 const std::string getAsStr(Attributor *A) const override {
7894 if (isAssumedReadNone())
7895 return "readnone";
7896 if (isAssumedReadOnly())
7897 return "readonly";
7898 if (isAssumedWriteOnly())
7899 return "writeonly";
7900 return "may-read/write";
7901 }
7902
7903 /// The set of IR attributes AAMemoryBehavior deals with.
7904 static const Attribute::AttrKind AttrKinds[3];
7905};
7906
7907const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
7908 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
7909
7910/// Memory behavior attribute for a floating value.
7911struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
7912 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A)
7913 : AAMemoryBehaviorImpl(IRP, A) {}
7914
7915 /// See AbstractAttribute::updateImpl(...).
7916 ChangeStatus updateImpl(Attributor &A) override;
7917
7918 /// See AbstractAttribute::trackStatistics()
7919 void trackStatistics() const override {
7920 if (isAssumedReadNone())
7922 else if (isAssumedReadOnly())
7924 else if (isAssumedWriteOnly())
7926 }
7927
7928private:
7929 /// Return true if users of \p UserI might access the underlying
7930 /// variable/location described by \p U and should therefore be analyzed.
7931 bool followUsersOfUseIn(Attributor &A, const Use &U,
7932 const Instruction *UserI);
7933
7934 /// Update the state according to the effect of use \p U in \p UserI.
7935 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI);
7936};
7937
7938/// Memory behavior attribute for function argument.
7939struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
7940 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A)
7941 : AAMemoryBehaviorFloating(IRP, A) {}
7942
7943 /// See AbstractAttribute::initialize(...).
7944 void initialize(Attributor &A) override {
7945 intersectAssumedBits(BEST_STATE);
7946 const IRPosition &IRP = getIRPosition();
7947 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
7948 // can query it when we use has/getAttr. That would allow us to reuse the
7949 // initialize of the base class here.
7950 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal},
7951 /* IgnoreSubsumingPositions */ true);
7952 getKnownStateFromValue(A, IRP, getState(),
7953 /* IgnoreSubsumingPositions */ HasByVal);
7954 }
7955
7956 ChangeStatus manifest(Attributor &A) override {
7957 // TODO: Pointer arguments are not supported on vectors of pointers yet.
7958 if (!getAssociatedValue().getType()->isPointerTy())
7959 return ChangeStatus::UNCHANGED;
7960
7961 // TODO: From readattrs.ll: "inalloca parameters are always
7962 // considered written"
7963 if (A.hasAttr(getIRPosition(),
7964 {Attribute::InAlloca, Attribute::Preallocated})) {
7965 removeKnownBits(NO_WRITES);
7966 removeAssumedBits(NO_WRITES);
7967 }
7968 A.removeAttrs(getIRPosition(), AttrKinds);
7969 return AAMemoryBehaviorFloating::manifest(A);
7970 }
7971
7972 /// See AbstractAttribute::trackStatistics()
7973 void trackStatistics() const override {
7974 if (isAssumedReadNone())
7975 STATS_DECLTRACK_ARG_ATTR(readnone)
7976 else if (isAssumedReadOnly())
7977 STATS_DECLTRACK_ARG_ATTR(readonly)
7978 else if (isAssumedWriteOnly())
7979 STATS_DECLTRACK_ARG_ATTR(writeonly)
7980 }
7981};
7982
7983struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
7984 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A)
7985 : AAMemoryBehaviorArgument(IRP, A) {}
7986
7987 /// See AbstractAttribute::initialize(...).
7988 void initialize(Attributor &A) override {
7989 // If we don't have an associated attribute this is either a variadic call
7990 // or an indirect call, either way, nothing to do here.
7991 Argument *Arg = getAssociatedArgument();
7992 if (!Arg) {
7993 indicatePessimisticFixpoint();
7994 return;
7995 }
7996 if (Arg->hasByValAttr()) {
7997 addKnownBits(NO_WRITES);
7998 removeKnownBits(NO_READS);
7999 removeAssumedBits(NO_READS);
8000 }
8001 AAMemoryBehaviorArgument::initialize(A);
8002 if (getAssociatedFunction()->isDeclaration())
8003 indicatePessimisticFixpoint();
8004 }
8005
8006 /// See AbstractAttribute::updateImpl(...).
8007 ChangeStatus updateImpl(Attributor &A) override {
8008 // TODO: Once we have call site specific value information we can provide
8009 // call site specific liveness liveness information and then it makes
8010 // sense to specialize attributes for call sites arguments instead of
8011 // redirecting requests to the callee argument.
8012 Argument *Arg = getAssociatedArgument();
8013 const IRPosition &ArgPos = IRPosition::argument(*Arg);
8014 auto *ArgAA =
8015 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED);
8016 if (!ArgAA)
8017 return indicatePessimisticFixpoint();
8018 return clampStateAndIndicateChange(getState(), ArgAA->getState());
8019 }
8020
8021 /// See AbstractAttribute::trackStatistics()
8022 void trackStatistics() const override {
8023 if (isAssumedReadNone())
8025 else if (isAssumedReadOnly())
8027 else if (isAssumedWriteOnly())
8029 }
8030};
8031
8032/// Memory behavior attribute for a call site return position.
8033struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
8034 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A)
8035 : AAMemoryBehaviorFloating(IRP, A) {}
8036
8037 /// See AbstractAttribute::initialize(...).
8038 void initialize(Attributor &A) override {
8039 AAMemoryBehaviorImpl::initialize(A);
8040 }
8041 /// See AbstractAttribute::manifest(...).
8042 ChangeStatus manifest(Attributor &A) override {
8043 // We do not annotate returned values.
8044 return ChangeStatus::UNCHANGED;
8045 }
8046
8047 /// See AbstractAttribute::trackStatistics()
8048 void trackStatistics() const override {}
8049};
8050
8051/// An AA to represent the memory behavior function attributes.
8052struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
8053 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A)
8054 : AAMemoryBehaviorImpl(IRP, A) {}
8055
8056 /// See AbstractAttribute::updateImpl(Attributor &A).
8057 ChangeStatus updateImpl(Attributor &A) override;
8058
8059 /// See AbstractAttribute::manifest(...).
8060 ChangeStatus manifest(Attributor &A) override {
8061 // TODO: It would be better to merge this with AAMemoryLocation, so that
8062 // we could determine read/write per location. This would also have the
8063 // benefit of only one place trying to manifest the memory attribute.
8064 Function &F = cast<Function>(getAnchorValue());
8066 if (isAssumedReadNone())
8067 ME = MemoryEffects::none();
8068 else if (isAssumedReadOnly())
8070 else if (isAssumedWriteOnly())
8072
8073 A.removeAttrs(getIRPosition(), AttrKinds);
8074 // Clear conflicting writable attribute.
8075 if (ME.onlyReadsMemory())
8076 for (Argument &Arg : F.args())
8077 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable);
8078 return A.manifestAttrs(getIRPosition(),
8079 Attribute::getWithMemoryEffects(F.getContext(), ME));
8080 }
8081
8082 /// See AbstractAttribute::trackStatistics()
8083 void trackStatistics() const override {
8084 if (isAssumedReadNone())
8085 STATS_DECLTRACK_FN_ATTR(readnone)
8086 else if (isAssumedReadOnly())
8087 STATS_DECLTRACK_FN_ATTR(readonly)
8088 else if (isAssumedWriteOnly())
8089 STATS_DECLTRACK_FN_ATTR(writeonly)
8090 }
8091};
8092
8093/// AAMemoryBehavior attribute for call sites.
8094struct AAMemoryBehaviorCallSite final
8095 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> {
8096 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A)
8097 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {}
8098
8099 /// See AbstractAttribute::manifest(...).
8100 ChangeStatus manifest(Attributor &A) override {
8101 // TODO: Deduplicate this with AAMemoryBehaviorFunction.
8102 CallBase &CB = cast<CallBase>(getAnchorValue());
8104 if (isAssumedReadNone())
8105 ME = MemoryEffects::none();
8106 else if (isAssumedReadOnly())
8108 else if (isAssumedWriteOnly())
8110
8111 A.removeAttrs(getIRPosition(), AttrKinds);
8112 // Clear conflicting writable attribute.
8113 if (ME.onlyReadsMemory())
8114 for (Use &U : CB.args())
8115 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()),
8116 Attribute::Writable);
8117 return A.manifestAttrs(
8118 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME));
8119 }
8120
8121 /// See AbstractAttribute::trackStatistics()
8122 void trackStatistics() const override {
8123 if (isAssumedReadNone())
8124 STATS_DECLTRACK_CS_ATTR(readnone)
8125 else if (isAssumedReadOnly())
8126 STATS_DECLTRACK_CS_ATTR(readonly)
8127 else if (isAssumedWriteOnly())
8128 STATS_DECLTRACK_CS_ATTR(writeonly)
8129 }
8130};
8131
8132ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
8133
8134 // The current assumed state used to determine a change.
8135 auto AssumedState = getAssumed();
8136
8137 auto CheckRWInst = [&](Instruction &I) {
8138 // If the instruction has an own memory behavior state, use it to restrict
8139 // the local state. No further analysis is required as the other memory
8140 // state is as optimistic as it gets.
8141 if (const auto *CB = dyn_cast<CallBase>(&I)) {
8142 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
8144 if (MemBehaviorAA) {
8145 intersectAssumedBits(MemBehaviorAA->getAssumed());
8146 return !isAtFixpoint();
8147 }
8148 }
8149
8150 // Remove access kind modifiers if necessary.
8151 if (I.mayReadFromMemory())
8152 removeAssumedBits(NO_READS);
8153 if (I.mayWriteToMemory())
8154 removeAssumedBits(NO_WRITES);
8155 return !isAtFixpoint();
8156 };
8157
8158 bool UsedAssumedInformation = false;
8159 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8160 UsedAssumedInformation))
8161 return indicatePessimisticFixpoint();
8162
8163 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8165}
8166
8167ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
8168
8169 const IRPosition &IRP = getIRPosition();
8170 const IRPosition &FnPos = IRPosition::function_scope(IRP);
8171 AAMemoryBehavior::StateType &S = getState();
8172
8173 // First, check the function scope. We take the known information and we avoid
8174 // work if the assumed information implies the current assumed information for
8175 // this attribute. This is a valid for all but byval arguments.
8176 Argument *Arg = IRP.getAssociatedArgument();
8177 AAMemoryBehavior::base_t FnMemAssumedState =
8179 if (!Arg || !Arg->hasByValAttr()) {
8180 const auto *FnMemAA =
8181 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL);
8182 if (FnMemAA) {
8183 FnMemAssumedState = FnMemAA->getAssumed();
8184 S.addKnownBits(FnMemAA->getKnown());
8185 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed())
8187 }
8188 }
8189
8190 // The current assumed state used to determine a change.
8191 auto AssumedState = S.getAssumed();
8192
8193 // Make sure the value is not captured (except through "return"), if
8194 // it is, any information derived would be irrelevant anyway as we cannot
8195 // check the potential aliases introduced by the capture. However, no need
8196 // to fall back to anythign less optimistic than the function state.
8197 bool IsKnownNoCapture;
8198 const AANoCapture *ArgNoCaptureAA = nullptr;
8199 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>(
8200 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false,
8201 &ArgNoCaptureAA);
8202
8203 if (!IsAssumedNoCapture &&
8204 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) {
8205 S.intersectAssumedBits(FnMemAssumedState);
8206 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8208 }
8209
8210 // Visit and expand uses until all are analyzed or a fixpoint is reached.
8211 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
8212 Instruction *UserI = cast<Instruction>(U.getUser());
8213 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI
8214 << " \n");
8215
8216 // Droppable users, e.g., llvm::assume does not actually perform any action.
8217 if (UserI->isDroppable())
8218 return true;
8219
8220 // Check if the users of UserI should also be visited.
8221 Follow = followUsersOfUseIn(A, U, UserI);
8222
8223 // If UserI might touch memory we analyze the use in detail.
8224 if (UserI->mayReadOrWriteMemory())
8225 analyzeUseIn(A, U, UserI);
8226
8227 return !isAtFixpoint();
8228 };
8229
8230 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
8231 return indicatePessimisticFixpoint();
8232
8233 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
8235}
8236
8237bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U,
8238 const Instruction *UserI) {
8239 // The loaded value is unrelated to the pointer argument, no need to
8240 // follow the users of the load.
8241 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI))
8242 return false;
8243
8244 // By default we follow all uses assuming UserI might leak information on U,
8245 // we have special handling for call sites operands though.
8246 const auto *CB = dyn_cast<CallBase>(UserI);
8247 if (!CB || !CB->isArgOperand(&U))
8248 return true;
8249
8250 // If the use is a call argument known not to be captured, the users of
8251 // the call do not need to be visited because they have to be unrelated to
8252 // the input. Note that this check is not trivial even though we disallow
8253 // general capturing of the underlying argument. The reason is that the
8254 // call might the argument "through return", which we allow and for which we
8255 // need to check call users.
8256 if (U.get()->getType()->isPointerTy()) {
8257 unsigned ArgNo = CB->getArgOperandNo(&U);
8258 bool IsKnownNoCapture;
8259 return !AA::hasAssumedIRAttr<Attribute::Captures>(
8260 A, this, IRPosition::callsite_argument(*CB, ArgNo),
8261 DepClassTy::OPTIONAL, IsKnownNoCapture);
8262 }
8263
8264 return true;
8265}
8266
8267void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U,
8268 const Instruction *UserI) {
8269 assert(UserI->mayReadOrWriteMemory());
8270
8271 switch (UserI->getOpcode()) {
8272 default:
8273 // TODO: Handle all atomics and other side-effect operations we know of.
8274 break;
8275 case Instruction::Load:
8276 // Loads cause the NO_READS property to disappear.
8277 removeAssumedBits(NO_READS);
8278 return;
8279
8280 case Instruction::Store:
8281 // Stores cause the NO_WRITES property to disappear if the use is the
8282 // pointer operand. Note that while capturing was taken care of somewhere
8283 // else we need to deal with stores of the value that is not looked through.
8284 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get())
8285 removeAssumedBits(NO_WRITES);
8286 else
8287 indicatePessimisticFixpoint();
8288 return;
8289
8290 case Instruction::Call:
8291 case Instruction::CallBr:
8292 case Instruction::Invoke: {
8293 // For call sites we look at the argument memory behavior attribute (this
8294 // could be recursive!) in order to restrict our own state.
8295 const auto *CB = cast<CallBase>(UserI);
8296
8297 // Give up on operand bundles.
8298 if (CB->isBundleOperand(&U)) {
8299 indicatePessimisticFixpoint();
8300 return;
8301 }
8302
8303 // Calling a function does read the function pointer, maybe write it if the
8304 // function is self-modifying.
8305 if (CB->isCallee(&U)) {
8306 removeAssumedBits(NO_READS);
8307 break;
8308 }
8309
8310 // Adjust the possible access behavior based on the information on the
8311 // argument.
8312 IRPosition Pos;
8313 if (U.get()->getType()->isPointerTy())
8315 else
8317 const auto *MemBehaviorAA =
8318 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL);
8319 if (!MemBehaviorAA)
8320 break;
8321 // "assumed" has at most the same bits as the MemBehaviorAA assumed
8322 // and at least "known".
8323 intersectAssumedBits(MemBehaviorAA->getAssumed());
8324 return;
8325 }
8326 };
8327
8328 // Generally, look at the "may-properties" and adjust the assumed state if we
8329 // did not trigger special handling before.
8330 if (UserI->mayReadFromMemory())
8331 removeAssumedBits(NO_READS);
8332 if (UserI->mayWriteToMemory())
8333 removeAssumedBits(NO_WRITES);
8334}
8335} // namespace
8336
8337/// -------------------- Memory Locations Attributes ---------------------------
8338/// Includes read-none, argmemonly, inaccessiblememonly,
8339/// inaccessiblememorargmemonly
8340/// ----------------------------------------------------------------------------
8341
8344 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
8345 return "all memory";
8347 return "no memory";
8348 std::string S = "memory:";
8349 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
8350 S += "stack,";
8351 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
8352 S += "constant,";
8354 S += "internal global,";
8356 S += "external global,";
8357 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
8358 S += "argument,";
8360 S += "inaccessible,";
8361 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
8362 S += "malloced,";
8363 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
8364 S += "unknown,";
8365 S.pop_back();
8366 return S;
8367}
8368
8369namespace {
8370struct AAMemoryLocationImpl : public AAMemoryLocation {
8371
8372 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A)
8374 AccessKind2Accesses.fill(nullptr);
8375 }
8376
8377 ~AAMemoryLocationImpl() {
8378 // The AccessSets are allocated via a BumpPtrAllocator, we call
8379 // the destructor manually.
8380 for (AccessSet *AS : AccessKind2Accesses)
8381 if (AS)
8382 AS->~AccessSet();
8383 }
8384
8385 /// See AbstractAttribute::initialize(...).
8386 void initialize(Attributor &A) override {
8387 intersectAssumedBits(BEST_STATE);
8388 getKnownStateFromValue(A, getIRPosition(), getState());
8389 AAMemoryLocation::initialize(A);
8390 }
8391
8392 /// Return the memory behavior information encoded in the IR for \p IRP.
8393 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP,
8394 BitIntegerState &State,
8395 bool IgnoreSubsumingPositions = false) {
8396 // For internal functions we ignore `argmemonly` and
8397 // `inaccessiblememorargmemonly` as we might break it via interprocedural
8398 // constant propagation. It is unclear if this is the best way but it is
8399 // unlikely this will cause real performance problems. If we are deriving
8400 // attributes for the anchor function we even remove the attribute in
8401 // addition to ignoring it.
8402 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM /
8403 // MemoryEffects::Other as a possible location.
8404 bool UseArgMemOnly = true;
8405 Function *AnchorFn = IRP.getAnchorScope();
8406 if (AnchorFn && A.isRunOn(*AnchorFn))
8407 UseArgMemOnly = !AnchorFn->hasLocalLinkage();
8408
8410 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions);
8411 for (const Attribute &Attr : Attrs) {
8412 // TODO: We can map MemoryEffects to Attributor locations more precisely.
8413 MemoryEffects ME = Attr.getMemoryEffects();
8414 if (ME.doesNotAccessMemory()) {
8415 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
8416 continue;
8417 }
8418 if (ME.onlyAccessesInaccessibleMem()) {
8419 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
8420 continue;
8421 }
8422 if (ME.onlyAccessesArgPointees()) {
8423 if (UseArgMemOnly)
8424 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
8425 else {
8426 // Remove location information, only keep read/write info.
8427 ME = MemoryEffects(ME.getModRef());
8428 A.manifestAttrs(IRP,
8430 IRP.getAnchorValue().getContext(), ME),
8431 /*ForceReplace*/ true);
8432 }
8433 continue;
8434 }
8436 if (UseArgMemOnly)
8437 State.addKnownBits(inverseLocation(
8438 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
8439 else {
8440 // Remove location information, only keep read/write info.
8441 ME = MemoryEffects(ME.getModRef());
8442 A.manifestAttrs(IRP,
8444 IRP.getAnchorValue().getContext(), ME),
8445 /*ForceReplace*/ true);
8446 }
8447 continue;
8448 }
8449 }
8450 }
8451
8452 /// See AbstractAttribute::getDeducedAttributes(...).
8453 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
8454 SmallVectorImpl<Attribute> &Attrs) const override {
8455 // TODO: We can map Attributor locations to MemoryEffects more precisely.
8456 assert(Attrs.size() == 0);
8457 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
8458 if (isAssumedReadNone())
8459 Attrs.push_back(
8461 else if (isAssumedInaccessibleMemOnly())
8464 else if (isAssumedArgMemOnly())
8465 Attrs.push_back(
8467 else if (isAssumedInaccessibleOrArgMemOnly())
8470 }
8471 assert(Attrs.size() <= 1);
8472 }
8473
8474 /// See AbstractAttribute::manifest(...).
8475 ChangeStatus manifest(Attributor &A) override {
8476 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could
8477 // provide per-location modref information here.
8478 const IRPosition &IRP = getIRPosition();
8479
8480 SmallVector<Attribute, 1> DeducedAttrs;
8481 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs);
8482 if (DeducedAttrs.size() != 1)
8483 return ChangeStatus::UNCHANGED;
8484 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
8485
8486 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects(
8487 IRP.getAnchorValue().getContext(), ME));
8488 }
8489
8490 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
8491 bool checkForAllAccessesToMemoryKind(
8492 function_ref<bool(const Instruction *, const Value *, AccessKind,
8493 MemoryLocationsKind)>
8494 Pred,
8495 MemoryLocationsKind RequestedMLK) const override {
8496 if (!isValidState())
8497 return false;
8498
8499 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
8500 if (AssumedMLK == NO_LOCATIONS)
8501 return true;
8502
8503 unsigned Idx = 0;
8504 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS;
8505 CurMLK *= 2, ++Idx) {
8506 if (CurMLK & RequestedMLK)
8507 continue;
8508
8509 if (const AccessSet *Accesses = AccessKind2Accesses[Idx])
8510 for (const AccessInfo &AI : *Accesses)
8511 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
8512 return false;
8513 }
8514
8515 return true;
8516 }
8517
8518 ChangeStatus indicatePessimisticFixpoint() override {
8519 // If we give up and indicate a pessimistic fixpoint this instruction will
8520 // become an access for all potential access kinds:
8521 // TODO: Add pointers for argmemonly and globals to improve the results of
8522 // checkForAllAccessesToMemoryKind.
8523 bool Changed = false;
8524 MemoryLocationsKind KnownMLK = getKnown();
8525 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
8526 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
8527 if (!(CurMLK & KnownMLK))
8528 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed,
8529 getAccessKindFromInst(I));
8530 return AAMemoryLocation::indicatePessimisticFixpoint();
8531 }
8532
8533protected:
8534 /// Helper struct to tie together an instruction that has a read or write
8535 /// effect with the pointer it accesses (if any).
8536 struct AccessInfo {
8537
8538 /// The instruction that caused the access.
8539 const Instruction *I;
8540
8541 /// The base pointer that is accessed, or null if unknown.
8542 const Value *Ptr;
8543
8544 /// The kind of access (read/write/read+write).
8546
8547 bool operator==(const AccessInfo &RHS) const {
8548 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
8549 }
8550 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
8551 if (LHS.I != RHS.I)
8552 return LHS.I < RHS.I;
8553 if (LHS.Ptr != RHS.Ptr)
8554 return LHS.Ptr < RHS.Ptr;
8555 if (LHS.Kind != RHS.Kind)
8556 return LHS.Kind < RHS.Kind;
8557 return false;
8558 }
8559 };
8560
8561 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
8562 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
8563 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>;
8564 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses;
8565
8566 /// Categorize the pointer arguments of CB that might access memory in
8567 /// AccessedLoc and update the state and access map accordingly.
8568 void
8569 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB,
8570 AAMemoryLocation::StateType &AccessedLocs,
8571 bool &Changed);
8572
8573 /// Return the kind(s) of location that may be accessed by \p V.
8575 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
8576
8577 /// Return the access kind as determined by \p I.
8578 AccessKind getAccessKindFromInst(const Instruction *I) {
8579 AccessKind AK = READ_WRITE;
8580 if (I) {
8581 AK = I->mayReadFromMemory() ? READ : NONE;
8582 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE));
8583 }
8584 return AK;
8585 }
8586
8587 /// Update the state \p State and the AccessKind2Accesses given that \p I is
8588 /// an access of kind \p AK to a \p MLK memory location with the access
8589 /// pointer \p Ptr.
8590 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
8591 MemoryLocationsKind MLK, const Instruction *I,
8592 const Value *Ptr, bool &Changed,
8593 AccessKind AK = READ_WRITE) {
8594
8595 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
8596 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)];
8597 if (!Accesses)
8598 Accesses = new (Allocator) AccessSet();
8599 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second;
8600 if (MLK == NO_UNKOWN_MEM)
8601 MLK = NO_LOCATIONS;
8602 State.removeAssumedBits(MLK);
8603 }
8604
8605 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
8606 /// arguments, and update the state and access map accordingly.
8607 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
8608 AAMemoryLocation::StateType &State, bool &Changed,
8609 unsigned AccessAS = 0);
8610
8611 /// Used to allocate access sets.
8613};
8614
8615void AAMemoryLocationImpl::categorizePtrValue(
8616 Attributor &A, const Instruction &I, const Value &Ptr,
8617 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) {
8618 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
8619 << Ptr << " ["
8620 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
8621
8622 auto Pred = [&](Value &Obj) {
8623 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace();
8624 // TODO: recognize the TBAA used for constant accesses.
8625 MemoryLocationsKind MLK = NO_LOCATIONS;
8626
8627 // Filter accesses to constant (GPU) memory if we have an AS at the access
8628 // site or the object is known to actually have the associated AS.
8629 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant ||
8630 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant &&
8631 isIdentifiedObject(&Obj))) &&
8632 AA::isGPU(*I.getModule()))
8633 return true;
8634
8635 if (isa<UndefValue>(&Obj))
8636 return true;
8637 if (isa<Argument>(&Obj)) {
8638 // TODO: For now we do not treat byval arguments as local copies performed
8639 // on the call edge, though, we should. To make that happen we need to
8640 // teach various passes, e.g., DSE, about the copy effect of a byval. That
8641 // would also allow us to mark functions only accessing byval arguments as
8642 // readnone again, arguably their accesses have no effect outside of the
8643 // function, like accesses to allocas.
8644 MLK = NO_ARGUMENT_MEM;
8645 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) {
8646 // Reading constant memory is not treated as a read "effect" by the
8647 // function attr pass so we won't neither. Constants defined by TBAA are
8648 // similar. (We know we do not write it because it is constant.)
8649 if (auto *GVar = dyn_cast<GlobalVariable>(GV))
8650 if (GVar->isConstant())
8651 return true;
8652
8653 if (GV->hasLocalLinkage())
8654 MLK = NO_GLOBAL_INTERNAL_MEM;
8655 else
8656 MLK = NO_GLOBAL_EXTERNAL_MEM;
8657 } else if (isa<ConstantPointerNull>(&Obj) &&
8658 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) ||
8659 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) {
8660 return true;
8661 } else if (isa<AllocaInst>(&Obj)) {
8662 MLK = NO_LOCAL_MEM;
8663 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) {
8664 bool IsKnownNoAlias;
8665 if (AA::hasAssumedIRAttr<Attribute::NoAlias>(
8667 IsKnownNoAlias))
8668 MLK = NO_MALLOCED_MEM;
8669 else
8670 MLK = NO_UNKOWN_MEM;
8671 } else {
8672 MLK = NO_UNKOWN_MEM;
8673 }
8674
8675 assert(MLK != NO_LOCATIONS && "No location specified!");
8676 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: "
8677 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n");
8678 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed,
8679 getAccessKindFromInst(&I));
8680
8681 return true;
8682 };
8683
8684 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
8686 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) {
8687 LLVM_DEBUG(
8688 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
8689 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed,
8690 getAccessKindFromInst(&I));
8691 return;
8692 }
8693
8694 LLVM_DEBUG(
8695 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: "
8696 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
8697}
8698
8699void AAMemoryLocationImpl::categorizeArgumentPointerLocations(
8700 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs,
8701 bool &Changed) {
8702 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) {
8703
8704 // Skip non-pointer arguments.
8705 const Value *ArgOp = CB.getArgOperand(ArgNo);
8706 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
8707 continue;
8708
8709 // Skip readnone arguments.
8710 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo);
8711 const auto *ArgOpMemLocationAA =
8712 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL);
8713
8714 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone())
8715 continue;
8716
8717 // Categorize potentially accessed pointer arguments as if there was an
8718 // access instruction with them as pointer.
8719 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed);
8720 }
8721}
8722
8724AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
8725 bool &Changed) {
8726 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
8727 << I << "\n");
8728
8729 AAMemoryLocation::StateType AccessedLocs;
8730 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
8731
8732 if (auto *CB = dyn_cast<CallBase>(&I)) {
8733
8734 // First check if we assume any memory is access is visible.
8735 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>(
8737 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
8738 << " [" << CBMemLocationAA << "]\n");
8739 if (!CBMemLocationAA) {
8740 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr,
8741 Changed, getAccessKindFromInst(&I));
8742 return NO_UNKOWN_MEM;
8743 }
8744
8745 if (CBMemLocationAA->isAssumedReadNone())
8746 return NO_LOCATIONS;
8747
8748 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) {
8749 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr,
8750 Changed, getAccessKindFromInst(&I));
8751 return AccessedLocs.getAssumed();
8752 }
8753
8754 uint32_t CBAssumedNotAccessedLocs =
8755 CBMemLocationAA->getAssumedNotAccessedLocation();
8756
8757 // Set the argmemonly and global bit as we handle them separately below.
8758 uint32_t CBAssumedNotAccessedLocsNoArgMem =
8759 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
8760
8761 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
8762 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK)
8763 continue;
8764 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed,
8765 getAccessKindFromInst(&I));
8766 }
8767
8768 // Now handle global memory if it might be accessed. This is slightly tricky
8769 // as NO_GLOBAL_MEM has multiple bits set.
8770 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM);
8771 if (HasGlobalAccesses) {
8772 auto AccessPred = [&](const Instruction *, const Value *Ptr,
8773 AccessKind Kind, MemoryLocationsKind MLK) {
8774 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed,
8775 getAccessKindFromInst(&I));
8776 return true;
8777 };
8778 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind(
8779 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
8780 return AccessedLocs.getWorstState();
8781 }
8782
8783 LLVM_DEBUG(
8784 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
8785 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8786
8787 // Now handle argument memory if it might be accessed.
8788 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM);
8789 if (HasArgAccesses)
8790 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed);
8791
8792 LLVM_DEBUG(
8793 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
8794 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
8795
8796 return AccessedLocs.getAssumed();
8797 }
8798
8799 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
8800 LLVM_DEBUG(
8801 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
8802 << I << " [" << *Ptr << "]\n");
8803 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed,
8804 Ptr->getType()->getPointerAddressSpace());
8805 return AccessedLocs.getAssumed();
8806 }
8807
8808 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
8809 << I << "\n");
8810 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed,
8811 getAccessKindFromInst(&I));
8812 return AccessedLocs.getAssumed();
8813}
8814
8815/// An AA to represent the memory behavior function attributes.
8816struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
8817 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A)
8818 : AAMemoryLocationImpl(IRP, A) {}
8819
8820 /// See AbstractAttribute::updateImpl(Attributor &A).
8821 ChangeStatus updateImpl(Attributor &A) override {
8822
8823 const auto *MemBehaviorAA =
8824 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE);
8825 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) {
8826 if (MemBehaviorAA->isKnownReadNone())
8827 return indicateOptimisticFixpoint();
8829 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
8830 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL);
8831 return ChangeStatus::UNCHANGED;
8832 }
8833
8834 // The current assumed state used to determine a change.
8835 auto AssumedState = getAssumed();
8836 bool Changed = false;
8837
8838 auto CheckRWInst = [&](Instruction &I) {
8839 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
8840 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
8841 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
8842 removeAssumedBits(inverseLocation(MLK, false, false));
8843 // Stop once only the valid bit set in the *not assumed location*, thus
8844 // once we don't actually exclude any memory locations in the state.
8845 return getAssumedNotAccessedLocation() != VALID_STATE;
8846 };
8847
8848 bool UsedAssumedInformation = false;
8849 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
8850 UsedAssumedInformation))
8851 return indicatePessimisticFixpoint();
8852
8853 Changed |= AssumedState != getAssumed();
8854 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8855 }
8856
8857 /// See AbstractAttribute::trackStatistics()
8858 void trackStatistics() const override {
8859 if (isAssumedReadNone())
8860 STATS_DECLTRACK_FN_ATTR(readnone)
8861 else if (isAssumedArgMemOnly())
8862 STATS_DECLTRACK_FN_ATTR(argmemonly)
8863 else if (isAssumedInaccessibleMemOnly())
8864 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
8865 else if (isAssumedInaccessibleOrArgMemOnly())
8866 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
8867 }
8868};
8869
8870/// AAMemoryLocation attribute for call sites.
8871struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
8872 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A)
8873 : AAMemoryLocationImpl(IRP, A) {}
8874
8875 /// See AbstractAttribute::updateImpl(...).
8876 ChangeStatus updateImpl(Attributor &A) override {
8877 // TODO: Once we have call site specific value information we can provide
8878 // call site specific liveness liveness information and then it makes
8879 // sense to specialize attributes for call sites arguments instead of
8880 // redirecting requests to the callee argument.
8881 Function *F = getAssociatedFunction();
8882 const IRPosition &FnPos = IRPosition::function(*F);
8883 auto *FnAA =
8884 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED);
8885 if (!FnAA)
8886 return indicatePessimisticFixpoint();
8887 bool Changed = false;
8888 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
8889 AccessKind Kind, MemoryLocationsKind MLK) {
8890 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed,
8891 getAccessKindFromInst(I));
8892 return true;
8893 };
8894 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
8895 return indicatePessimisticFixpoint();
8896 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
8897 }
8898
8899 /// See AbstractAttribute::trackStatistics()
8900 void trackStatistics() const override {
8901 if (isAssumedReadNone())
8902 STATS_DECLTRACK_CS_ATTR(readnone)
8903 }
8904};
8905} // namespace
8906
8907/// ------------------ denormal-fp-math Attribute -------------------------
8908
8909namespace {
8910struct AADenormalFPMathImpl : public AADenormalFPMath {
8911 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A)
8912 : AADenormalFPMath(IRP, A) {}
8913
8914 const std::string getAsStr(Attributor *A) const override {
8915 std::string Str("AADenormalFPMath[");
8917
8918 DenormalState Known = getKnown();
8919 if (Known.Mode.isValid())
8920 OS << "denormal-fp-math=" << Known.Mode;
8921 else
8922 OS << "invalid";
8923
8924 if (Known.ModeF32.isValid())
8925 OS << " denormal-fp-math-f32=" << Known.ModeF32;
8926 OS << ']';
8927 return Str;
8928 }
8929};
8930
8931struct AADenormalFPMathFunction final : AADenormalFPMathImpl {
8932 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A)
8933 : AADenormalFPMathImpl(IRP, A) {}
8934
8935 void initialize(Attributor &A) override {
8936 const Function *F = getAnchorScope();
8937 DenormalMode Mode = F->getDenormalModeRaw();
8938 DenormalMode ModeF32 = F->getDenormalModeF32Raw();
8939
8940 // TODO: Handling this here prevents handling the case where a callee has a
8941 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from
8942 // a function with a fully fixed mode.
8943 if (ModeF32 == DenormalMode::getInvalid())
8944 ModeF32 = Mode;
8945 Known = DenormalState{Mode, ModeF32};
8946 if (isModeFixed())
8947 indicateFixpoint();
8948 }
8949
8950 ChangeStatus updateImpl(Attributor &A) override {
8951 ChangeStatus Change = ChangeStatus::UNCHANGED;
8952
8953 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) {
8954 Function *Caller = CS.getInstruction()->getFunction();
8955 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName()
8956 << "->" << getAssociatedFunction()->getName() << '\n');
8957
8958 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>(
8959 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED);
8960 if (!CallerInfo)
8961 return false;
8962
8963 Change = Change | clampStateAndIndicateChange(this->getState(),
8964 CallerInfo->getState());
8965 return true;
8966 };
8967
8968 bool AllCallSitesKnown = true;
8969 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown))
8970 return indicatePessimisticFixpoint();
8971
8972 if (Change == ChangeStatus::CHANGED && isModeFixed())
8973 indicateFixpoint();
8974 return Change;
8975 }
8976
8977 ChangeStatus manifest(Attributor &A) override {
8978 LLVMContext &Ctx = getAssociatedFunction()->getContext();
8979
8980 SmallVector<Attribute, 2> AttrToAdd;
8981 SmallVector<StringRef, 2> AttrToRemove;
8982 if (Known.Mode == DenormalMode::getDefault()) {
8983 AttrToRemove.push_back("denormal-fp-math");
8984 } else {
8985 AttrToAdd.push_back(
8986 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str()));
8987 }
8988
8989 if (Known.ModeF32 != Known.Mode) {
8990 AttrToAdd.push_back(
8991 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str()));
8992 } else {
8993 AttrToRemove.push_back("denormal-fp-math-f32");
8994 }
8995
8996 auto &IRP = getIRPosition();
8997
8998 // TODO: There should be a combined add and remove API.
8999 return A.removeAttrs(IRP, AttrToRemove) |
9000 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true);
9001 }
9002
9003 void trackStatistics() const override {
9004 STATS_DECLTRACK_FN_ATTR(denormal_fp_math)
9005 }
9006};
9007} // namespace
9008
9009/// ------------------ Value Constant Range Attribute -------------------------
9010
9011namespace {
9012struct AAValueConstantRangeImpl : AAValueConstantRange {
9013 using StateType = IntegerRangeState;
9014 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A)
9015 : AAValueConstantRange(IRP, A) {}
9016
9017 /// See AbstractAttribute::initialize(..).
9018 void initialize(Attributor &A) override {
9019 if (A.hasSimplificationCallback(getIRPosition())) {
9020 indicatePessimisticFixpoint();
9021 return;
9022 }
9023
9024 // Intersect a range given by SCEV.
9025 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
9026
9027 // Intersect a range given by LVI.
9028 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
9029 }
9030
9031 /// See AbstractAttribute::getAsStr().
9032 const std::string getAsStr(Attributor *A) const override {
9033 std::string Str;
9035 OS << "range(" << getBitWidth() << ")<";
9036 getKnown().print(OS);
9037 OS << " / ";
9038 getAssumed().print(OS);
9039 OS << ">";
9040 return Str;
9041 }
9042
9043 /// Helper function to get a SCEV expr for the associated value at program
9044 /// point \p I.
9045 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
9046 if (!getAnchorScope())
9047 return nullptr;
9048
9049 ScalarEvolution *SE =
9050 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9051 *getAnchorScope());
9052
9053 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
9054 *getAnchorScope());
9055
9056 if (!SE || !LI)
9057 return nullptr;
9058
9059 const SCEV *S = SE->getSCEV(&getAssociatedValue());
9060 if (!I)
9061 return S;
9062
9063 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
9064 }
9065
9066 /// Helper function to get a range from SCEV for the associated value at
9067 /// program point \p I.
9068 ConstantRange getConstantRangeFromSCEV(Attributor &A,
9069 const Instruction *I = nullptr) const {
9070 if (!getAnchorScope())
9071 return getWorstState(getBitWidth());
9072
9073 ScalarEvolution *SE =
9074 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
9075 *getAnchorScope());
9076
9077 const SCEV *S = getSCEV(A, I);
9078 if (!SE || !S)
9079 return getWorstState(getBitWidth());
9080
9081 return SE->getUnsignedRange(S);
9082 }
9083
9084 /// Helper function to get a range from LVI for the associated value at
9085 /// program point \p I.
9087 getConstantRangeFromLVI(Attributor &A,
9088 const Instruction *CtxI = nullptr) const {
9089 if (!getAnchorScope())
9090 return getWorstState(getBitWidth());
9091
9092 LazyValueInfo *LVI =
9093 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
9094 *getAnchorScope());
9095
9096 if (!LVI || !CtxI)
9097 return getWorstState(getBitWidth());
9098 return LVI->getConstantRange(&getAssociatedValue(),
9099 const_cast<Instruction *>(CtxI),
9100 /*UndefAllowed*/ false);
9101 }
9102
9103 /// Return true if \p CtxI is valid for querying outside analyses.
9104 /// This basically makes sure we do not ask intra-procedural analysis
9105 /// about a context in the wrong function or a context that violates
9106 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates
9107 /// if the original context of this AA is OK or should be considered invalid.
9108 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A,
9109 const Instruction *CtxI,
9110 bool AllowAACtxI) const {
9111 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI()))
9112 return false;
9113
9114 // Our context might be in a different function, neither intra-procedural
9115 // analysis (ScalarEvolution nor LazyValueInfo) can handle that.
9116 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction()))
9117 return false;
9118
9119 // If the context is not dominated by the value there are paths to the
9120 // context that do not define the value. This cannot be handled by
9121 // LazyValueInfo so we need to bail.
9122 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) {
9123 InformationCache &InfoCache = A.getInfoCache();
9124 const DominatorTree *DT =
9126 *I->getFunction());
9127 return DT && DT->dominates(I, CtxI);
9128 }
9129
9130 return true;
9131 }
9132
9133 /// See AAValueConstantRange::getKnownConstantRange(..).
9135 getKnownConstantRange(Attributor &A,
9136 const Instruction *CtxI = nullptr) const override {
9137 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9138 /* AllowAACtxI */ false))
9139 return getKnown();
9140
9141 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9142 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9143 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
9144 }
9145
9146 /// See AAValueConstantRange::getAssumedConstantRange(..).
9148 getAssumedConstantRange(Attributor &A,
9149 const Instruction *CtxI = nullptr) const override {
9150 // TODO: Make SCEV use Attributor assumption.
9151 // We may be able to bound a variable range via assumptions in
9152 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
9153 // evolve to x^2 + x, then we can say that y is in [2, 12].
9154 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI,
9155 /* AllowAACtxI */ false))
9156 return getAssumed();
9157
9158 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
9159 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
9160 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
9161 }
9162
9163 /// Helper function to create MDNode for range metadata.
9164 static MDNode *
9165 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
9166 const ConstantRange &AssumedConstantRange) {
9167 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
9168 Ty, AssumedConstantRange.getLower())),
9169 ConstantAsMetadata::get(ConstantInt::get(
9170 Ty, AssumedConstantRange.getUpper()))};
9171 return MDNode::get(Ctx, LowAndHigh);
9172 }
9173
9174 /// Return true if \p Assumed is included in ranges from instruction \p I.
9175 static bool isBetterRange(const ConstantRange &Assumed,
9176 const Instruction &I) {
9177 if (Assumed.isFullSet())
9178 return false;
9179
9180 std::optional<ConstantRange> Known;
9181
9182 if (const auto *CB = dyn_cast<CallBase>(&I)) {
9183 Known = CB->getRange();
9184 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) {
9185 // If multiple ranges are annotated in IR, we give up to annotate assumed
9186 // range for now.
9187
9188 // TODO: If there exists a known range which containts assumed range, we
9189 // can say assumed range is better.
9190 if (KnownRanges->getNumOperands() > 2)
9191 return false;
9192
9194 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
9196 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
9197
9198 Known.emplace(Lower->getValue(), Upper->getValue());
9199 }
9200 return !Known || (*Known != Assumed && Known->contains(Assumed));
9201 }
9202
9203 /// Helper function to set range metadata.
9204 static bool
9205 setRangeMetadataIfisBetterRange(Instruction *I,
9206 const ConstantRange &AssumedConstantRange) {
9207 if (isBetterRange(AssumedConstantRange, *I)) {
9208 I->setMetadata(LLVMContext::MD_range,
9209 getMDNodeForConstantRange(I->getType(), I->getContext(),
9210 AssumedConstantRange));
9211 return true;
9212 }
9213 return false;
9214 }
9215 /// Helper function to set range return attribute.
9216 static bool
9217 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP,
9218 Instruction *I,
9219 const ConstantRange &AssumedConstantRange) {
9220 if (isBetterRange(AssumedConstantRange, *I)) {
9221 A.manifestAttrs(IRP,
9222 Attribute::get(I->getContext(), Attribute::Range,
9223 AssumedConstantRange),
9224 /*ForceReplace*/ true);
9225 return true;
9226 }
9227 return false;
9228 }
9229
9230 /// See AbstractAttribute::manifest()
9231 ChangeStatus manifest(Attributor &A) override {
9232 ChangeStatus Changed = ChangeStatus::UNCHANGED;
9233 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
9234 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
9235
9236 auto &V = getAssociatedValue();
9237 if (!AssumedConstantRange.isEmptySet() &&
9238 !AssumedConstantRange.isSingleElement()) {
9239 if (Instruction *I = dyn_cast<Instruction>(&V)) {
9240 assert(I == getCtxI() && "Should not annotate an instruction which is "
9241 "not the context instruction");
9242 if (isa<LoadInst>(I))
9243 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
9244 Changed = ChangeStatus::CHANGED;
9245 if (isa<CallInst>(I))
9246 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I,
9247 AssumedConstantRange))
9248 Changed = ChangeStatus::CHANGED;
9249 }
9250 }
9251
9252 return Changed;
9253 }
9254};
9255
9256struct AAValueConstantRangeArgument final
9257 : AAArgumentFromCallSiteArguments<
9258 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9259 true /* BridgeCallBaseContext */> {
9260 using Base = AAArgumentFromCallSiteArguments<
9261 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState,
9262 true /* BridgeCallBaseContext */>;
9263 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A)
9264 : Base(IRP, A) {}
9265
9266 /// See AbstractAttribute::trackStatistics()
9267 void trackStatistics() const override {
9268 STATS_DECLTRACK_ARG_ATTR(value_range)
9269 }
9270};
9271
9272struct AAValueConstantRangeReturned
9273 : AAReturnedFromReturnedValues<AAValueConstantRange,
9274 AAValueConstantRangeImpl,
9275 AAValueConstantRangeImpl::StateType,
9276 /* PropagateCallBaseContext */ true> {
9277 using Base =
9278 AAReturnedFromReturnedValues<AAValueConstantRange,
9279 AAValueConstantRangeImpl,
9281 /* PropagateCallBaseContext */ true>;
9282 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A)
9283 : Base(IRP, A) {}
9284
9285 /// See AbstractAttribute::initialize(...).
9286 void initialize(Attributor &A) override {
9287 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9288 indicatePessimisticFixpoint();
9289 }
9290
9291 /// See AbstractAttribute::trackStatistics()
9292 void trackStatistics() const override {
9293 STATS_DECLTRACK_FNRET_ATTR(value_range)
9294 }
9295};
9296
9297struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
9298 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A)
9299 : AAValueConstantRangeImpl(IRP, A) {}
9300
9301 /// See AbstractAttribute::initialize(...).
9302 void initialize(Attributor &A) override {
9303 AAValueConstantRangeImpl::initialize(A);
9304 if (isAtFixpoint())
9305 return;
9306
9307 Value &V = getAssociatedValue();
9308
9309 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9310 unionAssumed(ConstantRange(C->getValue()));
9311 indicateOptimisticFixpoint();
9312 return;
9313 }
9314
9315 if (isa<UndefValue>(&V)) {
9316 // Collapse the undef state to 0.
9317 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
9318 indicateOptimisticFixpoint();
9319 return;
9320 }
9321
9322 if (isa<CallBase>(&V))
9323 return;
9324
9325 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
9326 return;
9327
9328 // If it is a load instruction with range metadata, use it.
9329 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
9330 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
9331 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
9332 return;
9333 }
9334
9335 // We can work with PHI and select instruction as we traverse their operands
9336 // during update.
9337 if (isa<SelectInst>(V) || isa<PHINode>(V))
9338 return;
9339
9340 // Otherwise we give up.
9341 indicatePessimisticFixpoint();
9342
9343 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
9344 << getAssociatedValue() << "\n");
9345 }
9346
9347 bool calculateBinaryOperator(
9349 const Instruction *CtxI,
9351 Value *LHS = BinOp->getOperand(0);
9352 Value *RHS = BinOp->getOperand(1);
9353
9354 // Simplify the operands first.
9355 bool UsedAssumedInformation = false;
9356 const auto &SimplifiedLHS = A.getAssumedSimplified(
9357 IRPosition::value(*LHS, getCallBaseContext()), *this,
9358 UsedAssumedInformation, AA::Interprocedural);
9359 if (!SimplifiedLHS.has_value())
9360 return true;
9361 if (!*SimplifiedLHS)
9362 return false;
9363 LHS = *SimplifiedLHS;
9364
9365 const auto &SimplifiedRHS = A.getAssumedSimplified(
9366 IRPosition::value(*RHS, getCallBaseContext()), *this,
9367 UsedAssumedInformation, AA::Interprocedural);
9368 if (!SimplifiedRHS.has_value())
9369 return true;
9370 if (!*SimplifiedRHS)
9371 return false;
9372 RHS = *SimplifiedRHS;
9373
9374 // TODO: Allow non integers as well.
9375 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9376 return false;
9377
9378 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9379 *this, IRPosition::value(*LHS, getCallBaseContext()),
9380 DepClassTy::REQUIRED);
9381 if (!LHSAA)
9382 return false;
9383 QuerriedAAs.push_back(LHSAA);
9384 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9385
9386 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9387 *this, IRPosition::value(*RHS, getCallBaseContext()),
9388 DepClassTy::REQUIRED);
9389 if (!RHSAA)
9390 return false;
9391 QuerriedAAs.push_back(RHSAA);
9392 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9393
9394 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
9395
9396 T.unionAssumed(AssumedRange);
9397
9398 // TODO: Track a known state too.
9399
9400 return T.isValidState();
9401 }
9402
9403 bool calculateCastInst(
9405 const Instruction *CtxI,
9407 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
9408 // TODO: Allow non integers as well.
9409 Value *OpV = CastI->getOperand(0);
9410
9411 // Simplify the operand first.
9412 bool UsedAssumedInformation = false;
9413 const auto &SimplifiedOpV = A.getAssumedSimplified(
9414 IRPosition::value(*OpV, getCallBaseContext()), *this,
9415 UsedAssumedInformation, AA::Interprocedural);
9416 if (!SimplifiedOpV.has_value())
9417 return true;
9418 if (!*SimplifiedOpV)
9419 return false;
9420 OpV = *SimplifiedOpV;
9421
9422 if (!OpV->getType()->isIntegerTy())
9423 return false;
9424
9425 auto *OpAA = A.getAAFor<AAValueConstantRange>(
9426 *this, IRPosition::value(*OpV, getCallBaseContext()),
9427 DepClassTy::REQUIRED);
9428 if (!OpAA)
9429 return false;
9430 QuerriedAAs.push_back(OpAA);
9431 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(),
9432 getState().getBitWidth()));
9433 return T.isValidState();
9434 }
9435
9436 bool
9437 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
9438 const Instruction *CtxI,
9440 Value *LHS = CmpI->getOperand(0);
9441 Value *RHS = CmpI->getOperand(1);
9442
9443 // Simplify the operands first.
9444 bool UsedAssumedInformation = false;
9445 const auto &SimplifiedLHS = A.getAssumedSimplified(
9446 IRPosition::value(*LHS, getCallBaseContext()), *this,
9447 UsedAssumedInformation, AA::Interprocedural);
9448 if (!SimplifiedLHS.has_value())
9449 return true;
9450 if (!*SimplifiedLHS)
9451 return false;
9452 LHS = *SimplifiedLHS;
9453
9454 const auto &SimplifiedRHS = A.getAssumedSimplified(
9455 IRPosition::value(*RHS, getCallBaseContext()), *this,
9456 UsedAssumedInformation, AA::Interprocedural);
9457 if (!SimplifiedRHS.has_value())
9458 return true;
9459 if (!*SimplifiedRHS)
9460 return false;
9461 RHS = *SimplifiedRHS;
9462
9463 // TODO: Allow non integers as well.
9464 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
9465 return false;
9466
9467 auto *LHSAA = A.getAAFor<AAValueConstantRange>(
9468 *this, IRPosition::value(*LHS, getCallBaseContext()),
9469 DepClassTy::REQUIRED);
9470 if (!LHSAA)
9471 return false;
9472 QuerriedAAs.push_back(LHSAA);
9473 auto *RHSAA = A.getAAFor<AAValueConstantRange>(
9474 *this, IRPosition::value(*RHS, getCallBaseContext()),
9475 DepClassTy::REQUIRED);
9476 if (!RHSAA)
9477 return false;
9478 QuerriedAAs.push_back(RHSAA);
9479 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI);
9480 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI);
9481
9482 // If one of them is empty set, we can't decide.
9483 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
9484 return true;
9485
9486 bool MustTrue = false, MustFalse = false;
9487
9488 auto AllowedRegion =
9490
9491 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
9492 MustFalse = true;
9493
9494 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange))
9495 MustTrue = true;
9496
9497 assert((!MustTrue || !MustFalse) &&
9498 "Either MustTrue or MustFalse should be false!");
9499
9500 if (MustTrue)
9501 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
9502 else if (MustFalse)
9503 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
9504 else
9505 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
9506
9507 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after "
9508 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown"))
9509 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t"
9510 << *RHSAA);
9511
9512 // TODO: Track a known state too.
9513 return T.isValidState();
9514 }
9515
9516 /// See AbstractAttribute::updateImpl(...).
9517 ChangeStatus updateImpl(Attributor &A) override {
9518
9520 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
9521 Instruction *I = dyn_cast<Instruction>(&V);
9522 if (!I || isa<CallBase>(I)) {
9523
9524 // Simplify the operand first.
9525 bool UsedAssumedInformation = false;
9526 const auto &SimplifiedOpV = A.getAssumedSimplified(
9527 IRPosition::value(V, getCallBaseContext()), *this,
9528 UsedAssumedInformation, AA::Interprocedural);
9529 if (!SimplifiedOpV.has_value())
9530 return true;
9531 if (!*SimplifiedOpV)
9532 return false;
9533 Value *VPtr = *SimplifiedOpV;
9534
9535 // If the value is not instruction, we query AA to Attributor.
9536 const auto *AA = A.getAAFor<AAValueConstantRange>(
9537 *this, IRPosition::value(*VPtr, getCallBaseContext()),
9538 DepClassTy::REQUIRED);
9539
9540 // Clamp operator is not used to utilize a program point CtxI.
9541 if (AA)
9542 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI));
9543 else
9544 return false;
9545
9546 return T.isValidState();
9547 }
9548
9550 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
9551 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
9552 return false;
9553 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
9554 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
9555 return false;
9556 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
9557 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
9558 return false;
9559 } else {
9560 // Give up with other instructions.
9561 // TODO: Add other instructions
9562
9563 T.indicatePessimisticFixpoint();
9564 return false;
9565 }
9566
9567 // Catch circular reasoning in a pessimistic way for now.
9568 // TODO: Check how the range evolves and if we stripped anything, see also
9569 // AADereferenceable or AAAlign for similar situations.
9570 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
9571 if (QueriedAA != this)
9572 continue;
9573 // If we are in a stady state we do not need to worry.
9574 if (T.getAssumed() == getState().getAssumed())
9575 continue;
9576 T.indicatePessimisticFixpoint();
9577 }
9578
9579 return T.isValidState();
9580 };
9581
9582 if (!VisitValueCB(getAssociatedValue(), getCtxI()))
9583 return indicatePessimisticFixpoint();
9584
9585 // Ensure that long def-use chains can't cause circular reasoning either by
9586 // introducing a cutoff below.
9587 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED)
9588 return ChangeStatus::UNCHANGED;
9589 if (++NumChanges > MaxNumChanges) {
9590 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges
9591 << " but only " << MaxNumChanges
9592 << " are allowed to avoid cyclic reasoning.");
9593 return indicatePessimisticFixpoint();
9594 }
9595 return ChangeStatus::CHANGED;
9596 }
9597
9598 /// See AbstractAttribute::trackStatistics()
9599 void trackStatistics() const override {
9601 }
9602
9603 /// Tracker to bail after too many widening steps of the constant range.
9604 int NumChanges = 0;
9605
9606 /// Upper bound for the number of allowed changes (=widening steps) for the
9607 /// constant range before we give up.
9608 static constexpr int MaxNumChanges = 5;
9609};
9610
9611struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
9612 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A)
9613 : AAValueConstantRangeImpl(IRP, A) {}
9614
9615 /// See AbstractAttribute::initialize(...).
9616 ChangeStatus updateImpl(Attributor &A) override {
9617 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
9618 "not be called");
9619 }
9620
9621 /// See AbstractAttribute::trackStatistics()
9622 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
9623};
9624
9625struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
9626 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A)
9627 : AAValueConstantRangeFunction(IRP, A) {}
9628
9629 /// See AbstractAttribute::trackStatistics()
9630 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
9631};
9632
9633struct AAValueConstantRangeCallSiteReturned
9634 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9635 AAValueConstantRangeImpl::StateType,
9636 /* IntroduceCallBaseContext */ true> {
9637 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A)
9638 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl,
9639 AAValueConstantRangeImpl::StateType,
9640 /* IntroduceCallBaseContext */ true>(IRP, A) {}
9641
9642 /// See AbstractAttribute::initialize(...).
9643 void initialize(Attributor &A) override {
9644 // If it is a call instruction with range attribute, use the range.
9645 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) {
9646 if (std::optional<ConstantRange> Range = CI->getRange())
9647 intersectKnown(*Range);
9648 }
9649
9650 AAValueConstantRangeImpl::initialize(A);
9651 }
9652
9653 /// See AbstractAttribute::trackStatistics()
9654 void trackStatistics() const override {
9655 STATS_DECLTRACK_CSRET_ATTR(value_range)
9656 }
9657};
9658struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
9659 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
9660 : AAValueConstantRangeFloating(IRP, A) {}
9661
9662 /// See AbstractAttribute::manifest()
9663 ChangeStatus manifest(Attributor &A) override {
9664 return ChangeStatus::UNCHANGED;
9665 }
9666
9667 /// See AbstractAttribute::trackStatistics()
9668 void trackStatistics() const override {
9669 STATS_DECLTRACK_CSARG_ATTR(value_range)
9670 }
9671};
9672} // namespace
9673
9674/// ------------------ Potential Values Attribute -------------------------
9675
9676namespace {
9677struct AAPotentialConstantValuesImpl : AAPotentialConstantValues {
9678 using StateType = PotentialConstantIntValuesState;
9679
9680 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A)
9681 : AAPotentialConstantValues(IRP, A) {}
9682
9683 /// See AbstractAttribute::initialize(..).
9684 void initialize(Attributor &A) override {
9685 if (A.hasSimplificationCallback(getIRPosition()))
9686 indicatePessimisticFixpoint();
9687 else
9688 AAPotentialConstantValues::initialize(A);
9689 }
9690
9691 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S,
9692 bool &ContainsUndef, bool ForSelf) {
9694 bool UsedAssumedInformation = false;
9695 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural,
9696 UsedAssumedInformation)) {
9697 // Avoid recursion when the caller is computing constant values for this
9698 // IRP itself.
9699 if (ForSelf)
9700 return false;
9701 if (!IRP.getAssociatedType()->isIntegerTy())
9702 return false;
9703 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>(
9704 *this, IRP, DepClassTy::REQUIRED);
9705 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState())
9706 return false;
9707 ContainsUndef = PotentialValuesAA->getState().undefIsContained();
9708 S = PotentialValuesAA->getState().getAssumedSet();
9709 return true;
9710 }
9711
9712 // Copy all the constant values, except UndefValue. ContainsUndef is true
9713 // iff Values contains only UndefValue instances. If there are other known
9714 // constants, then UndefValue is dropped.
9715 ContainsUndef = false;
9716 for (auto &It : Values) {
9717 if (isa<UndefValue>(It.getValue())) {
9718 ContainsUndef = true;
9719 continue;
9720 }
9721 auto *CI = dyn_cast<ConstantInt>(It.getValue());
9722 if (!CI)
9723 return false;
9724 S.insert(CI->getValue());
9725 }
9726 ContainsUndef &= S.empty();
9727
9728 return true;
9729 }
9730
9731 /// See AbstractAttribute::getAsStr().
9732 const std::string getAsStr(Attributor *A) const override {
9733 std::string Str;
9735 OS << getState();
9736 return Str;
9737 }
9738
9739 /// See AbstractAttribute::updateImpl(...).
9740 ChangeStatus updateImpl(Attributor &A) override {
9741 return indicatePessimisticFixpoint();
9742 }
9743};
9744
9745struct AAPotentialConstantValuesArgument final
9746 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9747 AAPotentialConstantValuesImpl,
9748 PotentialConstantIntValuesState> {
9749 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues,
9750 AAPotentialConstantValuesImpl,
9752 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A)
9753 : Base(IRP, A) {}
9754
9755 /// See AbstractAttribute::trackStatistics()
9756 void trackStatistics() const override {
9757 STATS_DECLTRACK_ARG_ATTR(potential_values)
9758 }
9759};
9760
9761struct AAPotentialConstantValuesReturned
9762 : AAReturnedFromReturnedValues<AAPotentialConstantValues,
9763 AAPotentialConstantValuesImpl> {
9764 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues,
9765 AAPotentialConstantValuesImpl>;
9766 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A)
9767 : Base(IRP, A) {}
9768
9769 void initialize(Attributor &A) override {
9770 if (!A.isFunctionIPOAmendable(*getAssociatedFunction()))
9771 indicatePessimisticFixpoint();
9772 Base::initialize(A);
9773 }
9774
9775 /// See AbstractAttribute::trackStatistics()
9776 void trackStatistics() const override {
9777 STATS_DECLTRACK_FNRET_ATTR(potential_values)
9778 }
9779};
9780
9781struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl {
9782 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A)
9783 : AAPotentialConstantValuesImpl(IRP, A) {}
9784
9785 /// See AbstractAttribute::initialize(..).
9786 void initialize(Attributor &A) override {
9787 AAPotentialConstantValuesImpl::initialize(A);
9788 if (isAtFixpoint())
9789 return;
9790
9791 Value &V = getAssociatedValue();
9792
9793 if (auto *C = dyn_cast<ConstantInt>(&V)) {
9794 unionAssumed(C->getValue());
9795 indicateOptimisticFixpoint();
9796 return;
9797 }
9798
9799 if (isa<UndefValue>(&V)) {
9800 unionAssumedWithUndef();
9801 indicateOptimisticFixpoint();
9802 return;
9803 }
9804
9805 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V))
9806 return;
9807
9808 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V))
9809 return;
9810
9811 indicatePessimisticFixpoint();
9812
9813 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: "
9814 << getAssociatedValue() << "\n");
9815 }
9816
9817 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS,
9818 const APInt &RHS) {
9819 return ICmpInst::compare(LHS, RHS, ICI->getPredicate());
9820 }
9821
9822 static APInt calculateCastInst(const CastInst *CI, const APInt &Src,
9823 uint32_t ResultBitWidth) {
9824 Instruction::CastOps CastOp = CI->getOpcode();
9825 switch (CastOp) {
9826 default:
9827 llvm_unreachable("unsupported or not integer cast");
9828 case Instruction::Trunc:
9829 return Src.trunc(ResultBitWidth);
9830 case Instruction::SExt:
9831 return Src.sext(ResultBitWidth);
9832 case Instruction::ZExt:
9833 return Src.zext(ResultBitWidth);
9834 case Instruction::BitCast:
9835 return Src;
9836 }
9837 }
9838
9839 static APInt calculateBinaryOperator(const BinaryOperator *BinOp,
9840 const APInt &LHS, const APInt &RHS,
9841 bool &SkipOperation, bool &Unsupported) {
9842 Instruction::BinaryOps BinOpcode = BinOp->getOpcode();
9843 // Unsupported is set to true when the binary operator is not supported.
9844 // SkipOperation is set to true when UB occur with the given operand pair
9845 // (LHS, RHS).
9846 // TODO: we should look at nsw and nuw keywords to handle operations
9847 // that create poison or undef value.
9848 switch (BinOpcode) {
9849 default:
9850 Unsupported = true;
9851 return LHS;
9852 case Instruction::Add:
9853 return LHS + RHS;
9854 case Instruction::Sub:
9855 return LHS - RHS;
9856 case Instruction::Mul:
9857 return LHS * RHS;
9858 case Instruction::UDiv:
9859 if (RHS.isZero()) {
9860 SkipOperation = true;
9861 return LHS;
9862 }
9863 return LHS.udiv(RHS);
9864 case Instruction::SDiv:
9865 if (RHS.isZero()) {
9866 SkipOperation = true;
9867 return LHS;
9868 }
9869 return LHS.sdiv(RHS);
9870 case Instruction::URem:
9871 if (RHS.isZero()) {
9872 SkipOperation = true;
9873 return LHS;
9874 }
9875 return LHS.urem(RHS);
9876 case Instruction::SRem:
9877 if (RHS.isZero()) {
9878 SkipOperation = true;
9879 return LHS;
9880 }
9881 return LHS.srem(RHS);
9882 case Instruction::Shl:
9883 return LHS.shl(RHS);
9884 case Instruction::LShr:
9885 return LHS.lshr(RHS);
9886 case Instruction::AShr:
9887 return LHS.ashr(RHS);
9888 case Instruction::And:
9889 return LHS & RHS;
9890 case Instruction::Or:
9891 return LHS | RHS;
9892 case Instruction::Xor:
9893 return LHS ^ RHS;
9894 }
9895 }
9896
9897 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp,
9898 const APInt &LHS, const APInt &RHS) {
9899 bool SkipOperation = false;
9900 bool Unsupported = false;
9901 APInt Result =
9902 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported);
9903 if (Unsupported)
9904 return false;
9905 // If SkipOperation is true, we can ignore this operand pair (L, R).
9906 if (!SkipOperation)
9907 unionAssumed(Result);
9908 return isValidState();
9909 }
9910
9911 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) {
9912 auto AssumedBefore = getAssumed();
9913 Value *LHS = ICI->getOperand(0);
9914 Value *RHS = ICI->getOperand(1);
9915
9916 bool LHSContainsUndef = false, RHSContainsUndef = false;
9917 SetTy LHSAAPVS, RHSAAPVS;
9918 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9919 LHSContainsUndef, /* ForSelf */ false) ||
9920 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9921 RHSContainsUndef, /* ForSelf */ false))
9922 return indicatePessimisticFixpoint();
9923
9924 // TODO: make use of undef flag to limit potential values aggressively.
9925 bool MaybeTrue = false, MaybeFalse = false;
9926 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0);
9927 if (LHSContainsUndef && RHSContainsUndef) {
9928 // The result of any comparison between undefs can be soundly replaced
9929 // with undef.
9930 unionAssumedWithUndef();
9931 } else if (LHSContainsUndef) {
9932 for (const APInt &R : RHSAAPVS) {
9933 bool CmpResult = calculateICmpInst(ICI, Zero, R);
9934 MaybeTrue |= CmpResult;
9935 MaybeFalse |= !CmpResult;
9936 if (MaybeTrue & MaybeFalse)
9937 return indicatePessimisticFixpoint();
9938 }
9939 } else if (RHSContainsUndef) {
9940 for (const APInt &L : LHSAAPVS) {
9941 bool CmpResult = calculateICmpInst(ICI, L, Zero);
9942 MaybeTrue |= CmpResult;
9943 MaybeFalse |= !CmpResult;
9944 if (MaybeTrue & MaybeFalse)
9945 return indicatePessimisticFixpoint();
9946 }
9947 } else {
9948 for (const APInt &L : LHSAAPVS) {
9949 for (const APInt &R : RHSAAPVS) {
9950 bool CmpResult = calculateICmpInst(ICI, L, R);
9951 MaybeTrue |= CmpResult;
9952 MaybeFalse |= !CmpResult;
9953 if (MaybeTrue & MaybeFalse)
9954 return indicatePessimisticFixpoint();
9955 }
9956 }
9957 }
9958 if (MaybeTrue)
9959 unionAssumed(APInt(/* numBits */ 1, /* val */ 1));
9960 if (MaybeFalse)
9961 unionAssumed(APInt(/* numBits */ 1, /* val */ 0));
9962 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
9963 : ChangeStatus::CHANGED;
9964 }
9965
9966 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) {
9967 auto AssumedBefore = getAssumed();
9968 Value *LHS = SI->getTrueValue();
9969 Value *RHS = SI->getFalseValue();
9970
9971 bool UsedAssumedInformation = false;
9972 std::optional<Constant *> C = A.getAssumedConstant(
9973 *SI->getCondition(), *this, UsedAssumedInformation);
9974
9975 // Check if we only need one operand.
9976 bool OnlyLeft = false, OnlyRight = false;
9977 if (C && *C && (*C)->isOneValue())
9978 OnlyLeft = true;
9979 else if (C && *C && (*C)->isZeroValue())
9980 OnlyRight = true;
9981
9982 bool LHSContainsUndef = false, RHSContainsUndef = false;
9983 SetTy LHSAAPVS, RHSAAPVS;
9984 if (!OnlyRight &&
9985 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
9986 LHSContainsUndef, /* ForSelf */ false))
9987 return indicatePessimisticFixpoint();
9988
9989 if (!OnlyLeft &&
9990 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
9991 RHSContainsUndef, /* ForSelf */ false))
9992 return indicatePessimisticFixpoint();
9993
9994 if (OnlyLeft || OnlyRight) {
9995 // select (true/false), lhs, rhs
9996 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS;
9997 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef;
9998
9999 if (Undef)
10000 unionAssumedWithUndef();
10001 else {
10002 for (const auto &It : *OpAA)
10003 unionAssumed(It);
10004 }
10005
10006 } else if (LHSContainsUndef && RHSContainsUndef) {
10007 // select i1 *, undef , undef => undef
10008 unionAssumedWithUndef();
10009 } else {
10010 for (const auto &It : LHSAAPVS)
10011 unionAssumed(It);
10012 for (const auto &It : RHSAAPVS)
10013 unionAssumed(It);
10014 }
10015 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10016 : ChangeStatus::CHANGED;
10017 }
10018
10019 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) {
10020 auto AssumedBefore = getAssumed();
10021 if (!CI->isIntegerCast())
10022 return indicatePessimisticFixpoint();
10023 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!");
10024 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth();
10025 Value *Src = CI->getOperand(0);
10026
10027 bool SrcContainsUndef = false;
10028 SetTy SrcPVS;
10029 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS,
10030 SrcContainsUndef, /* ForSelf */ false))
10031 return indicatePessimisticFixpoint();
10032
10033 if (SrcContainsUndef)
10034 unionAssumedWithUndef();
10035 else {
10036 for (const APInt &S : SrcPVS) {
10037 APInt T = calculateCastInst(CI, S, ResultBitWidth);
10038 unionAssumed(T);
10039 }
10040 }
10041 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10042 : ChangeStatus::CHANGED;
10043 }
10044
10045 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) {
10046 auto AssumedBefore = getAssumed();
10047 Value *LHS = BinOp->getOperand(0);
10048 Value *RHS = BinOp->getOperand(1);
10049
10050 bool LHSContainsUndef = false, RHSContainsUndef = false;
10051 SetTy LHSAAPVS, RHSAAPVS;
10052 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS,
10053 LHSContainsUndef, /* ForSelf */ false) ||
10054 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS,
10055 RHSContainsUndef, /* ForSelf */ false))
10056 return indicatePessimisticFixpoint();
10057
10058 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0);
10059
10060 // TODO: make use of undef flag to limit potential values aggressively.
10061 if (LHSContainsUndef && RHSContainsUndef) {
10062 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero))
10063 return indicatePessimisticFixpoint();
10064 } else if (LHSContainsUndef) {
10065 for (const APInt &R : RHSAAPVS) {
10066 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R))
10067 return indicatePessimisticFixpoint();
10068 }
10069 } else if (RHSContainsUndef) {
10070 for (const APInt &L : LHSAAPVS) {
10071 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero))
10072 return indicatePessimisticFixpoint();
10073 }
10074 } else {
10075 for (const APInt &L : LHSAAPVS) {
10076 for (const APInt &R : RHSAAPVS) {
10077 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R))
10078 return indicatePessimisticFixpoint();
10079 }
10080 }
10081 }
10082 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10083 : ChangeStatus::CHANGED;
10084 }
10085
10086 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) {
10087 auto AssumedBefore = getAssumed();
10088 SetTy Incoming;
10089 bool ContainsUndef;
10090 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming,
10091 ContainsUndef, /* ForSelf */ true))
10092 return indicatePessimisticFixpoint();
10093 if (ContainsUndef) {
10094 unionAssumedWithUndef();
10095 } else {
10096 for (const auto &It : Incoming)
10097 unionAssumed(It);
10098 }
10099 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10100 : ChangeStatus::CHANGED;
10101 }
10102
10103 /// See AbstractAttribute::updateImpl(...).
10104 ChangeStatus updateImpl(Attributor &A) override {
10105 Value &V = getAssociatedValue();
10106 Instruction *I = dyn_cast<Instruction>(&V);
10107
10108 if (auto *ICI = dyn_cast<ICmpInst>(I))
10109 return updateWithICmpInst(A, ICI);
10110
10111 if (auto *SI = dyn_cast<SelectInst>(I))
10112 return updateWithSelectInst(A, SI);
10113
10114 if (auto *CI = dyn_cast<CastInst>(I))
10115 return updateWithCastInst(A, CI);
10116
10117 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
10118 return updateWithBinaryOperator(A, BinOp);
10119
10120 if (isa<PHINode>(I) || isa<LoadInst>(I))
10121 return updateWithInstruction(A, I);
10122
10123 return indicatePessimisticFixpoint();
10124 }
10125
10126 /// See AbstractAttribute::trackStatistics()
10127 void trackStatistics() const override {
10128 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
10129 }
10130};
10131
10132struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl {
10133 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A)
10134 : AAPotentialConstantValuesImpl(IRP, A) {}
10135
10136 /// See AbstractAttribute::initialize(...).
10137 ChangeStatus updateImpl(Attributor &A) override {
10139 "AAPotentialConstantValues(Function|CallSite)::updateImpl will "
10140 "not be called");
10141 }
10142
10143 /// See AbstractAttribute::trackStatistics()
10144 void trackStatistics() const override {
10145 STATS_DECLTRACK_FN_ATTR(potential_values)
10146 }
10147};
10148
10149struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction {
10150 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A)
10151 : AAPotentialConstantValuesFunction(IRP, A) {}
10152
10153 /// See AbstractAttribute::trackStatistics()
10154 void trackStatistics() const override {
10155 STATS_DECLTRACK_CS_ATTR(potential_values)
10156 }
10157};
10158
10159struct AAPotentialConstantValuesCallSiteReturned
10160 : AACalleeToCallSite<AAPotentialConstantValues,
10161 AAPotentialConstantValuesImpl> {
10162 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP,
10163 Attributor &A)
10164 : AACalleeToCallSite<AAPotentialConstantValues,
10165 AAPotentialConstantValuesImpl>(IRP, A) {}
10166
10167 /// See AbstractAttribute::trackStatistics()
10168 void trackStatistics() const override {
10169 STATS_DECLTRACK_CSRET_ATTR(potential_values)
10170 }
10171};
10172
10173struct AAPotentialConstantValuesCallSiteArgument
10174 : AAPotentialConstantValuesFloating {
10175 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP,
10176 Attributor &A)
10177 : AAPotentialConstantValuesFloating(IRP, A) {}
10178
10179 /// See AbstractAttribute::initialize(..).
10180 void initialize(Attributor &A) override {
10181 AAPotentialConstantValuesImpl::initialize(A);
10182 if (isAtFixpoint())
10183 return;
10184
10185 Value &V = getAssociatedValue();
10186
10187 if (auto *C = dyn_cast<ConstantInt>(&V)) {
10188 unionAssumed(C->getValue());
10189 indicateOptimisticFixpoint();
10190 return;
10191 }
10192
10193 if (isa<UndefValue>(&V)) {
10194 unionAssumedWithUndef();
10195 indicateOptimisticFixpoint();
10196 return;
10197 }
10198 }
10199
10200 /// See AbstractAttribute::updateImpl(...).
10201 ChangeStatus updateImpl(Attributor &A) override {
10202 Value &V = getAssociatedValue();
10203 auto AssumedBefore = getAssumed();
10204 auto *AA = A.getAAFor<AAPotentialConstantValues>(
10205 *this, IRPosition::value(V), DepClassTy::REQUIRED);
10206 if (!AA)
10207 return indicatePessimisticFixpoint();
10208 const auto &S = AA->getAssumed();
10209 unionAssumed(S);
10210 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED
10211 : ChangeStatus::CHANGED;
10212 }
10213
10214 /// See AbstractAttribute::trackStatistics()
10215 void trackStatistics() const override {
10216 STATS_DECLTRACK_CSARG_ATTR(potential_values)
10217 }
10218};
10219} // namespace
10220
10221/// ------------------------ NoUndef Attribute ---------------------------------
10223 Attribute::AttrKind ImpliedAttributeKind,
10224 bool IgnoreSubsumingPositions) {
10225 assert(ImpliedAttributeKind == Attribute::NoUndef &&
10226 "Unexpected attribute kind");
10227 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions,
10228 Attribute::NoUndef))
10229 return true;
10230
10231 Value &Val = IRP.getAssociatedValue();
10234 LLVMContext &Ctx = Val.getContext();
10235 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef));
10236 return true;
10237 }
10238
10239 return false;
10240}
10241
10242namespace {
10243struct AANoUndefImpl : AANoUndef {
10244 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {}
10245
10246 /// See AbstractAttribute::initialize(...).
10247 void initialize(Attributor &A) override {
10248 Value &V = getAssociatedValue();
10249 if (isa<UndefValue>(V))
10250 indicatePessimisticFixpoint();
10251 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef));
10252 }
10253
10254 /// See followUsesInMBEC
10255 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10256 AANoUndef::StateType &State) {
10257 const Value *UseV = U->get();
10258 const DominatorTree *DT = nullptr;
10259 AssumptionCache *AC = nullptr;
10260 InformationCache &InfoCache = A.getInfoCache();
10261 if (Function *F = getAnchorScope()) {
10264 }
10265 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT));
10266 bool TrackUse = false;
10267 // Track use for instructions which must produce undef or poison bits when
10268 // at least one operand contains such bits.
10269 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I))
10270 TrackUse = true;
10271 return TrackUse;
10272 }
10273
10274 /// See AbstractAttribute::getAsStr().
10275 const std::string getAsStr(Attributor *A) const override {
10276 return getAssumed() ? "noundef" : "may-undef-or-poison";
10277 }
10278
10279 ChangeStatus manifest(Attributor &A) override {
10280 // We don't manifest noundef attribute for dead positions because the
10281 // associated values with dead positions would be replaced with undef
10282 // values.
10283 bool UsedAssumedInformation = false;
10284 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
10285 UsedAssumedInformation))
10286 return ChangeStatus::UNCHANGED;
10287 // A position whose simplified value does not have any value is
10288 // considered to be dead. We don't manifest noundef in such positions for
10289 // the same reason above.
10290 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation,
10292 .has_value())
10293 return ChangeStatus::UNCHANGED;
10294 return AANoUndef::manifest(A);
10295 }
10296};
10297
10298struct AANoUndefFloating : public AANoUndefImpl {
10299 AANoUndefFloating(const IRPosition &IRP, Attributor &A)
10300 : AANoUndefImpl(IRP, A) {}
10301
10302 /// See AbstractAttribute::initialize(...).
10303 void initialize(Attributor &A) override {
10304 AANoUndefImpl::initialize(A);
10305 if (!getState().isAtFixpoint() && getAnchorScope() &&
10306 !getAnchorScope()->isDeclaration())
10307 if (Instruction *CtxI = getCtxI())
10308 followUsesInMBEC(*this, A, getState(), *CtxI);
10309 }
10310
10311 /// See AbstractAttribute::updateImpl(...).
10312 ChangeStatus updateImpl(Attributor &A) override {
10313 auto VisitValueCB = [&](const IRPosition &IRP) -> bool {
10314 bool IsKnownNoUndef;
10315 return AA::hasAssumedIRAttr<Attribute::NoUndef>(
10316 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef);
10317 };
10318
10319 bool Stripped;
10320 bool UsedAssumedInformation = false;
10321 Value *AssociatedValue = &getAssociatedValue();
10323 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10324 AA::AnyScope, UsedAssumedInformation))
10325 Stripped = false;
10326 else
10327 Stripped =
10328 Values.size() != 1 || Values.front().getValue() != AssociatedValue;
10329
10330 if (!Stripped) {
10331 // If we haven't stripped anything we might still be able to use a
10332 // different AA, but only if the IRP changes. Effectively when we
10333 // interpret this not as a call site value but as a floating/argument
10334 // value.
10335 const IRPosition AVIRP = IRPosition::value(*AssociatedValue);
10336 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP))
10337 return indicatePessimisticFixpoint();
10338 return ChangeStatus::UNCHANGED;
10339 }
10340
10341 for (const auto &VAC : Values)
10342 if (!VisitValueCB(IRPosition::value(*VAC.getValue())))
10343 return indicatePessimisticFixpoint();
10344
10345 return ChangeStatus::UNCHANGED;
10346 }
10347
10348 /// See AbstractAttribute::trackStatistics()
10349 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10350};
10351
10352struct AANoUndefReturned final
10353 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> {
10354 AANoUndefReturned(const IRPosition &IRP, Attributor &A)
10355 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {}
10356
10357 /// See AbstractAttribute::trackStatistics()
10358 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) }
10359};
10360
10361struct AANoUndefArgument final
10362 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> {
10363 AANoUndefArgument(const IRPosition &IRP, Attributor &A)
10364 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {}
10365
10366 /// See AbstractAttribute::trackStatistics()
10367 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) }
10368};
10369
10370struct AANoUndefCallSiteArgument final : AANoUndefFloating {
10371 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A)
10372 : AANoUndefFloating(IRP, A) {}
10373
10374 /// See AbstractAttribute::trackStatistics()
10375 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) }
10376};
10377
10378struct AANoUndefCallSiteReturned final
10379 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> {
10380 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A)
10381 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {}
10382
10383 /// See AbstractAttribute::trackStatistics()
10384 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) }
10385};
10386
10387/// ------------------------ NoFPClass Attribute -------------------------------
10388
10389struct AANoFPClassImpl : AANoFPClass {
10390 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {}
10391
10392 void initialize(Attributor &A) override {
10393 const IRPosition &IRP = getIRPosition();
10394
10395 Value &V = IRP.getAssociatedValue();
10396 if (isa<UndefValue>(V)) {
10397 indicateOptimisticFixpoint();
10398 return;
10399 }
10400
10402 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false);
10403 for (const auto &Attr : Attrs) {
10404 addKnownBits(Attr.getNoFPClass());
10405 }
10406
10407 const DataLayout &DL = A.getDataLayout();
10408 if (getPositionKind() != IRPosition::IRP_RETURNED) {
10410 addKnownBits(~KnownFPClass.KnownFPClasses);
10411 }
10412
10413 if (Instruction *CtxI = getCtxI())
10414 followUsesInMBEC(*this, A, getState(), *CtxI);
10415 }
10416
10417 /// See followUsesInMBEC
10418 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I,
10419 AANoFPClass::StateType &State) {
10420 // TODO: Determine what instructions can be looked through.
10421 auto *CB = dyn_cast<CallBase>(I);
10422 if (!CB)
10423 return false;
10424
10425 if (!CB->isArgOperand(U))
10426 return false;
10427
10428 unsigned ArgNo = CB->getArgOperandNo(U);
10429 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo);
10430 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE))
10431 State.addKnownBits(NoFPAA->getState().getKnown());
10432 return false;
10433 }
10434
10435 const std::string getAsStr(Attributor *A) const override {
10436 std::string Result = "nofpclass";
10437 raw_string_ostream OS(Result);
10438 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass();
10439 return Result;
10440 }
10441
10442 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx,
10443 SmallVectorImpl<Attribute> &Attrs) const override {
10444 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass()));
10445 }
10446};
10447
10448struct AANoFPClassFloating : public AANoFPClassImpl {
10449 AANoFPClassFloating(const IRPosition &IRP, Attributor &A)
10450 : AANoFPClassImpl(IRP, A) {}
10451
10452 /// See AbstractAttribute::updateImpl(...).
10453 ChangeStatus updateImpl(Attributor &A) override {
10455 bool UsedAssumedInformation = false;
10456 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values,
10457 AA::AnyScope, UsedAssumedInformation)) {
10458 Values.push_back({getAssociatedValue(), getCtxI()});
10459 }
10460
10461 StateType T;
10462 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool {
10463 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V),
10464 DepClassTy::REQUIRED);
10465 if (!AA || this == AA) {
10466 T.indicatePessimisticFixpoint();
10467 } else {
10468 const AANoFPClass::StateType &S =
10469 static_cast<const AANoFPClass::StateType &>(AA->getState());
10470 T ^= S;
10471 }
10472 return T.isValidState();
10473 };
10474
10475 for (const auto &VAC : Values)
10476 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI()))
10477 return indicatePessimisticFixpoint();
10478
10479 return clampStateAndIndicateChange(getState(), T);
10480 }
10481
10482 /// See AbstractAttribute::trackStatistics()
10483 void trackStatistics() const override {
10485 }
10486};
10487
10488struct AANoFPClassReturned final
10489 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10490 AANoFPClassImpl::StateType, false,
10491 Attribute::None, false> {
10492 AANoFPClassReturned(const IRPosition &IRP, Attributor &A)
10493 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl,
10494 AANoFPClassImpl::StateType, false,
10495 Attribute::None, false>(IRP, A) {}
10496
10497 /// See AbstractAttribute::trackStatistics()
10498 void trackStatistics() const override {
10500 }
10501};
10502
10503struct AANoFPClassArgument final
10504 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> {
10505 AANoFPClassArgument(const IRPosition &IRP, Attributor &A)
10506 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10507
10508 /// See AbstractAttribute::trackStatistics()
10509 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) }
10510};
10511
10512struct AANoFPClassCallSiteArgument final : AANoFPClassFloating {
10513 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A)
10514 : AANoFPClassFloating(IRP, A) {}
10515
10516 /// See AbstractAttribute::trackStatistics()
10517 void trackStatistics() const override {
10519 }
10520};
10521
10522struct AANoFPClassCallSiteReturned final
10523 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> {
10524 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A)
10525 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {}
10526
10527 /// See AbstractAttribute::trackStatistics()
10528 void trackStatistics() const override {
10530 }
10531};
10532
10533struct AACallEdgesImpl : public AACallEdges {
10534 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {}
10535
10536 const SetVector<Function *> &getOptimisticEdges() const override {
10537 return CalledFunctions;
10538 }
10539
10540 bool hasUnknownCallee() const override { return HasUnknownCallee; }
10541
10542 bool hasNonAsmUnknownCallee() const override {
10543 return HasUnknownCalleeNonAsm;
10544 }
10545
10546 const std::string getAsStr(Attributor *A) const override {
10547 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," +
10548 std::to_string(CalledFunctions.size()) + "]";
10549 }
10550
10551 void trackStatistics() const override {}
10552
10553protected:
10554 void addCalledFunction(Function *Fn, ChangeStatus &Change) {
10555 if (CalledFunctions.insert(Fn)) {
10556 Change = ChangeStatus::CHANGED;
10557 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName()
10558 << "\n");
10559 }
10560 }
10561
10562 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) {
10563 if (!HasUnknownCallee)
10564 Change = ChangeStatus::CHANGED;
10565 if (NonAsm && !HasUnknownCalleeNonAsm)
10566 Change = ChangeStatus::CHANGED;
10567 HasUnknownCalleeNonAsm |= NonAsm;
10568 HasUnknownCallee = true;
10569 }
10570
10571private:
10572 /// Optimistic set of functions that might be called by this position.
10573 SetVector<Function *> CalledFunctions;
10574
10575 /// Is there any call with a unknown callee.
10576 bool HasUnknownCallee = false;
10577
10578 /// Is there any call with a unknown callee, excluding any inline asm.
10579 bool HasUnknownCalleeNonAsm = false;
10580};
10581
10582struct AACallEdgesCallSite : public AACallEdgesImpl {
10583 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A)
10584 : AACallEdgesImpl(IRP, A) {}
10585 /// See AbstractAttribute::updateImpl(...).
10586 ChangeStatus updateImpl(Attributor &A) override {
10587 ChangeStatus Change = ChangeStatus::UNCHANGED;
10588
10589 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool {
10590 if (Function *Fn = dyn_cast<Function>(&V)) {
10591 addCalledFunction(Fn, Change);
10592 } else {
10593 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n");
10594 setHasUnknownCallee(true, Change);
10595 }
10596
10597 // Explore all values.
10598 return true;
10599 };
10600
10602 // Process any value that we might call.
10603 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) {
10604 if (isa<Constant>(V)) {
10605 VisitValue(*V, CtxI);
10606 return;
10607 }
10608
10609 bool UsedAssumedInformation = false;
10610 Values.clear();
10611 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values,
10612 AA::AnyScope, UsedAssumedInformation)) {
10613 Values.push_back({*V, CtxI});
10614 }
10615 for (auto &VAC : Values)
10616 VisitValue(*VAC.getValue(), VAC.getCtxI());
10617 };
10618
10619 CallBase *CB = cast<CallBase>(getCtxI());
10620
10621 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
10622 if (IA->hasSideEffects() &&
10623 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
10624 !hasAssumption(*CB, "ompx_no_call_asm")) {
10625 setHasUnknownCallee(false, Change);
10626 }
10627 return Change;
10628 }
10629
10630 if (CB->isIndirectCall())
10631 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>(
10632 *this, getIRPosition(), DepClassTy::OPTIONAL))
10633 if (IndirectCallAA->foreachCallee(
10634 [&](Function *Fn) { return VisitValue(*Fn, CB); }))
10635 return Change;
10636
10637 // The most simple case.
10638 ProcessCalledOperand(CB->getCalledOperand(), CB);
10639
10640 // Process callback functions.
10641 SmallVector<const Use *, 4u> CallbackUses;
10642 AbstractCallSite::getCallbackUses(*CB, CallbackUses);
10643 for (const Use *U : CallbackUses)
10644 ProcessCalledOperand(U->get(), CB);
10645
10646 return Change;
10647 }
10648};
10649
10650struct AACallEdgesFunction : public AACallEdgesImpl {
10651 AACallEdgesFunction(const IRPosition &IRP, Attributor &A)
10652 : AACallEdgesImpl(IRP, A) {}
10653
10654 /// See AbstractAttribute::updateImpl(...).
10655 ChangeStatus updateImpl(Attributor &A) override {
10656 ChangeStatus Change = ChangeStatus::UNCHANGED;
10657
10658 auto ProcessCallInst = [&](Instruction &Inst) {
10659 CallBase &CB = cast<CallBase>(Inst);
10660
10661 auto *CBEdges = A.getAAFor<AACallEdges>(
10662 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED);
10663 if (!CBEdges)
10664 return false;
10665 if (CBEdges->hasNonAsmUnknownCallee())
10666 setHasUnknownCallee(true, Change);
10667 if (CBEdges->hasUnknownCallee())
10668 setHasUnknownCallee(false, Change);
10669
10670 for (Function *F : CBEdges->getOptimisticEdges())
10671 addCalledFunction(F, Change);
10672
10673 return true;
10674 };
10675
10676 // Visit all callable instructions.
10677 bool UsedAssumedInformation = false;
10678 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
10679 UsedAssumedInformation,
10680 /* CheckBBLivenessOnly */ true)) {
10681 // If we haven't looked at all call like instructions, assume that there
10682 // are unknown callees.
10683 setHasUnknownCallee(true, Change);
10684 }
10685
10686 return Change;
10687 }
10688};
10689
10690/// -------------------AAInterFnReachability Attribute--------------------------
10691
10692struct AAInterFnReachabilityFunction
10693 : public CachedReachabilityAA<AAInterFnReachability, Function> {
10694 using Base = CachedReachabilityAA<AAInterFnReachability, Function>;
10695 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A)
10696 : Base(IRP, A) {}
10697
10698 bool instructionCanReach(
10699 Attributor &A, const Instruction &From, const Function &To,
10700 const AA::InstExclusionSetTy *ExclusionSet) const override {
10701 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!");
10702 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this);
10703
10704 RQITy StackRQI(A, From, To, ExclusionSet, false);
10705 typename RQITy::Reachable Result;
10706 if (!NonConstThis->checkQueryCache(A, StackRQI, Result))
10707 return NonConstThis->isReachableImpl(A, StackRQI,
10708 /*IsTemporaryRQI=*/true);
10709 return Result == RQITy::Reachable::Yes;
10710 }
10711
10712 bool isReachableImpl(Attributor &A, RQITy &RQI,
10713 bool IsTemporaryRQI) override {
10714 const Instruction *EntryI =
10715 &RQI.From->getFunction()->getEntryBlock().front();
10716 if (EntryI != RQI.From &&
10717 !instructionCanReach(A, *EntryI, *RQI.To, nullptr))
10718 return rememberResult(A, RQITy::Reachable::No, RQI, false,
10719 IsTemporaryRQI);
10720
10721 auto CheckReachableCallBase = [&](CallBase *CB) {
10722 auto *CBEdges = A.getAAFor<AACallEdges>(
10723 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL);
10724 if (!CBEdges || !CBEdges->getState().isValidState())
10725 return false;
10726 // TODO Check To backwards in this case.
10727 if (CBEdges->hasUnknownCallee())
10728 return false;
10729
10730 for (Function *Fn : CBEdges->getOptimisticEdges()) {
10731 if (Fn == RQI.To)
10732 return false;
10733
10734 if (Fn->isDeclaration()) {
10735 if (Fn->hasFnAttribute(Attribute::NoCallback))
10736 continue;
10737 // TODO Check To backwards in this case.
10738 return false;
10739 }
10740
10741 if (Fn == getAnchorScope()) {
10742 if (EntryI == RQI.From)
10743 continue;
10744 return false;
10745 }
10746
10747 const AAInterFnReachability *InterFnReachability =
10748 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn),
10749 DepClassTy::OPTIONAL);
10750
10751 const Instruction &FnFirstInst = Fn->getEntryBlock().front();
10752 if (!InterFnReachability ||
10753 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To,
10754 RQI.ExclusionSet))
10755 return false;
10756 }
10757 return true;
10758 };
10759
10760 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>(
10761 *this, IRPosition::function(*RQI.From->getFunction()),
10762 DepClassTy::OPTIONAL);
10763
10764 // Determine call like instructions that we can reach from the inst.
10765 auto CheckCallBase = [&](Instruction &CBInst) {
10766 // There are usually less nodes in the call graph, check inter function
10767 // reachability first.
10768 if (CheckReachableCallBase(cast<CallBase>(&CBInst)))
10769 return true;
10770 return IntraFnReachability && !IntraFnReachability->isAssumedReachable(
10771 A, *RQI.From, CBInst, RQI.ExclusionSet);
10772 };
10773
10774 bool UsedExclusionSet = /* conservative */ true;
10775 bool UsedAssumedInformation = false;
10776 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this,
10777 UsedAssumedInformation,
10778 /* CheckBBLivenessOnly */ true))
10779 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet,
10780 IsTemporaryRQI);
10781
10782 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet,
10783 IsTemporaryRQI);
10784 }
10785
10786 void trackStatistics() const override {}
10787};
10788} // namespace
10789
10790template <typename AAType>
10791static std::optional<Constant *>
10793 const IRPosition &IRP, Type &Ty) {
10794 if (!Ty.isIntegerTy())
10795 return nullptr;
10796
10797 // This will also pass the call base context.
10798 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE);
10799 if (!AA)
10800 return nullptr;
10801
10802 std::optional<Constant *> COpt = AA->getAssumedConstant(A);
10803
10804 if (!COpt.has_value()) {
10805 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10806 return std::nullopt;
10807 }
10808 if (auto *C = *COpt) {
10809 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL);
10810 return C;
10811 }
10812 return nullptr;
10813}
10814
10816 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP,
10818 Type &Ty = *IRP.getAssociatedType();
10819 std::optional<Value *> V;
10820 for (auto &It : Values) {
10821 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty);
10822 if (V.has_value() && !*V)
10823 break;
10824 }
10825 if (!V.has_value())
10826 return UndefValue::get(&Ty);
10827 return *V;
10828}
10829
10830namespace {
10831struct AAPotentialValuesImpl : AAPotentialValues {
10832 using StateType = PotentialLLVMValuesState;
10833
10834 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A)
10835 : AAPotentialValues(IRP, A) {}
10836
10837 /// See AbstractAttribute::initialize(..).
10838 void initialize(Attributor &A) override {
10839 if (A.hasSimplificationCallback(getIRPosition())) {
10840 indicatePessimisticFixpoint();
10841 return;
10842 }
10843 Value *Stripped = getAssociatedValue().stripPointerCasts();
10844 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) {
10845 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope,
10846 getAnchorScope());
10847 indicateOptimisticFixpoint();
10848 return;
10849 }
10850 AAPotentialValues::initialize(A);
10851 }
10852
10853 /// See AbstractAttribute::getAsStr().
10854 const std::string getAsStr(Attributor *A) const override {
10855 std::string Str;
10857 OS << getState();
10858 return Str;
10859 }
10860
10861 template <typename AAType>
10862 static std::optional<Value *> askOtherAA(Attributor &A,
10863 const AbstractAttribute &AA,
10864 const IRPosition &IRP, Type &Ty) {
10865 if (isa<Constant>(IRP.getAssociatedValue()))
10866 return &IRP.getAssociatedValue();
10867 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty);
10868 if (!C)
10869 return std::nullopt;
10870 if (*C)
10871 if (auto *CC = AA::getWithType(**C, Ty))
10872 return CC;
10873 return nullptr;
10874 }
10875
10876 virtual void addValue(Attributor &A, StateType &State, Value &V,
10877 const Instruction *CtxI, AA::ValueScope S,
10878 Function *AnchorScope) const {
10879
10880 IRPosition ValIRP = IRPosition::value(V);
10881 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) {
10882 for (const auto &U : CB->args()) {
10883 if (U.get() != &V)
10884 continue;
10885 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
10886 break;
10887 }
10888 }
10889
10890 Value *VPtr = &V;
10891 if (ValIRP.getAssociatedType()->isIntegerTy()) {
10892 Type &Ty = *getAssociatedType();
10893 std::optional<Value *> SimpleV =
10894 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty);
10895 if (SimpleV.has_value() && !*SimpleV) {
10896 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>(
10897 *this, ValIRP, DepClassTy::OPTIONAL);
10898 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) {
10899 for (const auto &It : PotentialConstantsAA->getAssumedSet())
10900 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S});
10901 if (PotentialConstantsAA->undefIsContained())
10902 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S});
10903 return;
10904 }
10905 }
10906 if (!SimpleV.has_value())
10907 return;
10908
10909 if (*SimpleV)
10910 VPtr = *SimpleV;
10911 }
10912
10913 if (isa<ConstantInt>(VPtr))
10914 CtxI = nullptr;
10915 if (!AA::isValidInScope(*VPtr, AnchorScope))
10917
10918 State.unionAssumed({{*VPtr, CtxI}, S});
10919 }
10920
10921 /// Helper struct to tie a value+context pair together with the scope for
10922 /// which this is the simplified version.
10923 struct ItemInfo {
10926
10927 bool operator==(const ItemInfo &II) const {
10928 return II.I == I && II.S == S;
10929 };
10930 bool operator<(const ItemInfo &II) const {
10931 return std::tie(I, S) < std::tie(II.I, II.S);
10932 };
10933 };
10934
10935 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) {
10937 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) {
10938 if (!(CS & S))
10939 continue;
10940
10941 bool UsedAssumedInformation = false;
10943 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS,
10944 UsedAssumedInformation))
10945 return false;
10946
10947 for (auto &It : Values)
10948 ValueScopeMap[It] += CS;
10949 }
10950 for (auto &It : ValueScopeMap)
10951 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(),
10952 AA::ValueScope(It.second), getAnchorScope());
10953
10954 return true;
10955 }
10956
10957 void giveUpOnIntraprocedural(Attributor &A) {
10958 auto NewS = StateType::getBestState(getState());
10959 for (const auto &It : getAssumedSet()) {
10960 if (It.second == AA::Intraprocedural)
10961 continue;
10962 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(),
10963 AA::Interprocedural, getAnchorScope());
10964 }
10965 assert(!undefIsContained() && "Undef should be an explicit value!");
10966 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural,
10967 getAnchorScope());
10968 getState() = NewS;
10969 }
10970
10971 /// See AbstractState::indicatePessimisticFixpoint(...).
10972 ChangeStatus indicatePessimisticFixpoint() override {
10973 getState() = StateType::getBestState(getState());
10974 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope});
10976 return ChangeStatus::CHANGED;
10977 }
10978
10979 /// See AbstractAttribute::updateImpl(...).
10980 ChangeStatus updateImpl(Attributor &A) override {
10981 return indicatePessimisticFixpoint();
10982 }
10983
10984 /// See AbstractAttribute::manifest(...).
10985 ChangeStatus manifest(Attributor &A) override {
10988 Values.clear();
10989 if (!getAssumedSimplifiedValues(A, Values, S))
10990 continue;
10991 Value &OldV = getAssociatedValue();
10992 if (isa<UndefValue>(OldV))
10993 continue;
10994 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values);
10995 if (!NewV || NewV == &OldV)
10996 continue;
10997 if (getCtxI() &&
10998 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache()))
10999 continue;
11000 if (A.changeAfterManifest(getIRPosition(), *NewV))
11001 return ChangeStatus::CHANGED;
11002 }
11004 }
11005
11006 bool getAssumedSimplifiedValues(
11008 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override {
11009 if (!isValidState())
11010 return false;
11011 bool UsedAssumedInformation = false;
11012 for (const auto &It : getAssumedSet())
11013 if (It.second & S) {
11014 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) ||
11015 isa<SelectInst>(It.first.getValue()))) {
11016 if (A.getAssumedSimplifiedValues(
11017 IRPosition::inst(*cast<Instruction>(It.first.getValue())),
11018 this, Values, S, UsedAssumedInformation))
11019 continue;
11020 }
11021 Values.push_back(It.first);
11022 }
11023 assert(!undefIsContained() && "Undef should be an explicit value!");
11024 return true;
11025 }
11026};
11027
11028struct AAPotentialValuesFloating : AAPotentialValuesImpl {
11029 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A)
11030 : AAPotentialValuesImpl(IRP, A) {}
11031
11032 /// See AbstractAttribute::updateImpl(...).
11033 ChangeStatus updateImpl(Attributor &A) override {
11034 auto AssumedBefore = getAssumed();
11035
11036 genericValueTraversal(A, &getAssociatedValue());
11037
11038 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11039 : ChangeStatus::CHANGED;
11040 }
11041
11042 /// Helper struct to remember which AAIsDead instances we actually used.
11043 struct LivenessInfo {
11044 const AAIsDead *LivenessAA = nullptr;
11045 bool AnyDead = false;
11046 };
11047
11048 /// Check if \p Cmp is a comparison we can simplify.
11049 ///
11050 /// We handle multiple cases, one in which at least one operand is an
11051 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other
11052 /// operand. Return true if successful, in that case Worklist will be updated.
11053 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS,
11054 CmpInst::Predicate Pred, ItemInfo II,
11055 SmallVectorImpl<ItemInfo> &Worklist) {
11056
11057 // Simplify the operands first.
11058 bool UsedAssumedInformation = false;
11059 SmallVector<AA::ValueAndContext> LHSValues, RHSValues;
11060 auto GetSimplifiedValues = [&](Value &V,
11062 if (!A.getAssumedSimplifiedValues(
11063 IRPosition::value(V, getCallBaseContext()), this, Values,
11064 AA::Intraprocedural, UsedAssumedInformation)) {
11065 Values.clear();
11066 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()});
11067 }
11068 return Values.empty();
11069 };
11070 if (GetSimplifiedValues(*LHS, LHSValues))
11071 return true;
11072 if (GetSimplifiedValues(*RHS, RHSValues))
11073 return true;
11074
11075 LLVMContext &Ctx = LHS->getContext();
11076
11077 InformationCache &InfoCache = A.getInfoCache();
11078 Instruction *CmpI = dyn_cast<Instruction>(&Cmp);
11079 Function *F = CmpI ? CmpI->getFunction() : nullptr;
11080 const auto *DT =
11082 : nullptr;
11083 const auto *TLI =
11084 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr;
11085 auto *AC =
11087 : nullptr;
11088
11089 const DataLayout &DL = A.getDataLayout();
11090 SimplifyQuery Q(DL, TLI, DT, AC, CmpI);
11091
11092 auto CheckPair = [&](Value &LHSV, Value &RHSV) {
11093 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) {
11094 addValue(A, getState(), *UndefValue::get(Cmp.getType()),
11095 /* CtxI */ nullptr, II.S, getAnchorScope());
11096 return true;
11097 }
11098
11099 // Handle the trivial case first in which we don't even need to think
11100 // about null or non-null.
11101 if (&LHSV == &RHSV &&
11103 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx),
11105 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11106 getAnchorScope());
11107 return true;
11108 }
11109
11110 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType());
11111 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType());
11112 if (TypedLHS && TypedRHS) {
11113 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q);
11114 if (NewV && NewV != &Cmp) {
11115 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11116 getAnchorScope());
11117 return true;
11118 }
11119 }
11120
11121 // From now on we only handle equalities (==, !=).
11122 if (!CmpInst::isEquality(Pred))
11123 return false;
11124
11125 bool LHSIsNull = isa<ConstantPointerNull>(LHSV);
11126 bool RHSIsNull = isa<ConstantPointerNull>(RHSV);
11127 if (!LHSIsNull && !RHSIsNull)
11128 return false;
11129
11130 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the
11131 // non-nullptr operand and if we assume it's non-null we can conclude the
11132 // result of the comparison.
11133 assert((LHSIsNull || RHSIsNull) &&
11134 "Expected nullptr versus non-nullptr comparison at this point");
11135
11136 // The index is the operand that we assume is not null.
11137 unsigned PtrIdx = LHSIsNull;
11138 bool IsKnownNonNull;
11139 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>(
11140 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)),
11141 DepClassTy::REQUIRED, IsKnownNonNull);
11142 if (!IsAssumedNonNull)
11143 return false;
11144
11145 // The new value depends on the predicate, true for != and false for ==.
11146 Constant *NewV =
11147 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE);
11148 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S,
11149 getAnchorScope());
11150 return true;
11151 };
11152
11153 for (auto &LHSValue : LHSValues)
11154 for (auto &RHSValue : RHSValues)
11155 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue()))
11156 return false;
11157 return true;
11158 }
11159
11160 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II,
11161 SmallVectorImpl<ItemInfo> &Worklist) {
11162 const Instruction *CtxI = II.I.getCtxI();
11163 bool UsedAssumedInformation = false;
11164
11165 std::optional<Constant *> C =
11166 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation);
11167 bool NoValueYet = !C.has_value();
11168 if (NoValueYet || isa_and_nonnull<UndefValue>(*C))
11169 return true;
11170 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) {
11171 if (CI->isZero())
11172 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11173 else
11174 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11175 } else if (&SI == &getAssociatedValue()) {
11176 // We could not simplify the condition, assume both values.
11177 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S});
11178 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S});
11179 } else {
11180 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11181 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S);
11182 if (!SimpleV.has_value())
11183 return true;
11184 if (*SimpleV) {
11185 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope());
11186 return true;
11187 }
11188 return false;
11189 }
11190 return true;
11191 }
11192
11193 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II,
11194 SmallVectorImpl<ItemInfo> &Worklist) {
11195 SmallSetVector<Value *, 4> PotentialCopies;
11196 SmallSetVector<Instruction *, 4> PotentialValueOrigins;
11197 bool UsedAssumedInformation = false;
11198 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies,
11199 PotentialValueOrigins, *this,
11200 UsedAssumedInformation,
11201 /* OnlyExact */ true)) {
11202 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially "
11203 "loaded values for load instruction "
11204 << LI << "\n");
11205 return false;
11206 }
11207
11208 // Do not simplify loads that are only used in llvm.assume if we cannot also
11209 // remove all stores that may feed into the load. The reason is that the
11210 // assume is probably worth something as long as the stores are around.
11211 InformationCache &InfoCache = A.getInfoCache();
11212 if (InfoCache.isOnlyUsedByAssume(LI)) {
11213 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) {
11214 if (!I || isa<AssumeInst>(I))
11215 return true;
11216 if (auto *SI = dyn_cast<StoreInst>(I))
11217 return A.isAssumedDead(SI->getOperandUse(0), this,
11218 /* LivenessAA */ nullptr,
11219 UsedAssumedInformation,
11220 /* CheckBBLivenessOnly */ false);
11221 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr,
11222 UsedAssumedInformation,
11223 /* CheckBBLivenessOnly */ false);
11224 })) {
11225 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes "
11226 "and we cannot delete all the stores: "
11227 << LI << "\n");
11228 return false;
11229 }
11230 }
11231
11232 // Values have to be dynamically unique or we loose the fact that a
11233 // single llvm::Value might represent two runtime values (e.g.,
11234 // stack locations in different recursive calls).
11235 const Instruction *CtxI = II.I.getCtxI();
11236 bool ScopeIsLocal = (II.S & AA::Intraprocedural);
11237 bool AllLocal = ScopeIsLocal;
11238 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) {
11239 AllLocal &= AA::isValidInScope(*PC, getAnchorScope());
11240 return AA::isDynamicallyUnique(A, *this, *PC);
11241 });
11242 if (!DynamicallyUnique) {
11243 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded "
11244 "values are dynamically unique: "
11245 << LI << "\n");
11246 return false;
11247 }
11248
11249 for (auto *PotentialCopy : PotentialCopies) {
11250 if (AllLocal) {
11251 Worklist.push_back({{*PotentialCopy, CtxI}, II.S});
11252 } else {
11253 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural});
11254 }
11255 }
11256 if (!AllLocal && ScopeIsLocal)
11257 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope());
11258 return true;
11259 }
11260
11261 bool handlePHINode(
11262 Attributor &A, PHINode &PHI, ItemInfo II,
11263 SmallVectorImpl<ItemInfo> &Worklist,
11265 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & {
11266 LivenessInfo &LI = LivenessAAs[&F];
11267 if (!LI.LivenessAA)
11268 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F),
11269 DepClassTy::NONE);
11270 return LI;
11271 };
11272
11273 if (&PHI == &getAssociatedValue()) {
11274 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction());
11275 const auto *CI =
11276 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(
11277 *PHI.getFunction());
11278
11279 Cycle *C = nullptr;
11280 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C);
11281 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) {
11282 BasicBlock *IncomingBB = PHI.getIncomingBlock(u);
11283 if (LI.LivenessAA &&
11284 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) {
11285 LI.AnyDead = true;
11286 continue;
11287 }
11288 Value *V = PHI.getIncomingValue(u);
11289 if (V == &PHI)
11290 continue;
11291
11292 // If the incoming value is not the PHI but an instruction in the same
11293 // cycle we might have multiple versions of it flying around.
11294 if (CyclePHI && isa<Instruction>(V) &&
11295 (!C || C->contains(cast<Instruction>(V)->getParent())))
11296 return false;
11297
11298 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S});
11299 }
11300 return true;
11301 }
11302
11303 bool UsedAssumedInformation = false;
11304 std::optional<Value *> SimpleV = A.getAssumedSimplified(
11305 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S);
11306 if (!SimpleV.has_value())
11307 return true;
11308 if (!(*SimpleV))
11309 return false;
11310 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope());
11311 return true;
11312 }
11313
11314 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to
11315 /// simplify any operand of the instruction \p I. Return true if successful,
11316 /// in that case Worklist will be updated.
11317 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II,
11318 SmallVectorImpl<ItemInfo> &Worklist) {
11319 bool SomeSimplified = false;
11320 bool UsedAssumedInformation = false;
11321
11322 SmallVector<Value *, 8> NewOps(I.getNumOperands());
11323 int Idx = 0;
11324 for (Value *Op : I.operands()) {
11325 const auto &SimplifiedOp = A.getAssumedSimplified(
11326 IRPosition::value(*Op, getCallBaseContext()), *this,
11327 UsedAssumedInformation, AA::Intraprocedural);
11328 // If we are not sure about any operand we are not sure about the entire
11329 // instruction, we'll wait.
11330 if (!SimplifiedOp.has_value())
11331 return true;
11332
11333 if (*SimplifiedOp)
11334 NewOps[Idx] = *SimplifiedOp;
11335 else
11336 NewOps[Idx] = Op;
11337
11338 SomeSimplified |= (NewOps[Idx] != Op);
11339 ++Idx;
11340 }
11341
11342 // We won't bother with the InstSimplify interface if we didn't simplify any
11343 // operand ourselves.
11344 if (!SomeSimplified)
11345 return false;
11346
11347 InformationCache &InfoCache = A.getInfoCache();
11348 Function *F = I.getFunction();
11349 const auto *DT =
11351 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
11352 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F);
11353
11354 const DataLayout &DL = I.getDataLayout();
11355 SimplifyQuery Q(DL, TLI, DT, AC, &I);
11356 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q);
11357 if (!NewV || NewV == &I)
11358 return false;
11359
11360 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to "
11361 << *NewV << "\n");
11362 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S});
11363 return true;
11364 }
11365
11367 Attributor &A, Instruction &I, ItemInfo II,
11368 SmallVectorImpl<ItemInfo> &Worklist,
11370 if (auto *CI = dyn_cast<CmpInst>(&I))
11371 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1),
11372 CI->getPredicate(), II, Worklist);
11373
11374 switch (I.getOpcode()) {
11375 case Instruction::Select:
11376 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist);
11377 case Instruction::PHI:
11378 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs);
11379 case Instruction::Load:
11380 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist);
11381 default:
11382 return handleGenericInst(A, I, II, Worklist);
11383 };
11384 return false;
11385 }
11386
11387 void genericValueTraversal(Attributor &A, Value *InitialV) {
11389
11390 SmallSet<ItemInfo, 16> Visited;
11392 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope});
11393
11394 int Iteration = 0;
11395 do {
11396 ItemInfo II = Worklist.pop_back_val();
11397 Value *V = II.I.getValue();
11398 assert(V);
11399 const Instruction *CtxI = II.I.getCtxI();
11400 AA::ValueScope S = II.S;
11401
11402 // Check if we should process the current value. To prevent endless
11403 // recursion keep a record of the values we followed!
11404 if (!Visited.insert(II).second)
11405 continue;
11406
11407 // Make sure we limit the compile time for complex expressions.
11408 if (Iteration++ >= MaxPotentialValuesIterations) {
11409 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: "
11410 << Iteration << "!\n");
11411 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11412 continue;
11413 }
11414
11415 // Explicitly look through calls with a "returned" attribute if we do
11416 // not have a pointer as stripPointerCasts only works on them.
11417 Value *NewV = nullptr;
11418 if (V->getType()->isPointerTy()) {
11419 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType());
11420 } else {
11421 if (auto *CB = dyn_cast<CallBase>(V))
11422 if (auto *Callee =
11423 dyn_cast_if_present<Function>(CB->getCalledOperand())) {
11424 for (Argument &Arg : Callee->args())
11425 if (Arg.hasReturnedAttr()) {
11426 NewV = CB->getArgOperand(Arg.getArgNo());
11427 break;
11428 }
11429 }
11430 }
11431 if (NewV && NewV != V) {
11432 Worklist.push_back({{*NewV, CtxI}, S});
11433 continue;
11434 }
11435
11436 if (auto *I = dyn_cast<Instruction>(V)) {
11437 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs))
11438 continue;
11439 }
11440
11441 if (V != InitialV || isa<Argument>(V))
11442 if (recurseForValue(A, IRPosition::value(*V), II.S))
11443 continue;
11444
11445 // If we haven't stripped anything we give up.
11446 if (V == InitialV && CtxI == getCtxI()) {
11447 indicatePessimisticFixpoint();
11448 return;
11449 }
11450
11451 addValue(A, getState(), *V, CtxI, S, getAnchorScope());
11452 } while (!Worklist.empty());
11453
11454 // If we actually used liveness information so we have to record a
11455 // dependence.
11456 for (auto &It : LivenessAAs)
11457 if (It.second.AnyDead)
11458 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL);
11459 }
11460
11461 /// See AbstractAttribute::trackStatistics()
11462 void trackStatistics() const override {
11463 STATS_DECLTRACK_FLOATING_ATTR(potential_values)
11464 }
11465};
11466
11467struct AAPotentialValuesArgument final : AAPotentialValuesImpl {
11468 using Base = AAPotentialValuesImpl;
11469 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A)
11470 : Base(IRP, A) {}
11471
11472 /// See AbstractAttribute::initialize(..).
11473 void initialize(Attributor &A) override {
11474 auto &Arg = cast<Argument>(getAssociatedValue());
11476 indicatePessimisticFixpoint();
11477 }
11478
11479 /// See AbstractAttribute::updateImpl(...).
11480 ChangeStatus updateImpl(Attributor &A) override {
11481 auto AssumedBefore = getAssumed();
11482
11483 unsigned ArgNo = getCalleeArgNo();
11484
11485 bool UsedAssumedInformation = false;
11487 auto CallSitePred = [&](AbstractCallSite ACS) {
11488 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo);
11489 if (CSArgIRP.getPositionKind() == IRP_INVALID)
11490 return false;
11491
11492 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values,
11494 UsedAssumedInformation))
11495 return false;
11496
11497 return isValidState();
11498 };
11499
11500 if (!A.checkForAllCallSites(CallSitePred, *this,
11501 /* RequireAllCallSites */ true,
11502 UsedAssumedInformation))
11503 return indicatePessimisticFixpoint();
11504
11505 Function *Fn = getAssociatedFunction();
11506 bool AnyNonLocal = false;
11507 for (auto &It : Values) {
11508 if (isa<Constant>(It.getValue())) {
11509 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11510 getAnchorScope());
11511 continue;
11512 }
11513 if (!AA::isDynamicallyUnique(A, *this, *It.getValue()))
11514 return indicatePessimisticFixpoint();
11515
11516 if (auto *Arg = dyn_cast<Argument>(It.getValue()))
11517 if (Arg->getParent() == Fn) {
11518 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope,
11519 getAnchorScope());
11520 continue;
11521 }
11522 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural,
11523 getAnchorScope());
11524 AnyNonLocal = true;
11525 }
11526 assert(!undefIsContained() && "Undef should be an explicit value!");
11527 if (AnyNonLocal)
11528 giveUpOnIntraprocedural(A);
11529
11530 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11531 : ChangeStatus::CHANGED;
11532 }
11533
11534 /// See AbstractAttribute::trackStatistics()
11535 void trackStatistics() const override {
11536 STATS_DECLTRACK_ARG_ATTR(potential_values)
11537 }
11538};
11539
11540struct AAPotentialValuesReturned : public AAPotentialValuesFloating {
11541 using Base = AAPotentialValuesFloating;
11542 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A)
11543 : Base(IRP, A) {}
11544
11545 /// See AbstractAttribute::initialize(..).
11546 void initialize(Attributor &A) override {
11547 Function *F = getAssociatedFunction();
11548 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) {
11549 indicatePessimisticFixpoint();
11550 return;
11551 }
11552
11553 for (Argument &Arg : F->args())
11554 if (Arg.hasReturnedAttr()) {
11555 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F);
11556 ReturnedArg = &Arg;
11557 break;
11558 }
11559 if (!A.isFunctionIPOAmendable(*F) ||
11560 A.hasSimplificationCallback(getIRPosition())) {
11561 if (!ReturnedArg)
11562 indicatePessimisticFixpoint();
11563 else
11564 indicateOptimisticFixpoint();
11565 }
11566 }
11567
11568 /// See AbstractAttribute::updateImpl(...).
11569 ChangeStatus updateImpl(Attributor &A) override {
11570 auto AssumedBefore = getAssumed();
11571 bool UsedAssumedInformation = false;
11572
11574 Function *AnchorScope = getAnchorScope();
11575 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI,
11576 bool AddValues) {
11578 Values.clear();
11579 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S,
11580 UsedAssumedInformation,
11581 /* RecurseForSelectAndPHI */ true))
11582 return false;
11583 if (!AddValues)
11584 continue;
11585
11586 bool AllInterAreIntra = false;
11587 if (S == AA::Interprocedural)
11588 AllInterAreIntra =
11589 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) {
11590 return AA::isValidInScope(*VAC.getValue(), AnchorScope);
11591 });
11592
11593 for (const AA::ValueAndContext &VAC : Values) {
11594 addValue(A, getState(), *VAC.getValue(),
11595 VAC.getCtxI() ? VAC.getCtxI() : CtxI,
11596 AllInterAreIntra ? AA::AnyScope : S, AnchorScope);
11597 }
11598 if (AllInterAreIntra)
11599 break;
11600 }
11601 return true;
11602 };
11603
11604 if (ReturnedArg) {
11605 HandleReturnedValue(*ReturnedArg, nullptr, true);
11606 } else {
11607 auto RetInstPred = [&](Instruction &RetI) {
11608 bool AddValues = true;
11609 if (isa<PHINode>(RetI.getOperand(0)) ||
11610 isa<SelectInst>(RetI.getOperand(0))) {
11611 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope,
11612 AnchorScope);
11613 AddValues = false;
11614 }
11615 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues);
11616 };
11617
11618 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11619 UsedAssumedInformation,
11620 /* CheckBBLivenessOnly */ true))
11621 return indicatePessimisticFixpoint();
11622 }
11623
11624 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11625 : ChangeStatus::CHANGED;
11626 }
11627
11628 ChangeStatus manifest(Attributor &A) override {
11629 if (ReturnedArg)
11630 return ChangeStatus::UNCHANGED;
11632 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural,
11633 /* RecurseForSelectAndPHI */ true))
11634 return ChangeStatus::UNCHANGED;
11635 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values);
11636 if (!NewVal)
11637 return ChangeStatus::UNCHANGED;
11638
11639 ChangeStatus Changed = ChangeStatus::UNCHANGED;
11640 if (auto *Arg = dyn_cast<Argument>(NewVal)) {
11641 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
11642 "Number of function with unique return");
11643 Changed |= A.manifestAttrs(
11645 {Attribute::get(Arg->getContext(), Attribute::Returned)});
11646 STATS_DECLTRACK_ARG_ATTR(returned);
11647 }
11648
11649 auto RetInstPred = [&](Instruction &RetI) {
11650 Value *RetOp = RetI.getOperand(0);
11651 if (isa<UndefValue>(RetOp) || RetOp == NewVal)
11652 return true;
11653 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache()))
11654 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal))
11655 Changed = ChangeStatus::CHANGED;
11656 return true;
11657 };
11658 bool UsedAssumedInformation = false;
11659 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
11660 UsedAssumedInformation,
11661 /* CheckBBLivenessOnly */ true);
11662 return Changed;
11663 }
11664
11665 ChangeStatus indicatePessimisticFixpoint() override {
11667 }
11668
11669 /// See AbstractAttribute::trackStatistics()
11670 void trackStatistics() const override{
11671 STATS_DECLTRACK_FNRET_ATTR(potential_values)}
11672
11673 /// The argumented with an existing `returned` attribute.
11674 Argument *ReturnedArg = nullptr;
11675};
11676
11677struct AAPotentialValuesFunction : AAPotentialValuesImpl {
11678 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A)
11679 : AAPotentialValuesImpl(IRP, A) {}
11680
11681 /// See AbstractAttribute::updateImpl(...).
11682 ChangeStatus updateImpl(Attributor &A) override {
11683 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will "
11684 "not be called");
11685 }
11686
11687 /// See AbstractAttribute::trackStatistics()
11688 void trackStatistics() const override {
11689 STATS_DECLTRACK_FN_ATTR(potential_values)
11690 }
11691};
11692
11693struct AAPotentialValuesCallSite : AAPotentialValuesFunction {
11694 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A)
11695 : AAPotentialValuesFunction(IRP, A) {}
11696
11697 /// See AbstractAttribute::trackStatistics()
11698 void trackStatistics() const override {
11699 STATS_DECLTRACK_CS_ATTR(potential_values)
11700 }
11701};
11702
11703struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl {
11704 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A)
11705 : AAPotentialValuesImpl(IRP, A) {}
11706
11707 /// See AbstractAttribute::updateImpl(...).
11708 ChangeStatus updateImpl(Attributor &A) override {
11709 auto AssumedBefore = getAssumed();
11710
11711 Function *Callee = getAssociatedFunction();
11712 if (!Callee)
11713 return indicatePessimisticFixpoint();
11714
11715 bool UsedAssumedInformation = false;
11716 auto *CB = cast<CallBase>(getCtxI());
11717 if (CB->isMustTailCall() &&
11718 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr,
11719 UsedAssumedInformation))
11720 return indicatePessimisticFixpoint();
11721
11722 Function *Caller = CB->getCaller();
11723
11724 auto AddScope = [&](AA::ValueScope S) {
11726 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this,
11727 Values, S, UsedAssumedInformation))
11728 return false;
11729
11730 for (auto &It : Values) {
11731 Value *V = It.getValue();
11732 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent(
11733 V, *CB, *this, UsedAssumedInformation);
11734 if (!CallerV.has_value()) {
11735 // Nothing to do as long as no value was determined.
11736 continue;
11737 }
11738 V = *CallerV ? *CallerV : V;
11739 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) {
11740 if (recurseForValue(A, IRPosition::value(*V), S))
11741 continue;
11742 }
11743 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) {
11744 giveUpOnIntraprocedural(A);
11745 return true;
11746 }
11747 addValue(A, getState(), *V, CB, S, getAnchorScope());
11748 }
11749 return true;
11750 };
11751 if (!AddScope(AA::Intraprocedural))
11752 return indicatePessimisticFixpoint();
11753 if (!AddScope(AA::Interprocedural))
11754 return indicatePessimisticFixpoint();
11755 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED
11756 : ChangeStatus::CHANGED;
11757 }
11758
11759 ChangeStatus indicatePessimisticFixpoint() override {
11760 return AAPotentialValues::indicatePessimisticFixpoint();
11761 }
11762
11763 /// See AbstractAttribute::trackStatistics()
11764 void trackStatistics() const override {
11765 STATS_DECLTRACK_CSRET_ATTR(potential_values)
11766 }
11767};
11768
11769struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating {
11770 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A)
11771 : AAPotentialValuesFloating(IRP, A) {}
11772
11773 /// See AbstractAttribute::trackStatistics()
11774 void trackStatistics() const override {
11775 STATS_DECLTRACK_CSARG_ATTR(potential_values)
11776 }
11777};
11778} // namespace
11779
11780/// ---------------------- Assumption Propagation ------------------------------
11781namespace {
11782struct AAAssumptionInfoImpl : public AAAssumptionInfo {
11783 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A,
11784 const DenseSet<StringRef> &Known)
11785 : AAAssumptionInfo(IRP, A, Known) {}
11786
11787 /// See AbstractAttribute::manifest(...).
11788 ChangeStatus manifest(Attributor &A) override {
11789 // Don't manifest a universal set if it somehow made it here.
11790 if (getKnown().isUniversal())
11791 return ChangeStatus::UNCHANGED;
11792
11793 const IRPosition &IRP = getIRPosition();
11794 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(),
11795 getAssumed().getSet().end());
11796 llvm::sort(Set);
11797 return A.manifestAttrs(IRP,
11800 llvm::join(Set, ",")),
11801 /*ForceReplace=*/true);
11802 }
11803
11804 bool hasAssumption(const StringRef Assumption) const override {
11805 return isValidState() && setContains(Assumption);
11806 }
11807
11808 /// See AbstractAttribute::getAsStr()
11809 const std::string getAsStr(Attributor *A) const override {
11810 const SetContents &Known = getKnown();
11811 const SetContents &Assumed = getAssumed();
11812
11813 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end());
11814 llvm::sort(Set);
11815 const std::string KnownStr = llvm::join(Set, ",");
11816
11817 std::string AssumedStr = "Universal";
11818 if (!Assumed.isUniversal()) {
11819 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end());
11820 AssumedStr = llvm::join(Set, ",");
11821 }
11822 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]";
11823 }
11824};
11825
11826/// Propagates assumption information from parent functions to all of their
11827/// successors. An assumption can be propagated if the containing function
11828/// dominates the called function.
11829///
11830/// We start with a "known" set of assumptions already valid for the associated
11831/// function and an "assumed" set that initially contains all possible
11832/// assumptions. The assumed set is inter-procedurally updated by narrowing its
11833/// contents as concrete values are known. The concrete values are seeded by the
11834/// first nodes that are either entries into the call graph, or contains no
11835/// assumptions. Each node is updated as the intersection of the assumed state
11836/// with all of its predecessors.
11837struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl {
11838 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A)
11839 : AAAssumptionInfoImpl(IRP, A,
11840 getAssumptions(*IRP.getAssociatedFunction())) {}
11841
11842 /// See AbstractAttribute::updateImpl(...).
11843 ChangeStatus updateImpl(Attributor &A) override {
11844 bool Changed = false;
11845
11846 auto CallSitePred = [&](AbstractCallSite ACS) {
11847 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>(
11848 *this, IRPosition::callsite_function(*ACS.getInstruction()),
11849 DepClassTy::REQUIRED);
11850 if (!AssumptionAA)
11851 return false;
11852 // Get the set of assumptions shared by all of this function's callers.
11853 Changed |= getIntersection(AssumptionAA->getAssumed());
11854 return !getAssumed().empty() || !getKnown().empty();
11855 };
11856
11857 bool UsedAssumedInformation = false;
11858 // Get the intersection of all assumptions held by this node's predecessors.
11859 // If we don't know all the call sites then this is either an entry into the
11860 // call graph or an empty node. This node is known to only contain its own
11861 // assumptions and can be propagated to its successors.
11862 if (!A.checkForAllCallSites(CallSitePred, *this, true,
11863 UsedAssumedInformation))
11864 return indicatePessimisticFixpoint();
11865
11866 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11867 }
11868
11869 void trackStatistics() const override {}
11870};
11871
11872/// Assumption Info defined for call sites.
11873struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl {
11874
11875 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A)
11876 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {}
11877
11878 /// See AbstractAttribute::initialize(...).
11879 void initialize(Attributor &A) override {
11880 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11881 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11882 }
11883
11884 /// See AbstractAttribute::updateImpl(...).
11885 ChangeStatus updateImpl(Attributor &A) override {
11886 const IRPosition &FnPos = IRPosition::function(*getAnchorScope());
11887 auto *AssumptionAA =
11888 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED);
11889 if (!AssumptionAA)
11890 return indicatePessimisticFixpoint();
11891 bool Changed = getIntersection(AssumptionAA->getAssumed());
11892 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
11893 }
11894
11895 /// See AbstractAttribute::trackStatistics()
11896 void trackStatistics() const override {}
11897
11898private:
11899 /// Helper to initialized the known set as all the assumptions this call and
11900 /// the callee contain.
11901 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) {
11902 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue());
11903 auto Assumptions = getAssumptions(CB);
11904 if (const Function *F = CB.getCaller())
11905 set_union(Assumptions, getAssumptions(*F));
11906 if (Function *F = IRP.getAssociatedFunction())
11907 set_union(Assumptions, getAssumptions(*F));
11908 return Assumptions;
11909 }
11910};
11911} // namespace
11912
11914 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>(
11915 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I))));
11916}
11917
11919
11920/// ------------------------ UnderlyingObjects ---------------------------------
11921
11922namespace {
11923struct AAUnderlyingObjectsImpl
11924 : StateWrapper<BooleanState, AAUnderlyingObjects> {
11926 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {}
11927
11928 /// See AbstractAttribute::getAsStr().
11929 const std::string getAsStr(Attributor *A) const override {
11930 if (!isValidState())
11931 return "<invalid>";
11932 std::string Str;
11934 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size()
11935 << " objects, intra " << IntraAssumedUnderlyingObjects.size()
11936 << " objects.\n";
11937 if (!InterAssumedUnderlyingObjects.empty()) {
11938 OS << "inter objects:\n";
11939 for (auto *Obj : InterAssumedUnderlyingObjects)
11940 OS << *Obj << '\n';
11941 }
11942 if (!IntraAssumedUnderlyingObjects.empty()) {
11943 OS << "intra objects:\n";
11944 for (auto *Obj : IntraAssumedUnderlyingObjects)
11945 OS << *Obj << '\n';
11946 }
11947 return Str;
11948 }
11949
11950 /// See AbstractAttribute::trackStatistics()
11951 void trackStatistics() const override {}
11952
11953 /// See AbstractAttribute::updateImpl(...).
11954 ChangeStatus updateImpl(Attributor &A) override {
11955 auto &Ptr = getAssociatedValue();
11956
11957 bool UsedAssumedInformation = false;
11958 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects,
11960 SmallPtrSet<Value *, 8> SeenObjects;
11962
11963 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values,
11964 Scope, UsedAssumedInformation))
11965 return UnderlyingObjects.insert(&Ptr);
11966
11967 bool Changed = false;
11968
11969 for (unsigned I = 0; I < Values.size(); ++I) {
11970 auto &VAC = Values[I];
11971 auto *Obj = VAC.getValue();
11972 Value *UO = getUnderlyingObject(Obj);
11973 if (!SeenObjects.insert(UO ? UO : Obj).second)
11974 continue;
11975 if (UO && UO != Obj) {
11976 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) {
11977 Changed |= UnderlyingObjects.insert(UO);
11978 continue;
11979 }
11980
11981 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>(
11982 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL);
11983 auto Pred = [&](Value &V) {
11984 if (&V == UO)
11985 Changed |= UnderlyingObjects.insert(UO);
11986 else
11987 Values.emplace_back(V, nullptr);
11988 return true;
11989 };
11990
11991 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope))
11993 "The forall call should not return false at this position");
11994 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint();
11995 continue;
11996 }
11997
11998 if (isa<SelectInst>(Obj)) {
11999 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope,
12000 UsedAssumedInformation);
12001 continue;
12002 }
12003 if (auto *PHI = dyn_cast<PHINode>(Obj)) {
12004 // Explicitly look through PHIs as we do not care about dynamically
12005 // uniqueness.
12006 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
12007 Changed |=
12008 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects,
12009 Scope, UsedAssumedInformation);
12010 }
12011 continue;
12012 }
12013
12014 Changed |= UnderlyingObjects.insert(Obj);
12015 }
12016
12017 return Changed;
12018 };
12019
12020 bool Changed = false;
12021 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural);
12022 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural);
12023 if (!UsedAssumedInformation)
12024 indicateOptimisticFixpoint();
12025 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
12026 }
12027
12028 bool forallUnderlyingObjects(
12029 function_ref<bool(Value &)> Pred,
12030 AA::ValueScope Scope = AA::Interprocedural) const override {
12031 if (!isValidState())
12032 return Pred(getAssociatedValue());
12033
12034 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural
12035 ? IntraAssumedUnderlyingObjects
12036 : InterAssumedUnderlyingObjects;
12037 for (Value *Obj : AssumedUnderlyingObjects)
12038 if (!Pred(*Obj))
12039 return false;
12040
12041 return true;
12042 }
12043
12044private:
12045 /// Handle the case where the value is not the actual underlying value, such
12046 /// as a phi node or a select instruction.
12047 bool handleIndirect(Attributor &A, Value &V,
12048 SmallSetVector<Value *, 8> &UnderlyingObjects,
12049 AA::ValueScope Scope, bool &UsedAssumedInformation) {
12050 bool Changed = false;
12051 const auto *AA = A.getAAFor<AAUnderlyingObjects>(
12052 *this, IRPosition::value(V), DepClassTy::OPTIONAL);
12053 auto Pred = [&](Value &V) {
12054 Changed |= UnderlyingObjects.insert(&V);
12055 return true;
12056 };
12057 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope))
12059 "The forall call should not return false at this position");
12060 UsedAssumedInformation |= !AA->getState().isAtFixpoint();
12061 return Changed;
12062 }
12063
12064 /// All the underlying objects collected so far via intra procedural scope.
12065 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects;
12066 /// All the underlying objects collected so far via inter procedural scope.
12067 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects;
12068};
12069
12070struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl {
12071 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A)
12072 : AAUnderlyingObjectsImpl(IRP, A) {}
12073};
12074
12075struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl {
12076 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A)
12077 : AAUnderlyingObjectsImpl(IRP, A) {}
12078};
12079
12080struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl {
12081 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A)
12082 : AAUnderlyingObjectsImpl(IRP, A) {}
12083};
12084
12085struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl {
12086 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A)
12087 : AAUnderlyingObjectsImpl(IRP, A) {}
12088};
12089
12090struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl {
12091 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A)
12092 : AAUnderlyingObjectsImpl(IRP, A) {}
12093};
12094
12095struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl {
12096 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A)
12097 : AAUnderlyingObjectsImpl(IRP, A) {}
12098};
12099
12100struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl {
12101 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A)
12102 : AAUnderlyingObjectsImpl(IRP, A) {}
12103};
12104} // namespace
12105
12106/// ------------------------ Global Value Info -------------------------------
12107namespace {
12108struct AAGlobalValueInfoFloating : public AAGlobalValueInfo {
12109 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A)
12110 : AAGlobalValueInfo(IRP, A) {}
12111
12112 /// See AbstractAttribute::initialize(...).
12113 void initialize(Attributor &A) override {}
12114
12115 bool checkUse(Attributor &A, const Use &U, bool &Follow,
12117 Instruction *UInst = dyn_cast<Instruction>(U.getUser());
12118 if (!UInst) {
12119 Follow = true;
12120 return true;
12121 }
12122
12123 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in "
12124 << *UInst << "\n");
12125
12126 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) {
12127 int Idx = &Cmp->getOperandUse(0) == &U;
12128 if (isa<Constant>(Cmp->getOperand(Idx)))
12129 return true;
12130 return U == &getAnchorValue();
12131 }
12132
12133 // Explicitly catch return instructions.
12134 if (isa<ReturnInst>(UInst)) {
12135 auto CallSitePred = [&](AbstractCallSite ACS) {
12136 Worklist.push_back(ACS.getInstruction());
12137 return true;
12138 };
12139 bool UsedAssumedInformation = false;
12140 // TODO: We should traverse the uses or add a "non-call-site" CB.
12141 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(),
12142 /*RequireAllCallSites=*/true, this,
12143 UsedAssumedInformation))
12144 return false;
12145 return true;
12146 }
12147
12148 // For now we only use special logic for call sites. However, the tracker
12149 // itself knows about a lot of other non-capturing cases already.
12150 auto *CB = dyn_cast<CallBase>(UInst);
12151 if (!CB)
12152 return false;
12153 // Direct calls are OK uses.
12154 if (CB->isCallee(&U))
12155 return true;
12156 // Non-argument uses are scary.
12157 if (!CB->isArgOperand(&U))
12158 return false;
12159 // TODO: Iterate callees.
12160 auto *Fn = dyn_cast<Function>(CB->getCalledOperand());
12161 if (!Fn || !A.isFunctionIPOAmendable(*Fn))
12162 return false;
12163
12164 unsigned ArgNo = CB->getArgOperandNo(&U);
12165 Worklist.push_back(Fn->getArg(ArgNo));
12166 return true;
12167 }
12168
12169 ChangeStatus updateImpl(Attributor &A) override {
12170 unsigned NumUsesBefore = Uses.size();
12171
12174 Worklist.push_back(&getAnchorValue());
12175
12176 auto UsePred = [&](const Use &U, bool &Follow) -> bool {
12177 Uses.insert(&U);
12178 // TODO(captures): Make this more precise.
12179 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr);
12180 if (CI.isPassthrough()) {
12181 Follow = true;
12182 return true;
12183 }
12184 return checkUse(A, U, Follow, Worklist);
12185 };
12186 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) {
12187 Uses.insert(&OldU);
12188 return true;
12189 };
12190
12191 while (!Worklist.empty()) {
12192 const Value *V = Worklist.pop_back_val();
12193 if (!Visited.insert(V).second)
12194 continue;
12195 if (!A.checkForAllUses(UsePred, *this, *V,
12196 /* CheckBBLivenessOnly */ true,
12197 DepClassTy::OPTIONAL,
12198 /* IgnoreDroppableUses */ true, EquivalentUseCB)) {
12199 return indicatePessimisticFixpoint();
12200 }
12201 }
12202
12203 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED
12204 : ChangeStatus::CHANGED;
12205 }
12206
12207 bool isPotentialUse(const Use &U) const override {
12208 return !isValidState() || Uses.contains(&U);
12209 }
12210
12211 /// See AbstractAttribute::manifest(...).
12212 ChangeStatus manifest(Attributor &A) override {
12213 return ChangeStatus::UNCHANGED;
12214 }
12215
12216 /// See AbstractAttribute::getAsStr().
12217 const std::string getAsStr(Attributor *A) const override {
12218 return "[" + std::to_string(Uses.size()) + " uses]";
12219 }
12220
12221 void trackStatistics() const override {
12222 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked);
12223 }
12224
12225private:
12226 /// Set of (transitive) uses of this GlobalValue.
12228};
12229} // namespace
12230
12231/// ------------------------ Indirect Call Info -------------------------------
12232namespace {
12233struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo {
12234 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A)
12235 : AAIndirectCallInfo(IRP, A) {}
12236
12237 /// See AbstractAttribute::initialize(...).
12238 void initialize(Attributor &A) override {
12239 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees);
12240 if (!MD && !A.isClosedWorldModule())
12241 return;
12242
12243 if (MD) {
12244 for (const auto &Op : MD->operands())
12245 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op))
12246 PotentialCallees.insert(Callee);
12247 } else if (A.isClosedWorldModule()) {
12248 ArrayRef<Function *> IndirectlyCallableFunctions =
12249 A.getInfoCache().getIndirectlyCallableFunctions(A);
12250 PotentialCallees.insert_range(IndirectlyCallableFunctions);
12251 }
12252
12253 if (PotentialCallees.empty())
12254 indicateOptimisticFixpoint();
12255 }
12256
12257 ChangeStatus updateImpl(Attributor &A) override {
12258 CallBase *CB = cast<CallBase>(getCtxI());
12259 const Use &CalleeUse = CB->getCalledOperandUse();
12260 Value *FP = CB->getCalledOperand();
12261
12262 SmallSetVector<Function *, 4> AssumedCalleesNow;
12263 bool AllCalleesKnownNow = AllCalleesKnown;
12264
12265 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee,
12266 bool &UsedAssumedInformation) {
12267 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>(
12268 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL);
12269 if (!GIAA || GIAA->isPotentialUse(CalleeUse))
12270 return true;
12271 UsedAssumedInformation = !GIAA->isAtFixpoint();
12272 return false;
12273 };
12274
12275 auto AddPotentialCallees = [&]() {
12276 for (auto *PotentialCallee : PotentialCallees) {
12277 bool UsedAssumedInformation = false;
12278 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation))
12279 AssumedCalleesNow.insert(PotentialCallee);
12280 }
12281 };
12282
12283 // Use simplification to find potential callees, if !callees was present,
12284 // fallback to that set if necessary.
12285 bool UsedAssumedInformation = false;
12287 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values,
12288 AA::ValueScope::AnyScope,
12289 UsedAssumedInformation)) {
12290 if (PotentialCallees.empty())
12291 return indicatePessimisticFixpoint();
12292 AddPotentialCallees();
12293 }
12294
12295 // Try to find a reason for \p Fn not to be a potential callee. If none was
12296 // found, add it to the assumed callees set.
12297 auto CheckPotentialCallee = [&](Function &Fn) {
12298 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn))
12299 return false;
12300
12301 auto &CachedResult = FilterResults[&Fn];
12302 if (CachedResult.has_value())
12303 return CachedResult.value();
12304
12305 bool UsedAssumedInformation = false;
12306 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) {
12307 if (!UsedAssumedInformation)
12308 CachedResult = false;
12309 return false;
12310 }
12311
12312 int NumFnArgs = Fn.arg_size();
12313 int NumCBArgs = CB->arg_size();
12314
12315 // Check if any excess argument (which we fill up with poison) is known to
12316 // be UB on undef.
12317 for (int I = NumCBArgs; I < NumFnArgs; ++I) {
12318 bool IsKnown = false;
12319 if (AA::hasAssumedIRAttr<Attribute::NoUndef>(
12320 A, this, IRPosition::argument(*Fn.getArg(I)),
12321 DepClassTy::OPTIONAL, IsKnown)) {
12322 if (IsKnown)
12323 CachedResult = false;
12324 return false;
12325 }
12326 }
12327
12328 CachedResult = true;
12329 return true;
12330 };
12331
12332 // Check simplification result, prune known UB callees, also restrict it to
12333 // the !callees set, if present.
12334 for (auto &VAC : Values) {
12335 if (isa<UndefValue>(VAC.getValue()))
12336 continue;
12337 if (isa<ConstantPointerNull>(VAC.getValue()) &&
12338 VAC.getValue()->getType()->getPointerAddressSpace() == 0)
12339 continue;
12340 // TODO: Check for known UB, e.g., poison + noundef.
12341 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) {
12342 if (CheckPotentialCallee(*VACFn))
12343 AssumedCalleesNow.insert(VACFn);
12344 continue;
12345 }
12346 if (!PotentialCallees.empty()) {
12347 AddPotentialCallees();
12348 break;
12349 }
12350 AllCalleesKnownNow = false;
12351 }
12352
12353 if (AssumedCalleesNow == AssumedCallees &&
12354 AllCalleesKnown == AllCalleesKnownNow)
12355 return ChangeStatus::UNCHANGED;
12356
12357 std::swap(AssumedCallees, AssumedCalleesNow);
12358 AllCalleesKnown = AllCalleesKnownNow;
12359 return ChangeStatus::CHANGED;
12360 }
12361
12362 /// See AbstractAttribute::manifest(...).
12363 ChangeStatus manifest(Attributor &A) override {
12364 // If we can't specialize at all, give up now.
12365 if (!AllCalleesKnown && AssumedCallees.empty())
12366 return ChangeStatus::UNCHANGED;
12367
12368 CallBase *CB = cast<CallBase>(getCtxI());
12369 bool UsedAssumedInformation = false;
12370 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr,
12371 UsedAssumedInformation))
12372 return ChangeStatus::UNCHANGED;
12373
12374 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12375 Value *FP = CB->getCalledOperand();
12376 if (FP->getType()->getPointerAddressSpace())
12377 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0),
12378 FP->getName() + ".as0", CB->getIterator());
12379
12380 bool CBIsVoid = CB->getType()->isVoidTy();
12382 FunctionType *CSFT = CB->getFunctionType();
12383 SmallVector<Value *> CSArgs(CB->args());
12384
12385 // If we know all callees and there are none, the call site is (effectively)
12386 // dead (or UB).
12387 if (AssumedCallees.empty()) {
12388 assert(AllCalleesKnown &&
12389 "Expected all callees to be known if there are none.");
12390 A.changeToUnreachableAfterManifest(CB);
12391 return ChangeStatus::CHANGED;
12392 }
12393
12394 // Special handling for the single callee case.
12395 if (AllCalleesKnown && AssumedCallees.size() == 1) {
12396 auto *NewCallee = AssumedCallees.front();
12397 if (isLegalToPromote(*CB, NewCallee)) {
12398 promoteCall(*CB, NewCallee, nullptr);
12399 NumIndirectCallsPromoted++;
12400 return ChangeStatus::CHANGED;
12401 }
12402 Instruction *NewCall =
12403 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12404 CB->getName(), CB->getIterator());
12405 if (!CBIsVoid)
12406 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall);
12407 A.deleteAfterManifest(*CB);
12408 return ChangeStatus::CHANGED;
12409 }
12410
12411 // For each potential value we create a conditional
12412 //
12413 // ```
12414 // if (ptr == value) value(args);
12415 // else ...
12416 // ```
12417 //
12418 bool SpecializedForAnyCallees = false;
12419 bool SpecializedForAllCallees = AllCalleesKnown;
12420 ICmpInst *LastCmp = nullptr;
12421 SmallVector<Function *, 8> SkippedAssumedCallees;
12423 for (Function *NewCallee : AssumedCallees) {
12424 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee,
12425 AssumedCallees.size())) {
12426 SkippedAssumedCallees.push_back(NewCallee);
12427 SpecializedForAllCallees = false;
12428 continue;
12429 }
12430 SpecializedForAnyCallees = true;
12431
12432 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee);
12433 Instruction *ThenTI =
12434 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false);
12435 BasicBlock *CBBB = CB->getParent();
12436 A.registerManifestAddedBasicBlock(*ThenTI->getParent());
12437 A.registerManifestAddedBasicBlock(*IP->getParent());
12438 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode());
12439 BasicBlock *ElseBB;
12440 if (&*IP == CB) {
12441 ElseBB = BasicBlock::Create(ThenTI->getContext(), "",
12442 ThenTI->getFunction(), CBBB);
12443 A.registerManifestAddedBasicBlock(*ElseBB);
12444 IP = BranchInst::Create(CBBB, ElseBB)->getIterator();
12445 SplitTI->replaceUsesOfWith(CBBB, ElseBB);
12446 } else {
12447 ElseBB = IP->getParent();
12448 ThenTI->replaceUsesOfWith(ElseBB, CBBB);
12449 }
12450 CastInst *RetBC = nullptr;
12451 CallInst *NewCall = nullptr;
12452 if (isLegalToPromote(*CB, NewCallee)) {
12453 auto *CBClone = cast<CallBase>(CB->clone());
12454 CBClone->insertBefore(ThenTI->getIterator());
12455 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC));
12456 NumIndirectCallsPromoted++;
12457 } else {
12458 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs,
12459 CB->getName(), ThenTI->getIterator());
12460 }
12461 NewCalls.push_back({NewCall, RetBC});
12462 }
12463
12464 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) {
12465 if (!AllCalleesKnown)
12466 return ChangeStatus::UNCHANGED;
12467 MDBuilder MDB(IndirectCB.getContext());
12468 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees);
12469 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees);
12470 return ChangeStatus::CHANGED;
12471 };
12472
12473 if (!SpecializedForAnyCallees)
12474 return AttachCalleeMetadata(*CB);
12475
12476 // Check if we need the fallback indirect call still.
12477 if (SpecializedForAllCallees) {
12479 LastCmp->eraseFromParent();
12480 new UnreachableInst(IP->getContext(), IP);
12481 IP->eraseFromParent();
12482 } else {
12483 auto *CBClone = cast<CallInst>(CB->clone());
12484 CBClone->setName(CB->getName());
12485 CBClone->insertBefore(*IP->getParent(), IP);
12486 NewCalls.push_back({CBClone, nullptr});
12487 AttachCalleeMetadata(*CBClone);
12488 }
12489
12490 // Check if we need a PHI to merge the results.
12491 if (!CBIsVoid) {
12492 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(),
12493 CB->getName() + ".phi",
12494 CB->getParent()->getFirstInsertionPt());
12495 for (auto &It : NewCalls) {
12496 CallBase *NewCall = It.first;
12497 Instruction *CallRet = It.second ? It.second : It.first;
12498 if (CallRet->getType() == CB->getType())
12499 PHI->addIncoming(CallRet, CallRet->getParent());
12500 else if (NewCall->getType()->isVoidTy())
12501 PHI->addIncoming(PoisonValue::get(CB->getType()),
12502 NewCall->getParent());
12503 else
12504 llvm_unreachable("Call return should match or be void!");
12505 }
12506 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI);
12507 }
12508
12509 A.deleteAfterManifest(*CB);
12510 Changed = ChangeStatus::CHANGED;
12511
12512 return Changed;
12513 }
12514
12515 /// See AbstractAttribute::getAsStr().
12516 const std::string getAsStr(Attributor *A) const override {
12517 return std::string(AllCalleesKnown ? "eliminate" : "specialize") +
12518 " indirect call site with " + std::to_string(AssumedCallees.size()) +
12519 " functions";
12520 }
12521
12522 void trackStatistics() const override {
12523 if (AllCalleesKnown) {
12525 Eliminated, CallSites,
12526 "Number of indirect call sites eliminated via specialization")
12527 } else {
12528 STATS_DECLTRACK(Specialized, CallSites,
12529 "Number of indirect call sites specialized")
12530 }
12531 }
12532
12533 bool foreachCallee(function_ref<bool(Function *)> CB) const override {
12534 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB);
12535 }
12536
12537private:
12538 /// Map to remember filter results.
12540
12541 /// If the !callee metadata was present, this set will contain all potential
12542 /// callees (superset).
12543 SmallSetVector<Function *, 4> PotentialCallees;
12544
12545 /// This set contains all currently assumed calllees, which might grow over
12546 /// time.
12547 SmallSetVector<Function *, 4> AssumedCallees;
12548
12549 /// Flag to indicate if all possible callees are in the AssumedCallees set or
12550 /// if there could be others.
12551 bool AllCalleesKnown = true;
12552};
12553} // namespace
12554
12555/// --------------------- Invariant Load Pointer -------------------------------
12556namespace {
12557
12558struct AAInvariantLoadPointerImpl
12559 : public StateWrapper<BitIntegerState<uint8_t, 15>,
12560 AAInvariantLoadPointer> {
12561
12562 enum {
12563 // pointer does not alias within the bounds of the function
12564 IS_NOALIAS = 1 << 0,
12565 // pointer is not involved in any effectful instructions within the bounds
12566 // of the function
12567 IS_NOEFFECT = 1 << 1,
12568 // loads are invariant within the bounds of the function
12569 IS_LOCALLY_INVARIANT = 1 << 2,
12570 // memory lifetime is constrained within the bounds of the function
12571 IS_LOCALLY_CONSTRAINED = 1 << 3,
12572
12573 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT |
12574 IS_LOCALLY_CONSTRAINED,
12575 };
12576 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state");
12577
12578 using Base =
12580
12581 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but
12582 // pessimistic about IS_KNOWN_INVARIANT
12583 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A)
12584 : Base(IRP) {}
12585
12586 bool isKnownInvariant() const final {
12587 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED);
12588 }
12589
12590 bool isKnownLocallyInvariant() const final {
12591 if (isKnown(IS_LOCALLY_INVARIANT))
12592 return true;
12593 return isKnown(IS_NOALIAS | IS_NOEFFECT);
12594 }
12595
12596 bool isAssumedInvariant() const final {
12597 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED);
12598 }
12599
12600 bool isAssumedLocallyInvariant() const final {
12601 if (isAssumed(IS_LOCALLY_INVARIANT))
12602 return true;
12603 return isAssumed(IS_NOALIAS | IS_NOEFFECT);
12604 }
12605
12606 ChangeStatus updateImpl(Attributor &A) override {
12607 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12608
12609 Changed |= updateNoAlias(A);
12610 if (requiresNoAlias() && !isAssumed(IS_NOALIAS))
12611 return indicatePessimisticFixpoint();
12612
12613 Changed |= updateNoEffect(A);
12614
12615 Changed |= updateLocalInvariance(A);
12616
12617 return Changed;
12618 }
12619
12620 ChangeStatus manifest(Attributor &A) override {
12621 if (!isKnownInvariant())
12622 return ChangeStatus::UNCHANGED;
12623
12624 ChangeStatus Changed = ChangeStatus::UNCHANGED;
12625 const Value *Ptr = &getAssociatedValue();
12626 const auto TagInvariantLoads = [&](const Use &U, bool &) {
12627 if (U.get() != Ptr)
12628 return true;
12629 auto *I = dyn_cast<Instruction>(U.getUser());
12630 if (!I)
12631 return true;
12632
12633 // Ensure that we are only changing uses from the corresponding callgraph
12634 // SSC in the case that the AA isn't run on the entire module
12635 if (!A.isRunOn(I->getFunction()))
12636 return true;
12637
12638 if (I->hasMetadata(LLVMContext::MD_invariant_load))
12639 return true;
12640
12641 if (auto *LI = dyn_cast<LoadInst>(I)) {
12642 LI->setMetadata(LLVMContext::MD_invariant_load,
12643 MDNode::get(LI->getContext(), {}));
12644 Changed = ChangeStatus::CHANGED;
12645 }
12646 return true;
12647 };
12648
12649 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr);
12650 return Changed;
12651 }
12652
12653 /// See AbstractAttribute::getAsStr().
12654 const std::string getAsStr(Attributor *) const override {
12655 if (isKnownInvariant())
12656 return "load-invariant pointer";
12657 return "non-invariant pointer";
12658 }
12659
12660 /// See AbstractAttribute::trackStatistics().
12661 void trackStatistics() const override {}
12662
12663private:
12664 /// Indicate that noalias is required for the pointer to be invariant.
12665 bool requiresNoAlias() const {
12666 switch (getPositionKind()) {
12667 default:
12668 // Conservatively default to require noalias.
12669 return true;
12670 case IRP_FLOAT:
12671 case IRP_RETURNED:
12672 case IRP_CALL_SITE:
12673 return false;
12674 case IRP_CALL_SITE_RETURNED: {
12675 const auto &CB = cast<CallBase>(getAnchorValue());
12677 &CB, /*MustPreserveNullness=*/false);
12678 }
12679 case IRP_ARGUMENT: {
12680 const Function *F = getAssociatedFunction();
12681 assert(F && "no associated function for argument");
12682 return !isCallableCC(F->getCallingConv());
12683 }
12684 }
12685 }
12686
12687 bool isExternal() const {
12688 const Function *F = getAssociatedFunction();
12689 if (!F)
12690 return true;
12691 return isCallableCC(F->getCallingConv()) &&
12692 getPositionKind() != IRP_CALL_SITE_RETURNED;
12693 }
12694
12695 ChangeStatus updateNoAlias(Attributor &A) {
12696 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS))
12697 return ChangeStatus::UNCHANGED;
12698
12699 // Try to use AANoAlias.
12700 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>(
12701 getIRPosition(), this, DepClassTy::REQUIRED)) {
12702 if (ANoAlias->isKnownNoAlias()) {
12703 addKnownBits(IS_NOALIAS);
12704 return ChangeStatus::CHANGED;
12705 }
12706
12707 if (!ANoAlias->isAssumedNoAlias()) {
12708 removeAssumedBits(IS_NOALIAS);
12709 return ChangeStatus::CHANGED;
12710 }
12711
12712 return ChangeStatus::UNCHANGED;
12713 }
12714
12715 // Try to infer noalias from argument attribute, since it is applicable for
12716 // the duration of the function.
12717 if (const Argument *Arg = getAssociatedArgument()) {
12718 if (Arg->hasNoAliasAttr()) {
12719 addKnownBits(IS_NOALIAS);
12720 return ChangeStatus::UNCHANGED;
12721 }
12722
12723 // Noalias information is not provided, and cannot be inferred,
12724 // so we conservatively assume the pointer aliases.
12725 removeAssumedBits(IS_NOALIAS);
12726 return ChangeStatus::CHANGED;
12727 }
12728
12729 return ChangeStatus::UNCHANGED;
12730 }
12731
12732 ChangeStatus updateNoEffect(Attributor &A) {
12733 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT))
12734 return ChangeStatus::UNCHANGED;
12735
12736 if (!getAssociatedFunction())
12737 return indicatePessimisticFixpoint();
12738
12739 if (isa<AllocaInst>(&getAssociatedValue()))
12740 return indicatePessimisticFixpoint();
12741
12742 const auto HasNoEffectLoads = [&](const Use &U, bool &) {
12743 const auto *LI = dyn_cast<LoadInst>(U.getUser());
12744 return !LI || !LI->mayHaveSideEffects();
12745 };
12746 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue()))
12747 return indicatePessimisticFixpoint();
12748
12749 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>(
12750 getIRPosition(), this, DepClassTy::REQUIRED)) {
12751 // For non-instructions, try to use AAMemoryBehavior to infer the readonly
12752 // attribute
12753 if (!AMemoryBehavior->isAssumedReadOnly())
12754 return indicatePessimisticFixpoint();
12755
12756 if (AMemoryBehavior->isKnownReadOnly()) {
12757 addKnownBits(IS_NOEFFECT);
12758 return ChangeStatus::UNCHANGED;
12759 }
12760
12761 return ChangeStatus::UNCHANGED;
12762 }
12763
12764 if (const Argument *Arg = getAssociatedArgument()) {
12765 if (Arg->onlyReadsMemory()) {
12766 addKnownBits(IS_NOEFFECT);
12767 return ChangeStatus::UNCHANGED;
12768 }
12769
12770 // Readonly information is not provided, and cannot be inferred from
12771 // AAMemoryBehavior.
12772 return indicatePessimisticFixpoint();
12773 }
12774
12775 return ChangeStatus::UNCHANGED;
12776 }
12777
12778 ChangeStatus updateLocalInvariance(Attributor &A) {
12779 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT))
12780 return ChangeStatus::UNCHANGED;
12781
12782 // try to infer invariance from underlying objects
12783 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
12784 getIRPosition(), this, DepClassTy::REQUIRED);
12785 if (!AUO)
12786 return ChangeStatus::UNCHANGED;
12787
12788 bool UsedAssumedInformation = false;
12789 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) {
12790 if (!V.getType()->isPointerTy())
12791 return true;
12792 const auto *IsInvariantLoadPointer =
12793 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this,
12794 DepClassTy::REQUIRED);
12795 // Conservatively fail if invariance cannot be inferred.
12796 if (!IsInvariantLoadPointer)
12797 return false;
12798
12799 if (IsInvariantLoadPointer->isKnownLocallyInvariant())
12800 return true;
12801 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant())
12802 return false;
12803
12804 UsedAssumedInformation = true;
12805 return true;
12806 };
12807 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer))
12808 return indicatePessimisticFixpoint();
12809
12810 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) {
12812 CB, /*MustPreserveNullness=*/false)) {
12813 for (const Value *Arg : CB->args()) {
12814 if (!IsLocallyInvariantLoadIfPointer(*Arg))
12815 return indicatePessimisticFixpoint();
12816 }
12817 }
12818 }
12819
12820 if (!UsedAssumedInformation) {
12821 // Pointer is known and not just assumed to be locally invariant.
12822 addKnownBits(IS_LOCALLY_INVARIANT);
12823 return ChangeStatus::CHANGED;
12824 }
12825
12826 return ChangeStatus::UNCHANGED;
12827 }
12828};
12829
12830struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl {
12831 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A)
12832 : AAInvariantLoadPointerImpl(IRP, A) {}
12833};
12834
12835struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl {
12836 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A)
12837 : AAInvariantLoadPointerImpl(IRP, A) {}
12838
12839 void initialize(Attributor &) override {
12840 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12841 }
12842};
12843
12844struct AAInvariantLoadPointerCallSiteReturned final
12845 : AAInvariantLoadPointerImpl {
12846 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A)
12847 : AAInvariantLoadPointerImpl(IRP, A) {}
12848
12849 void initialize(Attributor &A) override {
12850 const Function *F = getAssociatedFunction();
12851 assert(F && "no associated function for return from call");
12852
12853 if (!F->isDeclaration() && !F->isIntrinsic())
12854 return AAInvariantLoadPointerImpl::initialize(A);
12855
12856 const auto &CB = cast<CallBase>(getAnchorValue());
12858 &CB, /*MustPreserveNullness=*/false))
12859 return AAInvariantLoadPointerImpl::initialize(A);
12860
12861 if (F->onlyReadsMemory() && F->hasNoSync())
12862 return AAInvariantLoadPointerImpl::initialize(A);
12863
12864 // At this point, the function is opaque, so we conservatively assume
12865 // non-invariance.
12866 indicatePessimisticFixpoint();
12867 }
12868};
12869
12870struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl {
12871 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A)
12872 : AAInvariantLoadPointerImpl(IRP, A) {}
12873
12874 void initialize(Attributor &) override {
12875 const Function *F = getAssociatedFunction();
12876 assert(F && "no associated function for argument");
12877
12878 if (!isCallableCC(F->getCallingConv())) {
12879 addKnownBits(IS_LOCALLY_CONSTRAINED);
12880 return;
12881 }
12882
12883 if (!F->hasLocalLinkage())
12884 removeAssumedBits(IS_LOCALLY_CONSTRAINED);
12885 }
12886};
12887
12888struct AAInvariantLoadPointerCallSiteArgument final
12889 : AAInvariantLoadPointerImpl {
12890 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A)
12891 : AAInvariantLoadPointerImpl(IRP, A) {}
12892};
12893} // namespace
12894
12895/// ------------------------ Address Space ------------------------------------
12896namespace {
12897
12898template <typename InstType>
12899static bool makeChange(Attributor &A, InstType *MemInst, const Use &U,
12900 Value *OriginalValue, PointerType *NewPtrTy,
12901 bool UseOriginalValue) {
12902 if (U.getOperandNo() != InstType::getPointerOperandIndex())
12903 return false;
12904
12905 if (MemInst->isVolatile()) {
12906 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(
12907 *MemInst->getFunction());
12908 unsigned NewAS = NewPtrTy->getPointerAddressSpace();
12909 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS))
12910 return false;
12911 }
12912
12913 if (UseOriginalValue) {
12914 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue);
12915 return true;
12916 }
12917
12918 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy);
12919 CastInst->insertBefore(MemInst->getIterator());
12920 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst);
12921 return true;
12922}
12923
12924struct AAAddressSpaceImpl : public AAAddressSpace {
12925 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A)
12926 : AAAddressSpace(IRP, A) {}
12927
12928 uint32_t getAddressSpace() const override {
12929 assert(isValidState() && "the AA is invalid");
12930 return AssumedAddressSpace;
12931 }
12932
12933 /// See AbstractAttribute::initialize(...).
12934 void initialize(Attributor &A) override {
12935 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
12936 "Associated value is not a pointer");
12937
12938 if (!A.getInfoCache().getFlatAddressSpace().has_value()) {
12939 indicatePessimisticFixpoint();
12940 return;
12941 }
12942
12943 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12944 unsigned AS = getAssociatedType()->getPointerAddressSpace();
12945 if (AS != FlatAS) {
12946 [[maybe_unused]] bool R = takeAddressSpace(AS);
12947 assert(R && "The take should happen");
12948 indicateOptimisticFixpoint();
12949 }
12950 }
12951
12952 ChangeStatus updateImpl(Attributor &A) override {
12953 uint32_t OldAddressSpace = AssumedAddressSpace;
12954 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
12955
12956 auto CheckAddressSpace = [&](Value &Obj) {
12957 // Ignore undef.
12958 if (isa<UndefValue>(&Obj))
12959 return true;
12960
12961 // If the object already has a non-flat address space, we simply take it.
12962 unsigned ObjAS = Obj.getType()->getPointerAddressSpace();
12963 if (ObjAS != FlatAS)
12964 return takeAddressSpace(ObjAS);
12965
12966 // At this point, we know Obj is in the flat address space. For a final
12967 // attempt, we want to use getAssumedAddrSpace, but first we must get the
12968 // associated function, if possible.
12969 Function *F = nullptr;
12970 if (auto *Arg = dyn_cast<Argument>(&Obj))
12971 F = Arg->getParent();
12972 else if (auto *I = dyn_cast<Instruction>(&Obj))
12973 F = I->getFunction();
12974
12975 // Use getAssumedAddrSpace if the associated function exists.
12976 if (F) {
12977 auto *TTI =
12978 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F);
12979 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj);
12980 if (AssumedAS != ~0U)
12981 return takeAddressSpace(AssumedAS);
12982 }
12983
12984 // Now we can't do anything else but to take the flat AS.
12985 return takeAddressSpace(FlatAS);
12986 };
12987
12988 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this,
12989 DepClassTy::REQUIRED);
12990 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
12991 return indicatePessimisticFixpoint();
12992
12993 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED
12994 : ChangeStatus::CHANGED;
12995 }
12996
12997 /// See AbstractAttribute::manifest(...).
12998 ChangeStatus manifest(Attributor &A) override {
12999 unsigned NewAS = getAddressSpace();
13000
13001 if (NewAS == InvalidAddressSpace ||
13002 NewAS == getAssociatedType()->getPointerAddressSpace())
13003 return ChangeStatus::UNCHANGED;
13004
13005 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13006
13007 Value *AssociatedValue = &getAssociatedValue();
13008 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS);
13009
13010 PointerType *NewPtrTy =
13011 PointerType::get(getAssociatedType()->getContext(), NewAS);
13012 bool UseOriginalValue =
13013 OriginalValue->getType()->getPointerAddressSpace() == NewAS;
13014
13015 bool Changed = false;
13016
13017 auto Pred = [&](const Use &U, bool &) {
13018 if (U.get() != AssociatedValue)
13019 return true;
13020 auto *Inst = dyn_cast<Instruction>(U.getUser());
13021 if (!Inst)
13022 return true;
13023 // This is a WA to make sure we only change uses from the corresponding
13024 // CGSCC if the AA is run on CGSCC instead of the entire module.
13025 if (!A.isRunOn(Inst->getFunction()))
13026 return true;
13027 if (auto *LI = dyn_cast<LoadInst>(Inst)) {
13028 Changed |=
13029 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13030 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) {
13031 Changed |=
13032 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue);
13033 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) {
13034 Changed |=
13035 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue);
13036 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
13037 Changed |=
13038 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue);
13039 }
13040 return true;
13041 };
13042
13043 // It doesn't matter if we can't check all uses as we can simply
13044 // conservatively ignore those that can not be visited.
13045 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(),
13046 /* CheckBBLivenessOnly */ true);
13047
13048 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13049 }
13050
13051 /// See AbstractAttribute::getAsStr().
13052 const std::string getAsStr(Attributor *A) const override {
13053 if (!isValidState())
13054 return "addrspace(<invalid>)";
13055 return "addrspace(" +
13056 (AssumedAddressSpace == InvalidAddressSpace
13057 ? "none"
13058 : std::to_string(AssumedAddressSpace)) +
13059 ")";
13060 }
13061
13062private:
13063 uint32_t AssumedAddressSpace = InvalidAddressSpace;
13064
13065 bool takeAddressSpace(uint32_t AS) {
13066 if (AssumedAddressSpace == InvalidAddressSpace) {
13067 AssumedAddressSpace = AS;
13068 return true;
13069 }
13070 return AssumedAddressSpace == AS;
13071 }
13072
13073 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) {
13074 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) {
13075 assert(I->getSrcAddressSpace() != FlatAS &&
13076 "there should not be flat AS -> non-flat AS");
13077 return I->getPointerOperand();
13078 }
13079 if (auto *C = dyn_cast<ConstantExpr>(V))
13080 if (C->getOpcode() == Instruction::AddrSpaceCast) {
13081 assert(C->getOperand(0)->getType()->getPointerAddressSpace() !=
13082 FlatAS &&
13083 "there should not be flat AS -> non-flat AS X");
13084 return C->getOperand(0);
13085 }
13086 return V;
13087 }
13088};
13089
13090struct AAAddressSpaceFloating final : AAAddressSpaceImpl {
13091 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A)
13092 : AAAddressSpaceImpl(IRP, A) {}
13093
13094 void trackStatistics() const override {
13096 }
13097};
13098
13099struct AAAddressSpaceReturned final : AAAddressSpaceImpl {
13100 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A)
13101 : AAAddressSpaceImpl(IRP, A) {}
13102
13103 /// See AbstractAttribute::initialize(...).
13104 void initialize(Attributor &A) override {
13105 // TODO: we don't rewrite function argument for now because it will need to
13106 // rewrite the function signature and all call sites.
13107 (void)indicatePessimisticFixpoint();
13108 }
13109
13110 void trackStatistics() const override {
13111 STATS_DECLTRACK_FNRET_ATTR(addrspace);
13112 }
13113};
13114
13115struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl {
13116 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13117 : AAAddressSpaceImpl(IRP, A) {}
13118
13119 void trackStatistics() const override {
13120 STATS_DECLTRACK_CSRET_ATTR(addrspace);
13121 }
13122};
13123
13124struct AAAddressSpaceArgument final : AAAddressSpaceImpl {
13125 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A)
13126 : AAAddressSpaceImpl(IRP, A) {}
13127
13128 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); }
13129};
13130
13131struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl {
13132 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13133 : AAAddressSpaceImpl(IRP, A) {}
13134
13135 /// See AbstractAttribute::initialize(...).
13136 void initialize(Attributor &A) override {
13137 // TODO: we don't rewrite call site argument for now because it will need to
13138 // rewrite the function signature of the callee.
13139 (void)indicatePessimisticFixpoint();
13140 }
13141
13142 void trackStatistics() const override {
13143 STATS_DECLTRACK_CSARG_ATTR(addrspace);
13144 }
13145};
13146} // namespace
13147
13148/// ------------------------ No Alias Address Space ---------------------------
13149// This attribute assumes flat address space can alias all other address space
13150
13151// TODO: this is similar to AAAddressSpace, most of the code should be merged.
13152// But merging it created failing cased on gateway test that cannot be
13153// reproduced locally. So should open a seperated PR to hande the merge of
13154// AANoAliasAddrSpace and AAAddressSpace attribute
13155
13156namespace {
13157struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace {
13158 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A)
13159 : AANoAliasAddrSpace(IRP, A) {}
13160
13161 void initialize(Attributor &A) override {
13162 assert(getAssociatedType()->isPtrOrPtrVectorTy() &&
13163 "Associated value is not a pointer");
13164
13165 resetASRanges(A);
13166
13167 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace();
13168 if (!FlatAS.has_value()) {
13169 indicatePessimisticFixpoint();
13170 return;
13171 }
13172
13173 removeAS(*FlatAS);
13174
13175 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13176 if (AS != *FlatAS) {
13177 removeAS(AS);
13178 indicateOptimisticFixpoint();
13179 }
13180 }
13181
13182 ChangeStatus updateImpl(Attributor &A) override {
13183 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13184 uint32_t OldAssumed = getAssumed();
13185
13186 auto CheckAddressSpace = [&](Value &Obj) {
13187 if (isa<PoisonValue>(&Obj))
13188 return true;
13189
13190 unsigned AS = Obj.getType()->getPointerAddressSpace();
13191 if (AS == FlatAS)
13192 return false;
13193
13194 removeAS(Obj.getType()->getPointerAddressSpace());
13195 return true;
13196 };
13197
13198 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(
13199 getIRPosition(), this, DepClassTy::REQUIRED);
13200 if (!AUO->forallUnderlyingObjects(CheckAddressSpace))
13201 return indicatePessimisticFixpoint();
13202
13203 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED
13204 : ChangeStatus::CHANGED;
13205 }
13206
13207 /// See AbstractAttribute::manifest(...).
13208 ChangeStatus manifest(Attributor &A) override {
13209 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value();
13210
13211 unsigned AS = getAssociatedType()->getPointerAddressSpace();
13212 if (AS != FlatAS || Map.empty())
13213 return ChangeStatus::UNCHANGED;
13214
13215 LLVMContext &Ctx = getAssociatedValue().getContext();
13216 MDNode *NoAliasASNode = nullptr;
13217 MDBuilder MDB(Ctx);
13218 // Has to use iterator to get the range info.
13219 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13220 if (!I.value())
13221 continue;
13222 unsigned Upper = I.stop();
13223 unsigned Lower = I.start();
13224 if (!NoAliasASNode) {
13225 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13226 continue;
13227 }
13228 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1));
13229 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange);
13230 }
13231
13232 Value *AssociatedValue = &getAssociatedValue();
13233 bool Changed = false;
13234
13235 auto AddNoAliasAttr = [&](const Use &U, bool &) {
13236 if (U.get() != AssociatedValue)
13237 return true;
13238 Instruction *Inst = dyn_cast<Instruction>(U.getUser());
13239 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace))
13240 return true;
13241 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) &&
13242 !isa<AtomicCmpXchgInst>(Inst) && !isa<AtomicRMWInst>(Inst))
13243 return true;
13244 if (!A.isRunOn(Inst->getFunction()))
13245 return true;
13246 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode);
13247 Changed = true;
13248 return true;
13249 };
13250 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue,
13251 /*CheckBBLivenessOnly=*/true);
13252 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
13253 }
13254
13255 /// See AbstractAttribute::getAsStr().
13256 const std::string getAsStr(Attributor *A) const override {
13257 if (!isValidState())
13258 return "<invalid>";
13259 std::string Str;
13261 OS << "CanNotBeAddrSpace(";
13262 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) {
13263 unsigned Upper = I.stop();
13264 unsigned Lower = I.start();
13265 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')';
13266 }
13267 OS << " )";
13268 return OS.str();
13269 }
13270
13271private:
13272 void removeAS(unsigned AS) {
13273 RangeMap::iterator I = Map.find(AS);
13274
13275 if (I != Map.end()) {
13276 unsigned Upper = I.stop();
13277 unsigned Lower = I.start();
13278 I.erase();
13279 if (Upper == Lower)
13280 return;
13281 if (AS != ~((unsigned)0) && AS + 1 <= Upper)
13282 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true);
13283 if (AS != 0 && Lower <= AS - 1)
13284 Map.insert(Lower, AS - 1, true);
13285 }
13286 }
13287
13288 void resetASRanges(Attributor &A) {
13289 Map.clear();
13290 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true);
13291 }
13292};
13293
13294struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl {
13295 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A)
13296 : AANoAliasAddrSpaceImpl(IRP, A) {}
13297
13298 void trackStatistics() const override {
13299 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace);
13300 }
13301};
13302
13303struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl {
13304 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A)
13305 : AANoAliasAddrSpaceImpl(IRP, A) {}
13306
13307 void trackStatistics() const override {
13308 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace);
13309 }
13310};
13311
13312struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl {
13313 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A)
13314 : AANoAliasAddrSpaceImpl(IRP, A) {}
13315
13316 void trackStatistics() const override {
13317 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace);
13318 }
13319};
13320
13321struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl {
13322 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A)
13323 : AANoAliasAddrSpaceImpl(IRP, A) {}
13324
13325 void trackStatistics() const override {
13326 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace);
13327 }
13328};
13329
13330struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl {
13331 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A)
13332 : AANoAliasAddrSpaceImpl(IRP, A) {}
13333
13334 void trackStatistics() const override {
13335 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace);
13336 }
13337};
13338} // namespace
13339/// ----------- Allocation Info ----------
13340namespace {
13341struct AAAllocationInfoImpl : public AAAllocationInfo {
13342 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A)
13343 : AAAllocationInfo(IRP, A) {}
13344
13345 std::optional<TypeSize> getAllocatedSize() const override {
13346 assert(isValidState() && "the AA is invalid");
13347 return AssumedAllocatedSize;
13348 }
13349
13350 std::optional<TypeSize> findInitialAllocationSize(Instruction *I,
13351 const DataLayout &DL) {
13352
13353 // TODO: implement case for malloc like instructions
13354 switch (I->getOpcode()) {
13355 case Instruction::Alloca: {
13356 AllocaInst *AI = cast<AllocaInst>(I);
13357 return AI->getAllocationSize(DL);
13358 }
13359 default:
13360 return std::nullopt;
13361 }
13362 }
13363
13364 ChangeStatus updateImpl(Attributor &A) override {
13365
13366 const IRPosition &IRP = getIRPosition();
13367 Instruction *I = IRP.getCtxI();
13368
13369 // TODO: update check for malloc like calls
13370 if (!isa<AllocaInst>(I))
13371 return indicatePessimisticFixpoint();
13372
13373 bool IsKnownNoCapture;
13374 if (!AA::hasAssumedIRAttr<Attribute::Captures>(
13375 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture))
13376 return indicatePessimisticFixpoint();
13377
13378 const AAPointerInfo *PI =
13379 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED);
13380
13381 if (!PI)
13382 return indicatePessimisticFixpoint();
13383
13384 if (!PI->getState().isValidState() || PI->reachesReturn())
13385 return indicatePessimisticFixpoint();
13386
13387 const DataLayout &DL = A.getDataLayout();
13388 const auto AllocationSize = findInitialAllocationSize(I, DL);
13389
13390 // If allocation size is nullopt, we give up.
13391 if (!AllocationSize)
13392 return indicatePessimisticFixpoint();
13393
13394 // For zero sized allocations, we give up.
13395 // Since we can't reduce further
13396 if (*AllocationSize == 0)
13397 return indicatePessimisticFixpoint();
13398
13399 int64_t BinSize = PI->numOffsetBins();
13400
13401 // TODO: implement for multiple bins
13402 if (BinSize > 1)
13403 return indicatePessimisticFixpoint();
13404
13405 if (BinSize == 0) {
13406 auto NewAllocationSize = std::make_optional<TypeSize>(0, false);
13407 if (!changeAllocationSize(NewAllocationSize))
13408 return ChangeStatus::UNCHANGED;
13409 return ChangeStatus::CHANGED;
13410 }
13411
13412 // TODO: refactor this to be part of multiple bin case
13413 const auto &It = PI->begin();
13414
13415 // TODO: handle if Offset is not zero
13416 if (It->first.Offset != 0)
13417 return indicatePessimisticFixpoint();
13418
13419 uint64_t SizeOfBin = It->first.Offset + It->first.Size;
13420
13421 if (SizeOfBin >= *AllocationSize)
13422 return indicatePessimisticFixpoint();
13423
13424 auto NewAllocationSize = std::make_optional<TypeSize>(SizeOfBin * 8, false);
13425
13426 if (!changeAllocationSize(NewAllocationSize))
13427 return ChangeStatus::UNCHANGED;
13428
13429 return ChangeStatus::CHANGED;
13430 }
13431
13432 /// See AbstractAttribute::manifest(...).
13433 ChangeStatus manifest(Attributor &A) override {
13434
13435 assert(isValidState() &&
13436 "Manifest should only be called if the state is valid.");
13437
13438 Instruction *I = getIRPosition().getCtxI();
13439
13440 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue();
13441
13442 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8;
13443
13444 switch (I->getOpcode()) {
13445 // TODO: add case for malloc like calls
13446 case Instruction::Alloca: {
13447
13448 AllocaInst *AI = cast<AllocaInst>(I);
13449
13450 Type *CharType = Type::getInt8Ty(I->getContext());
13451
13452 auto *NumBytesToValue =
13453 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate));
13454
13455 BasicBlock::iterator insertPt = AI->getIterator();
13456 insertPt = std::next(insertPt);
13457 AllocaInst *NewAllocaInst =
13458 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue,
13459 AI->getAlign(), AI->getName(), insertPt);
13460
13461 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst))
13462 return ChangeStatus::CHANGED;
13463
13464 break;
13465 }
13466 default:
13467 break;
13468 }
13469
13470 return ChangeStatus::UNCHANGED;
13471 }
13472
13473 /// See AbstractAttribute::getAsStr().
13474 const std::string getAsStr(Attributor *A) const override {
13475 if (!isValidState())
13476 return "allocationinfo(<invalid>)";
13477 return "allocationinfo(" +
13478 (AssumedAllocatedSize == HasNoAllocationSize
13479 ? "none"
13480 : std::to_string(AssumedAllocatedSize->getFixedValue())) +
13481 ")";
13482 }
13483
13484private:
13485 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize;
13486
13487 // Maintain the computed allocation size of the object.
13488 // Returns (bool) weather the size of the allocation was modified or not.
13489 bool changeAllocationSize(std::optional<TypeSize> Size) {
13490 if (AssumedAllocatedSize == HasNoAllocationSize ||
13491 AssumedAllocatedSize != Size) {
13492 AssumedAllocatedSize = Size;
13493 return true;
13494 }
13495 return false;
13496 }
13497};
13498
13499struct AAAllocationInfoFloating : AAAllocationInfoImpl {
13500 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A)
13501 : AAAllocationInfoImpl(IRP, A) {}
13502
13503 void trackStatistics() const override {
13504 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo);
13505 }
13506};
13507
13508struct AAAllocationInfoReturned : AAAllocationInfoImpl {
13509 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A)
13510 : AAAllocationInfoImpl(IRP, A) {}
13511
13512 /// See AbstractAttribute::initialize(...).
13513 void initialize(Attributor &A) override {
13514 // TODO: we don't rewrite function argument for now because it will need to
13515 // rewrite the function signature and all call sites
13516 (void)indicatePessimisticFixpoint();
13517 }
13518
13519 void trackStatistics() const override {
13520 STATS_DECLTRACK_FNRET_ATTR(allocationinfo);
13521 }
13522};
13523
13524struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl {
13525 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A)
13526 : AAAllocationInfoImpl(IRP, A) {}
13527
13528 void trackStatistics() const override {
13529 STATS_DECLTRACK_CSRET_ATTR(allocationinfo);
13530 }
13531};
13532
13533struct AAAllocationInfoArgument : AAAllocationInfoImpl {
13534 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A)
13535 : AAAllocationInfoImpl(IRP, A) {}
13536
13537 void trackStatistics() const override {
13538 STATS_DECLTRACK_ARG_ATTR(allocationinfo);
13539 }
13540};
13541
13542struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl {
13543 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A)
13544 : AAAllocationInfoImpl(IRP, A) {}
13545
13546 /// See AbstractAttribute::initialize(...).
13547 void initialize(Attributor &A) override {
13548
13549 (void)indicatePessimisticFixpoint();
13550 }
13551
13552 void trackStatistics() const override {
13553 STATS_DECLTRACK_CSARG_ATTR(allocationinfo);
13554 }
13555};
13556} // namespace
13557
13558const char AANoUnwind::ID = 0;
13559const char AANoSync::ID = 0;
13560const char AANoFree::ID = 0;
13561const char AANonNull::ID = 0;
13562const char AAMustProgress::ID = 0;
13563const char AANoRecurse::ID = 0;
13564const char AANonConvergent::ID = 0;
13565const char AAWillReturn::ID = 0;
13566const char AAUndefinedBehavior::ID = 0;
13567const char AANoAlias::ID = 0;
13568const char AAIntraFnReachability::ID = 0;
13569const char AANoReturn::ID = 0;
13570const char AAIsDead::ID = 0;
13571const char AADereferenceable::ID = 0;
13572const char AAAlign::ID = 0;
13573const char AAInstanceInfo::ID = 0;
13574const char AANoCapture::ID = 0;
13575const char AAValueSimplify::ID = 0;
13576const char AAHeapToStack::ID = 0;
13577const char AAPrivatizablePtr::ID = 0;
13578const char AAMemoryBehavior::ID = 0;
13579const char AAMemoryLocation::ID = 0;
13580const char AAValueConstantRange::ID = 0;
13581const char AAPotentialConstantValues::ID = 0;
13582const char AAPotentialValues::ID = 0;
13583const char AANoUndef::ID = 0;
13584const char AANoFPClass::ID = 0;
13585const char AACallEdges::ID = 0;
13586const char AAInterFnReachability::ID = 0;
13587const char AAPointerInfo::ID = 0;
13588const char AAAssumptionInfo::ID = 0;
13589const char AAUnderlyingObjects::ID = 0;
13590const char AAInvariantLoadPointer::ID = 0;
13591const char AAAddressSpace::ID = 0;
13592const char AANoAliasAddrSpace::ID = 0;
13593const char AAAllocationInfo::ID = 0;
13594const char AAIndirectCallInfo::ID = 0;
13595const char AAGlobalValueInfo::ID = 0;
13596const char AADenormalFPMath::ID = 0;
13597
13598// Macro magic to create the static generator function for attributes that
13599// follow the naming scheme.
13600
13601#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
13602 case IRPosition::PK: \
13603 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
13604
13605#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
13606 case IRPosition::PK: \
13607 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \
13608 ++NumAAs; \
13609 break;
13610
13611#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13612 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13613 CLASS *AA = nullptr; \
13614 switch (IRP.getPositionKind()) { \
13615 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13616 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13617 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13618 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13619 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13620 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13621 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13622 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13623 } \
13624 return *AA; \
13625 }
13626
13627#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13628 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13629 CLASS *AA = nullptr; \
13630 switch (IRP.getPositionKind()) { \
13631 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13632 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
13633 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13634 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13635 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13636 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13637 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13638 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13639 } \
13640 return *AA; \
13641 }
13642
13643#define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \
13644 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13645 CLASS *AA = nullptr; \
13646 switch (IRP.getPositionKind()) { \
13647 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \
13648 default: \
13649 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \
13650 " position!"); \
13651 } \
13652 return *AA; \
13653 }
13654
13655#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13656 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13657 CLASS *AA = nullptr; \
13658 switch (IRP.getPositionKind()) { \
13659 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13660 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13661 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13662 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13663 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13664 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
13665 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13666 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13667 } \
13668 return *AA; \
13669 }
13670
13671#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13672 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13673 CLASS *AA = nullptr; \
13674 switch (IRP.getPositionKind()) { \
13675 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13676 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
13677 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
13678 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13679 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
13680 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
13681 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
13682 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13683 } \
13684 return *AA; \
13685 }
13686
13687#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
13688 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
13689 CLASS *AA = nullptr; \
13690 switch (IRP.getPositionKind()) { \
13691 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
13692 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
13693 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
13694 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
13695 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
13696 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
13697 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
13698 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
13699 } \
13700 return *AA; \
13701 }
13702
13712
13730
13735
13740
13747
13749
13750#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
13751#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
13752#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
13753#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
13754#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
13755#undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION
13756#undef SWITCH_PK_CREATE
13757#undef SWITCH_PK_INV
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
AMDGPU Register Bank Select
Rewrite undef for PHI
This file implements a class to represent arbitrary precision integral constant values and operations...
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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 const Value * getPointerOperand(const Instruction *I, bool AllowVolatile)
Get pointer operand of memory accessing instruction.
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)
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static bool isReachableImpl(SmallVectorImpl< BasicBlock * > &Worklist, const StopSetT &StopSet, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet, const DominatorTree *DT, const LoopInfo *LI)
Definition: CFG.cpp:135
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
DXIL Forward Handle Accesses
DXIL Resource Access
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
Performs the initial survey of the specified function
Given that RA is a live value
This file defines DenseMapInfo traits for DenseMap.
T Content
uint32_t Index
uint64_t Size
#define Check(C,...)
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
#define T
#define T1
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
if(PassOpts->AAPipeline)
static StringRef getName(Value *V)
Basic Register Allocator
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
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.
raw_pwrite_stream & OS
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:167
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:39
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
@ Floating
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
A manager for alias analyses.
A private abstract base class describing the concept of an individual alias analysis implementation.
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition: APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1562
AbstractCallSite.
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.
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
Definition: Instructions.h:64
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:128
unsigned getAddressSpace() const
Return the address space for the allocation.
Definition: Instructions.h:106
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:32
LLVM_ABI bool hasNoAliasAttr() const
Return true if this argument has the noalias attribute.
Definition: Function.cpp:273
LLVM_ABI bool onlyReadsMemory() const
Return true if this argument has the readonly or readnone attribute.
Definition: Function.cpp:309
LLVM_ABI bool hasPointeeInMemoryValueAttr() const
Return true if this argument has the byval, sret, inalloca, preallocated, or byref attribute.
Definition: Function.cpp:172
LLVM_ABI bool hasReturnedAttr() const
Return true if this argument has the returned attribute.
Definition: Function.cpp:297
LLVM_ABI bool hasByValAttr() const
Return true if this argument has the byval attribute.
Definition: Function.cpp:128
const Function * getParent() const
Definition: Argument.h:44
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
Definition: Argument.h:50
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:95
static LLVM_ABI Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:244
LLVM_ABI FPClassTest getNoFPClass() const
Return the FPClassTest for nofpclass.
Definition: Attributes.cpp:504
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:372
LLVM_ABI MemoryEffects getMemoryEffects() const
Returns memory effects.
Definition: Attributes.cpp:492
static LLVM_ABI Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:250
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
Definition: Attributes.cpp:286
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition: Attributes.h:88
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
Definition: Attributes.cpp:291
static bool isEnumAttrKind(AttrKind Kind)
Definition: Attributes.h:101
static LLVM_ABI Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
Definition: Attributes.cpp:281
LLVM_ABI CaptureInfo getCaptureInfo() const
Returns information from captures attribute.
Definition: Attributes.cpp:498
static LLVM_ABI Attribute getWithAlignment(LLVMContext &Context, Align Alignment)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:234
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...
Definition: BasicBlock.cpp:393
const Instruction & front() const
Definition: BasicBlock.h:482
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:213
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:233
BinaryOps getOpcode() const
Definition: InstrTypes.h:374
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1348
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.
Definition: InstrTypes.h:1359
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
const Use & getCalledOperandUse() const
Definition: InstrTypes.h:1342
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Definition: InstrTypes.h:1303
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
Definition: InstrTypes.h:1292
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
Definition: InstrTypes.h:2016
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1967
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1205
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.
Definition: InstrTypes.h:1283
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
Definition: InstrTypes.h:1323
unsigned arg_size() const
Definition: InstrTypes.h:1290
bool isArgOperand(const Use *U) const
Definition: InstrTypes.h:1312
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition: ModRef.h:367
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:448
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
Definition: InstrTypes.h:612
LLVM_ABI bool isIntegerCast() const
There are several places where we need to know if a cast instruction only deals with integer source a...
Type * getDestTy() const
Return the destination type, as a convenience.
Definition: InstrTypes.h:619
This class is the base class for the comparison instructions.
Definition: InstrTypes.h:666
bool isEquality() const
Determine if this is an equals/not equals predicate.
Definition: InstrTypes.h:917
bool isFalseWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:950
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:678
@ ICMP_EQ
equal
Definition: InstrTypes.h:699
@ ICMP_NE
not equal
Definition: InstrTypes.h:700
bool isTrueWhenEqual() const
This is just a convenience.
Definition: InstrTypes.h:944
Predicate getPredicate() const
Return the predicate for this instruction.
Definition: InstrTypes.h:767
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:1120
static LLVM_ABI Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
Definition: Constants.cpp:2564
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:868
This class represents a range of values.
Definition: ConstantRange.h:47
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.
LLVM_ABI APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
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.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
LLVM_ABI APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
This is an important base class in LLVM.
Definition: Constant.h:43
Analysis pass which computes a CycleInfo.
Definition: CycleAnalysis.h:46
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:124
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:165
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:229
unsigned size() const
Definition: DenseMap.h:108
iterator begin()
Definition: DenseMap.h:78
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:161
iterator end()
Definition: DenseMap.h:81
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition: DenseMap.h:156
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:214
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:284
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:165
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Definition: Dominators.cpp:135
An instruction for ordering other memory operations.
Definition: Instructions.h:429
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
const BasicBlock & getEntryBlock() const
Definition: Function.h:807
iterator_range< arg_iterator > args()
Definition: Function.h:890
const Function & getFunction() const
Definition: Function.h:164
size_t arg_size() const
Definition: Function.h:899
Argument * getArg(unsigned i) const
Definition: Function.h:884
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:727
CycleT * getCycle(const BlockT *Block) const
Find the innermost cycle containing a given block.
A possibly irreducible generalization of a Loop.
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:316
bool hasLocalLinkage() const
Definition: GlobalValue.h:530
This instruction compares its operands according to the predicate given to the constructor.
static LLVM_ABI bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:2036
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition: IRBuilder.h:527
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isLifetimeStartOrEnd() const LLVM_READONLY
Return true if the instruction is a llvm.lifetime.start or llvm.lifetime.end marker.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
Definition: Instruction.h:808
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.
Definition: Instruction.h:406
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.
Definition: Instruction.cpp:82
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
Definition: Instruction.h:315
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.
Definition: Metadata.cpp:1718
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:312
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:510
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition: Instruction.cpp:86
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:49
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
Analysis to compute lazy value information.
This pass computes, caches, and vends lazy value constraint information.
Definition: LazyValueInfo.h:32
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...
An instruction for reading from memory.
Definition: Instructions.h:180
Analysis pass that exposes the LoopInfo for a function.
Definition: LoopInfo.h:570
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Metadata node.
Definition: Metadata.h:1077
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
static LLVM_ABI MDNode * getMostGenericRange(MDNode *A, MDNode *B)
Definition: Metadata.cpp:1324
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
bool empty() const
Definition: MapVector.h:75
static MemoryEffectsBase readOnly()
Create MemoryEffectsBase that can read any memory.
Definition: ModRef.h:125
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition: ModRef.h:215
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access argument memory.
Definition: ModRef.h:135
static MemoryEffectsBase inaccessibleMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible memory.
Definition: ModRef.h:141
bool onlyAccessesInaccessibleMem() const
Whether this function only (at most) accesses inaccessible memory.
Definition: ModRef.h:234
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:188
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition: ModRef.h:224
bool onlyReadsMemory() const
Whether this function only (at most) reads memory.
Definition: ModRef.h:218
static MemoryEffectsBase writeOnly()
Create MemoryEffectsBase that can write any memory.
Definition: ModRef.h:130
static MemoryEffectsBase inaccessibleOrArgMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Create MemoryEffectsBase that can only access inaccessible or argument memory.
Definition: ModRef.h:158
static MemoryEffectsBase none()
Create MemoryEffectsBase that cannot read or write any memory.
Definition: ModRef.h:120
bool onlyAccessesInaccessibleOrArgMem() const
Whether this function only (at most) accesses argument and inaccessible memory.
Definition: ModRef.h:245
static MemoryEffectsBase unknown()
Create MemoryEffectsBase that can read and write any memory.
Definition: ModRef.h:115
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Root of the metadata hierarchy.
Definition: Metadata.h:63
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Evaluate the size and offset of an object pointed to by a Value*.
static SizeOffsetValue unknown()
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
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.
Definition: Constants.cpp:1885
Return a value (possibly void), from a function.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This class represents an analyzed expression in the program.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
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.
This class represents the LLVM 'select' instruction.
A vector that has set insertion semantics.
Definition: SetVector.h:59
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:104
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:418
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:470
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
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:182
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
An instruction for storing to memory.
Definition: Instructions.h:296
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition: DataLayout.h:626
TypeSize getElementOffset(unsigned Idx) const
Definition: DataLayout.h:657
TypeSize getElementOffsetInBits(unsigned Idx) const
Definition: DataLayout.h:662
Class to represent struct types.
Definition: DerivedTypes.h:218
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:368
Type * getElementType(unsigned N) const
Definition: DerivedTypes.h:369
Multiway switch.
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI unsigned getAssumedAddrSpace(const Value *V) const
LLVM_ABI bool areTypesABICompatible(const Function *Caller, const Function *Callee, const ArrayRef< Type * > &Types) const
LLVM_ABI bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const
Return true if the given instruction (assumed to be a memory access instruction) has a volatile varia...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:267
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:311
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition: Type.h:270
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
bool isVoidTy() const
Return true if this is 'void'.
Definition: Type.h:139
LLVM_ABI unsigned getIntegerBitWidth() const
'undef' values are things that do not have specified contents.
Definition: Constants.h:1420
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition: Constants.cpp:1866
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:61
Value * get() const
Definition: Use.h:55
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:21
const Use & getOperandUse(unsigned i) const
Definition: User.h:245
Value * getOperand(unsigned i) const
Definition: User.h:232
unsigned getNumOperands() const
Definition: User.h:254
LLVM_ABI bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
Definition: User.cpp:115
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: ValueMap.h:169
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
static constexpr uint64_t MaximumAlignment
Definition: Value.h:830
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
iterator_range< user_iterator > users()
Definition: Value.h:426
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition: Value.cpp:1101
iterator_range< use_iterator > uses()
Definition: Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:203
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:172
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:34
self_iterator getIterator()
Definition: ilist_node.h:134
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:359
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
Definition: SCCIterator.h:49
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI bool isAssumedReadNone(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readnone.
Definition: Attributor.cpp:655
LLVM_ABI bool isAssumedReadOnly(Attributor &A, const IRPosition &IRP, const AbstractAttribute &QueryingAA, bool &IsKnown)
Return true if IRP is readonly.
Definition: Attributor.cpp:650
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.
Definition: Attributor.cpp:341
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,...
Definition: Attributor.cpp:292
LLVM_ABI bool isAssumedThreadLocalObject(Attributor &A, Value &Obj, const AbstractAttribute &QueryingAA)
Return true if Obj is assumed to be a thread local object.
Definition: Attributor.cpp:837
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...
Definition: Attributor.cpp:231
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.
Definition: Attributor.cpp:601
LLVM_ABI bool isGPU(const Module &M)
Return true iff M target a GPU (and we can use GPU AS reasoning).
Definition: Attributor.cpp:200
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.
Definition: Attributor.cpp:282
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...
Definition: Attributor.cpp:818
LLVM_ABI bool isNoSyncInst(Attributor &A, const Instruction &I, const AbstractAttribute &QueryingAA)
Return true if I is a nosync instruction.
Definition: Attributor.cpp:205
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.
Definition: Attributor.cpp:591
LLVM_ABI Value * getWithType(Value &V, Type &Ty)
Try to convert V to type Ty without introducing new instructions.
Definition: Attributor.cpp:318
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ Unsupported
This operation is completely unsupported on the target.
@ Undef
Value of the register doesn't matter.
Offsets
Offsets in bytes from the start of the input buffer.
Definition: SIInstrInfo.h:1716
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:55
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
LocationClass< Ty > location(Ty &L)
Definition: CommandLine.h:464
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
Definition: DenseMapInfo.h:41
ElementType
The element type of an SRV or UAV resource.
Definition: DXILABI.h:59
constexpr double e
Definition: MathExtras.h:47
LLVM_ABI const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
LLVM_ABI const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
Definition: Path.cpp:235
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
@ Length
Definition: DWP.cpp:477
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:362
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt gcd(const DynamicAPInt &A, const DynamicAPInt &B)
Definition: DynamicAPInt.h:403
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:1744
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:1702
auto pred_end(const MachineBasicBlock *BB)
unsigned getPointerAddressSpace(const Type *T)
Definition: SPIRVUtils.h:294
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI)
Return true if this is a call to an allocation function that does not have side effects that we are r...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1563
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
LLVM_ABI Value * getAllocAlignment(const CallBase *V, const TargetLibraryInfo *TLI)
Gets the alignment argument for an aligned_alloc-like function, using either built-in knowledge based...
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.
Definition: SCCIterator.h:233
PotentialValuesState< std::pair< AA::ValueAndContext, AA::ValueScope > > PotentialLLVMValuesState
Definition: Attributor.h:5275
@ NONE
Definition: Attributor.h:6612
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
Definition: GraphWriter.h:376
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 operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
auto map_range(ContainerTy &&C, FuncTy F)
Definition: STLExtras.h:386
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.
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:1751
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:336
LLVM_ABI bool isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(const CallBase *Call, bool MustPreserveNullness)
{launder,strip}.invariant.group returns pointer that aliases its argument, and it only captures point...
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:288
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1669
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition: ModRef.h:296
@ None
Definition: CodeGenData.h:107
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 ...
Definition: Function.cpp:1172
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
bool isPointerTy(const Type *T)
Definition: SPIRVUtils.h:288
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Definition: Local.cpp:421
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
Definition: SetOperations.h:43
LLVM_ABI CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
LLVM_ABI bool hasAssumption(const Function &F, const KnownAssumptionString &AssumptionStr)
Return true if F has the assumption AssumptionStr attached.
Definition: Assumptions.cpp:69
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.
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.
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)
PotentialValuesState< APInt > PotentialConstantIntValuesState
Definition: Attributor.h:5273
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.
Definition: ValueMapper.h:289
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.
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...
Definition: Attributor.h:3505
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:223
auto pred_begin(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
Definition: iterator.h:363
ChangeStatus
{
Definition: Attributor.h:496
LLVM_ABI std::optional< APInt > getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI, function_ref< const Value *(const Value *)> Mapper=[](const Value *V) { return V;})
Return the size of the requested allocation.
LLVM_ABI DenseSet< StringRef > getAssumptions(const Function &F)
Return the set of all assumptions for the function F.
Definition: Assumptions.cpp:85
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Definition: Alignment.h:111
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ OPTIONAL
The target may be valid if the source is not.
@ NONE
Do not track a dependence between source and target.
@ REQUIRED
The target cannot be valid if the source is not.
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI)
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:280
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool capturesNothing(CaptureComponents CC)
Definition: ModRef.h:315
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
constexpr StringRef AssumptionAttrKey
The key we use for assumption attributes.
Definition: Assumptions.h:29
constexpr bool isCallableCC(CallingConv::ID CC)
Definition: CallingConv.h:298
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:851
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
A type to track pointer/struct usage and accesses for AAPointerInfo.
bool forallInterferingAccesses(AA::RangeTy Range, F CB) const
See AAPointerInfo::forallInterferingAccesses.
AAPointerInfo::const_bin_iterator end() const
ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, std::optional< Value * > Content, AAPointerInfo::AccessKind Kind, Type *Ty, Instruction *RemoteI=nullptr)
Add a new Access to the state at offset Offset and with size Size.
DenseMap< const Instruction *, SmallVector< unsigned > > RemoteIMap
AAPointerInfo::const_bin_iterator begin() const
AAPointerInfo::OffsetInfo ReturnedOffsets
Flag to determine if the underlying pointer is reaching a return statement in the associated function...
State(State &&SIS)=default
const AAPointerInfo::Access & getAccess(unsigned Index) const
SmallVector< AAPointerInfo::Access > AccessList
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint().
bool forallInterferingAccesses(Instruction &I, F CB, AA::RangeTy &Range) const
See AAPointerInfo::forallInterferingAccesses.
static State getWorstState(const State &SIS)
Return the worst possible representable state.
AAPointerInfo::OffsetBinsTy OffsetBins
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint().
State & operator=(const State &R)
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.
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.
An abstract interface for address space information.
Definition: Attributor.h:6383
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6419
An abstract interface for all align attributes.
Definition: Attributor.h:4323
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4355
Align getKnownAlign() const
Return known alignment.
Definition: Attributor.h:4337
static LLVM_ABI const char ID
Definition: Attributor.h:6499
An abstract attribute for getting assumption information.
Definition: Attributor.h:6268
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6296
An abstract state for querying live call edges.
Definition: Attributor.h:5541
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5585
An abstract Attribute for specializing "dynamic" components of "denormal-fp-math" and "denormal-fp-ma...
Definition: Attributor.h:6585
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6607
An abstract interface for all dereferenceable attribute.
Definition: Attributor.h:4269
uint32_t getKnownDereferenceableBytes() const
Return known dereferenceable bytes.
Definition: Attributor.h:4293
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4314
An abstract interface for llvm::GlobalValue information interference.
Definition: Attributor.h:6504
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6538
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4619
An abstract interface for indirect call information interference.
Definition: Attributor.h:6543
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6579
An abstract interface to track if a value leaves it's defining function instance.
Definition: Attributor.h:4362
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4395
An abstract Attribute for computing reachability between functions.
Definition: Attributor.h:5738
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5773
bool canReach(Attributor &A, const Function &Fn) const
If the function represented by this possition can reach Fn.
Definition: Attributor.h:5744
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.
Definition: Attributor.h:3863
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3891
virtual bool isAssumedReachable(Attributor &A, const Instruction &From, const Instruction &To, const AA::InstExclusionSetTy *ExclusionSet=nullptr) const =0
Returns true if 'From' instruction is assumed to reach, 'To' instruction.
An abstract interface for identifying pointers from which loads can be marked invariant.
Definition: Attributor.h:6343
static LLVM_ABI const char ID
Unique ID (due to the unique address).
Definition: Attributor.h:6379
An abstract interface for liveness abstract attribute.
Definition: Attributor.h:4026
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4117
An abstract interface for memory access kind related attributes (readnone/readonly/writeonly).
Definition: Attributor.h:4684
bool isAssumedReadOnly() const
Return true if we assume that the underlying value is not accessed (=written) in its respective scope...
Definition: Attributor.h:4722
bool isKnownReadNone() const
Return true if we know that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4710
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4749
bool isAssumedReadNone() const
Return true if we assume that the underlying value is not read or accessed in its respective scope.
Definition: Attributor.h:4714
An abstract interface for all memory location attributes (readnone/argmemonly/inaccessiblememonly/ina...
Definition: Attributor.h:4758
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)
Definition: Attributor.h:4934
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3636
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3671
An abstract interface for potential address space information.
Definition: Attributor.h:6428
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6460
An abstract interface for all noalias attributes.
Definition: Attributor.h:3898
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)
Definition: Attributor.h:3938
An abstract interface for all nocapture attributes.
Definition: Attributor.h:4403
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4477
@ 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...
Definition: Attributor.h:4433
bool isAssumedNoCaptureMaybeReturned() const
Return true if we assume that the underlying value is not captured in its respective scope but we all...
Definition: Attributor.h:4457
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)
Definition: Attributor.h:5495
An AbstractAttribute for nofree.
Definition: Attributor.h:3945
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3989
An abstract attribute for norecurse.
Definition: Attributor.h:3730
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3755
An AbstractAttribute for noreturn.
Definition: Attributor.h:3996
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4021
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3629
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.
Definition: Attributor.h:5407
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5443
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)
Definition: Attributor.h:3544
An abstract Attribute for determining the necessity of the convergent attribute.
Definition: Attributor.h:5778
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5806
bool isAssumedNotConvergent() const
Return true if "non-convergent" is assumed.
Definition: Attributor.h:5788
An abstract interface for all nonnull attributes.
Definition: Attributor.h:3678
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3723
static LLVM_ABI bool isImpliedByIR(Attributor &A, const IRPosition &IRP, Attribute::AttrKind ImpliedAttributeKind, bool IgnoreSubsumingPositions=false)
See AbstractAttribute::isImpliedByIR(...).
An access description.
Definition: Attributor.h:6043
A helper containing a list of offsets computed for a Use.
Definition: Attributor.h:5847
A container for a list of ranges.
Definition: Attributor.h:5892
static void set_difference(const RangeList &L, const RangeList &R, RangeList &D)
Copy ranges from L that are not in R, into D.
Definition: Attributor.h:5928
An abstract interface for struct information.
Definition: Attributor.h:5810
virtual bool reachesReturn() const =0
virtual const_bin_iterator begin() const =0
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:6260
virtual int64_t numOffsetBins() const =0
An abstract interface for potential values analysis.
Definition: Attributor.h:5298
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5355
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5393
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.
Definition: Attributor.h:4633
virtual std::optional< Type * > getPrivatizableType() const =0
Return the type we can choose for a private copy of the underlying value.
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4675
An abstract attribute for undefined behavior.
Definition: Attributor.h:3825
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3858
An abstract attribute for getting all assumption underlying objects.
Definition: Attributor.h:6300
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)
Definition: Attributor.h:6330
An abstract interface for range value analysis.
Definition: Attributor.h:4939
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:5002
An abstract interface for value simplify abstract attribute.
Definition: Attributor.h:4556
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:4578
An abstract attribute for willreturn.
Definition: Attributor.h:3762
static LLVM_ABI const char ID
Unique ID (due to the unique address)
Definition: Attributor.h:3820
Helper to represent an access offset and size, with logic to deal with uncertainty and check for over...
Definition: Attributor.h:241
static constexpr int64_t Unknown
Definition: Attributor.h:320
static RangeTy getUnknown()
Definition: Attributor.h:247
Base struct for all "concrete attribute" deductions.
Definition: Attributor.h:3322
void print(raw_ostream &OS) const
Helper functions, for debug purposes only.
Definition: Attributor.h:3406
virtual StateType & getState()=0
Return the internal abstract state for inspection.
An interface to query the internal state of an abstract attribute.
Definition: Attributor.h:2642
virtual ChangeStatus indicatePessimisticFixpoint()=0
Indicate that the abstract state should converge to the pessimistic state.
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.
virtual ChangeStatus indicateOptimisticFixpoint()=0
Indicate that the abstract state should converge to the optimistic state.
Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign but the instruction.
static unsigned getHashValue(const Access &A)
static Access getTombstoneKey()
static bool isEqual(const Access &LHS, const Access &RHS)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Helper struct used in the communication between an abstract attribute (AA) that wants to change the s...
Definition: Attributor.h:2245
std::function< void(const ArgumentReplacementInfo &, AbstractCallSite, SmallVectorImpl< Value * > &)> ACSRepairCBTy
Abstract call site (ACS) repair callback type.
Definition: Attributor.h:2268
const Argument & getReplacedArg() const
Definition: Attributor.h:2275
std::function< void(const ArgumentReplacementInfo &, Function &, Function::arg_iterator)> CalleeRepairCBTy
Callee repair callback type.
Definition: Attributor.h:2254
The fixpoint analysis framework that orchestrates the attribute deduction.
Definition: Attributor.h:1533
std::function< std::optional< Value * >(const IRPosition &, const AbstractAttribute *, bool &)> SimplifictionCallbackTy
Register CB as a simplification callback.
Definition: Attributor.h:2042
Specialization of the integer state for a bit-wise encoding.
Definition: Attributor.h:2783
BitIntegerState & removeAssumedBits(base_t BitsEncoding)
Remove the bits in BitsEncoding from the "assumed bits" if not known.
Definition: Attributor.h:2808
BitIntegerState & addKnownBits(base_t Bits)
Add the bits in BitsEncoding to the "known bits".
Definition: Attributor.h:2800
Simple wrapper for a single bit (boolean) state.
Definition: Attributor.h:2926
Represent subnormal handling kind for floating point instruction inputs and outputs.
static constexpr DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.
static constexpr DenormalMode getInvalid()
static unsigned getHashValue(const Access &A)
static bool isEqual(const Access &LHS, const Access &RHS)
static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B)
static unsigned getHashValue(const AA::RangeTy &Range)
static ReachabilityQueryInfo< ToTy > * getEmptyKey()
static ReachabilityQueryInfo< ToTy > * getTombstoneKey()
static bool isEqual(const ReachabilityQueryInfo< ToTy > *LHS, const ReachabilityQueryInfo< ToTy > *RHS)
static unsigned getHashValue(const ReachabilityQueryInfo< ToTy > *RQI)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:54
State for dereferenceable attribute.
Definition: Attributor.h:4123
IncIntegerState DerefBytesState
State representing for dereferenceable bytes.
Definition: Attributor.h:4139
ChangeStatus manifest(Attributor &A) override
See AbstractAttribute::manifest(...).
Definition: Attributor.h:3259
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
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
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
Data structure to hold cached (LLVM-IR) information.
Definition: Attributor.h:1210
bool isOnlyUsedByAssume(const Instruction &I) const
Definition: Attributor.h:1311
AP::Result * getAnalysisResultForFunction(const Function &F, bool CachedOnly=false)
Return the analysis result from a pass AP for function F.
Definition: Attributor.h:1321
State for an integer range.
Definition: Attributor.h:2968
ConstantRange getKnown() const
Return the known state encoding.
Definition: Attributor.h:3024
ConstantRange getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:3027
bool isValidState() const override
See AbstractState::isValidState() NOTE: For now we simply pretend that the worst possible state is in...
Definition: Attributor.h:2701
bool isAtFixpoint() const override
See AbstractState::isAtFixpoint()
Definition: Attributor.h:2704
ChangeStatus indicateOptimisticFixpoint() override
See AbstractState::indicateOptimisticFixpoint(...)
Definition: Attributor.h:2707
base_t getAssumed() const
Return the assumed state encoding.
Definition: Attributor.h:2722
static constexpr base_t getWorstState()
Return the worst possible representable state.
Definition: Attributor.h:2694
ChangeStatus indicatePessimisticFixpoint() override
See AbstractState::indicatePessimisticFixpoint(...)
Definition: Attributor.h:2713
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.
Definition: KnownFPClass.h:25
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
A "must be executed context" for a given program point PP is the set of instructions,...
Definition: MustExecute.h:388
iterator & end()
Return an universal end iterator.
Definition: MustExecute.h:436
bool findInContextOf(const Instruction *I, const Instruction *PP)
Helper to look for I in the context of PP.
Definition: MustExecute.h:472
iterator & begin(const Instruction *PP)
Return an iterator to explore the context around PP.
Definition: MustExecute.h:422
bool checkForAllContext(const Instruction *PP, function_ref< bool(const Instruction *)> Pred)
}
Definition: MustExecute.h:458
Various options to control the behavior of getObjectSize.
A class for a set state.
Definition: Attributor.h:5013
static unsigned MaxPotentialValues
Maximum number of potential values to be tracked.
Definition: Attributor.h:5066
void unionAssumed(const MemberTy &C)
Union assumed set with the passed value.
Definition: Attributor.h:5083
const SetTy & getAssumedSet() const
Return this set.
Definition: Attributor.h:5043
Represent one information held inside an operand bundle of an llvm.assume.
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:249
Helper to tie a abstract state implementation to an abstract attribute.
Definition: Attributor.h:3211
StateType & getState() override
See AbstractAttribute::getState(...).
Definition: Attributor.h:3219
Capture information for a specific Use.
bool isPassthrough() const
LLVM_ABI bool unionAssumed(std::optional< Value * > Other)
Merge Other into the currently assumed simplified value.